BC remote Oracle DBA - Call (800) 766-1884  
Oracle Consulting Oracle Training Development

Remote DBA

Remote DBA Plans  

Remote DBA Service

Remote DBA RAC

Remote DBA Oracle Home
Remote DBA Oracle Training
Remote DBA SQL Tuning Consulting
Remote DBA Oracle Tuning Consulting
Remote DBA Data Warehouse Consulting
Remote DBA Oracle Project Management
Remote DBA Oracle Security Assessment
Remote DBA Unix Consulting
Burleson Books
Burleson Articles
Burleson Web Courses
Burleson Qualifications
Oracle Links
Remote DBA Oracle Monitoring
Remote DBA Support Benefits
Remote DBA Plans & Prices
Our Automation Strategy
What We Monitor
Oracle Apps Support
Print Our Brochure
Contact Us (e-mail)
Oracle Job Opportunities
Oracle Consulting Prices





Remote DBA services

Remote DBA Support

Remote DBA RAC

Remote DBA Reasons

Remote Oracle Tuning

Remote DBA Links

Oracle DBA Support

Oracle DBA Forum

Oracle Disaster

Oracle Training

Oracle Tuning

Oracle Training

 Remote DBA SQL Server

Remote MSSQL Consulting

Oracle DBA Hosting

Oracle License Negotiation








EnterpriseDB: DROP TABLE

Oracle Tips by Burleson Consulting

Drop the table emp.  emp has a foreign key relation to dept.  You cannot normally drop a table that has a dependant object (such as a foreign key).  The CASCADE keyword forces the database to drop the dependency (in this case, the foreign key not the other table) and then drop the table 


Drop the dept table.



An index on a table helps queries run faster.  If you think of the index in a book, you can flip to the back of a book, scan through a handful of pages for a specific topic and then jump right to the page you are looking for.  Without that index, you would have to scan each page in the book to find that one topic.  If the topic is on the last page, you have done a full book scan.

An index on a table works much like an index in a book but instead of storing a page number, the index stores a pointer to the specific row in the table.  Like a book index, a table index is stored in sorted order.  Sorted order may mean alphabetical order for character data or numerical order for numeric data.  It would mean date order (with earlier dates coming first) for date and timestamp fields.

If you are looking for a specific row, an index will point you to a specific row so that you don't have to look at every row in the table.  A query that returns one row will get more benefits from an index than a query that returns multiple rows.  The higher the percentage of rows returned (rows returned / rows in the table), the less useful the index becomes.

Returning to our book analogy, let's say that you have a 500-page book and you want to find all pages that say "EnterpriseDB".  If you look at the index and it appears on only a single page, you have found the page you want.  If it says it appears on 10 pages, you will have to look at up to 10 pages but that's a lot better than 500 pages.  What if it appears on 100 pages?  Or 400 pages?  At some point, it's just easier, and probably faster, to scan through the book yourself.

The same is true with a table index.  The exact percentage where a useful index becomes a nuisance is not a hard and fast rule. There are many considerations such as work load, query frequency, data distribution, etc. but a general rule of thumb would be that if more than 30% of the rows in the table will be returned, you will not benefit by creating an index.

An index on a table also has overhead and the maintenance of that index can slow down other operations.  For example, when you add a new row, every index on the table must be altered to add the new row.  Because indexes are sorted (that's what makes them fast to search), each index has to be searched for the right place to put the row, space has to be made for the row and the pointer has to be added.  If a table has 10 indexes, all 10 must be maintained.  Updates and deletes work a bit differently, but those operations do generate system overhead.

An additional item to note about indexes, small tables really do not benefit from indexes.  When a table is small, scanning the whole thing is probably faster than scanning an index and then going after the correct row in the small table (two disk activities instead of one).  In addition, if a table is small, it will be searched on disk the first time and put in memory.  If the table is frequently used, it will stay in memory and all future searches will be done in memory.  Memory is much faster than disk and is another reason not to create an index on a small table.  Unfortunately, there is no hard and fast rule as to what defines "small".  If it's less than a couple of hundred rows, you don't need an index.  If it's less than a few thousand, you should benchmark it on your hardware.  Over that and you will probably benefit from the index.

Most databases provide multiple flavors of indexing.  Different index types use different coding techniques and storage mechanisms.  In EnterpriseDB, the b-tree index is the index type with which you will be most concerned.  A b-tree is a general-purpose index and is probably the most common index in database land.

When you create an index in EnterpriseDB, with the CREATE INDEX command, a b-tree index will be the default.  Under some very specific circumstances, you might benefit from an r-tree or a hash index.  The situations that benefited by those index types are so rare that I will not cover them further in this book. 


CREATE [ UNIQUE ] INDEX <index name>
ON <table name>
[ USING {btree|hash|rtree|gist} ]
    ( { <column name> | ( <expression> ) }
    [ TABLESPACE <tablespace> ]
    [ WHERE <where criteria> ]

A query like this:

SELECT ename
  FROM emp
  WHERE empno = 123;

would be helped by an index on the empno column.  Here you are looking for all records where empno is equal to 123.  Each empno that was equal to 123 would have a corresponding entry in the index with a row pointer.  You would create an index for user with:

CREATE INDEX empno_idx ON emp (empno);

Indexes are also useful when you are doing a RANGE SCAN, by that I mean that you are doing a search for a range of records:

SELECT ename
  FROM emp
  WHERE empno BETWEEN 123 and 567;

In this case, you are looking for all records where the empno is greater than or equal to 123 and less than or equal to 567.  Because the index is sorted, the database would scan the index until it found 123 and then scan until it found 567 and return the row pointers between those two points.  The index created above, empno_idx, would also work with a range scan.

An index can contain one or more columns.  If your queries are frequently using AND to combine multiple columns in a where clause:

SELECT ename
  FROM emp
  WHERE empno = 123
      AND job = 'CLERK';

You may want an index on empno and job (with empno as the leading column).  The database will search for a match on the empno and then for that empno it will scan for the job CLERK.

CREATE INDEX empno_job_idx ON emp (empno, job);

Having multiple columns in an index does not help if you frequently use OR:

SELECT ename, empno, job
  FROM emp
  WHERE empno = 123
       OR job = 'CLERK';

In this case, if you had an index on empno and clerk, with empno as the leading column, the database could use the index to find empno = 123 but it would need to search the entire table to find job  = 'CLERK'.  Since it is going to full scan the table anyway, it makes sense to not use the index at all and just scan the table.

If you had an index on empno and a separate index on job, the database could use both indexes and create what is known as an in memory bitmap, or a bitmap scan, to combine the two indexes into one.  The result would be faster than a full table scan, but slower than a single scan of an index.

You would define your indexes like a normal index.  You don't have to do anything special to allow them to be turned into a bitmap scan.  EnterpriseDB will do that automatically if the database decides that will be the fastest method to access your data.

CREATE INDEX empno_idx ON emp (empno);
CREATE INDEX job_idx ON emp (job);

You can also create function-based indexes (FBI), also called Expression Indexes.  An FBI is an index created with a SQL function or expression in the create statement that would match the function or expression in a query.  For example, if you wanted to search the emp table for all names that are equal to 'lewis' (regardless whether or not the data is stored in upper case, mixed case or lower case), you would execute this query:

SELECT ename, empno
  FROM emp
  WHERE lower(ename) = 'lewis';

If you don't use the LOWER() function to force the ename column to lower case, your query would not find records where ename was equal to 'Lewis'.  However, if your index was on ename, you would not be able to use it because lower(ename) is not the same as ename.  If you are going to query frequently on lower(ename), you should create your index with the lower function as part of the index creation statement, i.e.

CREATE INDEX lowerename_idx ON emp (lower(ename));

You can use SQL functions (functions that come with the database) or you can write your own functions with SQL, PL/SQL, PL/pgSQL or one of the other supported languages.  You can also embed expressions such as:

SELECT deptno, dname, loc
  FROM dept
  WHERE (dname || ' - ' || loc) = 'HR - New Orleans'; 

CREATE INDEX dname_loc_idx ON dept ((dname || ' - ' || loc));

The double parenthesis (()) is required for expressions.

Earlier in this section (under CREATE TABLE and ALTER TABLE), I spoke about adding constraints to a table.  A Unique Constraint at the table level (or a Primary Key) forces all rows in the table to be unique based on that column or set of columns.  This constraint is implemented via a Unique Index.  You can create a unique index using the CREATE UNIQUE INDEX command:

CREATE UNIQUE INDEX emp_pk ON emp (empno);

Even though you can create an index in this manner, creating a constraint while creating the table, or afterwards with an ALTER TABLE, is the preferred method of doing so.

Another nifty feature of indexes in EnterpriseDB is the ability to create a partial index.  A partial index includes only a subset of a table's records.  IF you have a wide variety in your data distribution, using a partial index probably won't help you.  However, if you have a table where most of the records are a particular value (a high percentage of the table), you can exclude that value from the index.  Remember that an index helps when you are accessing a small portion of a table's records, not all of them.

Let's say that the dept table had 5000 records and 90% of those records had a LOC of 'Tampa, FL'.  The other 10% of the records are spread out amongst 10 other cities.  It might make sense to create a partial index that excluded 'Tampa, FL' since any query for 'Tampa, FL' should do a full table scan anyway.

CREATE INDEX tampa_dept_loc_prtidx ON dept(loc) WHERE loc <> 'Tampa, FL';

If we query:

  FROM dept
  WHERE LOC = 'New Orleans, LA';

We would use the partial index.

If we queried:

  FROM dept
  WHERE LOC <> 'Tampa, FL';

We would use the partial index.

If we queried:

  FROM dept
  WHERE LOC <> 'New Orleans, LA';

We would not use the index and would instead do a full table scan.

If we queried:

  FROM dept
  WHERE LOC = 'Tampa, FL';

We would not use the index and would instead do a full table scan.

Partial indexes can be tricky at times.  If you choose to use a partial index, I would recommend that you test your cases well.  Pay particular attention to the border cases.

ALTER INDEX <index name>
    RENAME TO <new index name>
    OWNER TO <new owner>
    SET TABLESPACE < new tablespace>

There are only three ways to alter an index: rename it, change the owner or assign it to a different tablespace.

Rename an index:

ALTER INDEX empno_idx RENAME TO emp_empno_idx;

Move an index to a new tablespace:

ALTER INDEX empno_idx SET TABLESPACE hr_idx_tbs;

Change an index owner.  This might be useful if an admin user creates an index and wants to allow a less privileged user do the maintenance on it.  I have never needed to change owners.

ALTER INDEX empno_idx OWNER TO tom;


You cannot grant to an index.  You would grant to a table that uses the index.


You cannot revoke permissions from an index.  You would revoke permissions from a table that uses the index.


Drop the index empno_idx.  If another object has a dependency on the index, you need to use the CASCADE keyword, which will force the database to drop the dependency and then drop the index.  I don't think I have ever had a case where I needed to use CASCASE to drop an index.


Or, more commonly:

DROP INDEX empno_idx;

This is an excerpt from the book "EnterpriseDB: The Definitive Reference" by Rampant TechPress.

Expert Remote DBA

BC is America's oldest and largest Remote DBA Oracle support provider.  Get real Remote DBA experts, call
BC Remote DBA today.



Remote DBA Service

Oracle Tuning Book


Advance SQL Tuning Book 

BC Oracle support

Oracle books by Rampant

Oracle monitoring software







BC Remote Oracle Support

Remote DBA

Remote DBA Services

Copyright © 1996 -  2013 by Burleson. All rights reserved.

Oracle® is the registered trademark of Oracle Corporation.

Hit Counter