By executing the following command that will list out all indexes found in my schema, the query returned nothing - suggesting that either no index is created, or probably i do not have sufficient permission.
select * from user_indexes;
Are there any more ways to list the indexes i have in a schema?
Sure it's possible.
Common, even :)
It just means nobody's created any indexes.
If the query returned nothing, it means that you DO have permission ... and there simply aren't any indexes.
Here's a good link on "Managing indexes in Oracle" (it sounds like you're probably running Oracle):
http://download.oracle.com/docs/cd/B19306_01/server.102/b14231/indexes.htm
As paulsm4 say, you do not have any indexes in your schema.
you can use
select * from all_indexes;
and you'll see all your indexes + the others where you have rights.
Florin is correct, USER_INDEXES is a view on ALL_INDEXES that only shows those which were created by you. You can query ALL_INDEXES directly to determine if anyone else has created indexes on the table in question but you will probably want to add a where clause for the table_name as it will list all indexes for all tables in the instance and also only some of the columns.
SELECT TABLE_NAME, INDEX_NAME FROM ALL_INDEXES WHERE TABLE_NAME='XYZ';
You can limit which tables using an IN CLAUSE if there is are several tables you are interested in
SELECT TABLE_NAME, INDEX_NAME FROM ALL_INDEXES WHERE TABLE_NAME IN ('ABC','XYZ');
and you can use a like clause if there is a prefix or suffix
SELECT TABLE_NAME, INDEX_NAME FROM ALL_INDEXES WHERE TABLE_NAME like 'XYZ%';
Also, if you want to see which columns these indexes are on, you can select from ALL_IND_COLUMNS;
SELECT * FROM ALL_IND_COLUMNS WHERE TABLE_NAME='XYZ'
Note that whether a table has indexes or not depends on the data and the usage. A small lookup table that has maybe a hundred rows or less would not need an index whereas a table that contains millions of rows but is queried for just a handful when needed would need an index.
Related
In order to optimize the query of the following statement add an index:
SELECT SUPPLIER.COMPANY_NAME, SUPPLIER.CITY
FROM PRODUCT JOIN SUPPLIER
ON PRODUCT.SUPPLIER_NAME = SUPPLIER.COMPANY_NAME;
The statement I wrote is as follows:
EXPLAIN PLAN FOR SELECT PRODUCT.SUPPLIER_NAME, SUPPLIER.COMPANY_NAME FROM PRODUCT,SUPPLIER;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
CREATE INDEX PS_IDX_SC ON PRODUCT,SUPPLIER(PRODUCT.) ;
EXPLAIN PLAN FOR SELECT PRODUCT.SUPPLIER_NAME, SUPPLIER.COMPANY_NAME FROM PRODUCT JOIN SUPPLIER;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
DROP INDEX PS_IDX_SC;
How to write the statement on line 45,thanks.
You can not crete the index on two tables.
You need to create two separate index as follows:
CREATE INDEX PS_IDX_PS ON PRODUCT(SUPPLIER_NAME) ;
CREATE INDEX PS_IDX_SC ON SUPPLIER(COMPANY_NAME) ;
Let me try to answer your question in a different way, trying to give you a short overview of what indexes are for, and that sometimes they are not the answer. You are joining two tables based on a condition, but without filtering. When you need to analyse a performance issue, and you think an index is the answer, try to think a bit more.
In your specific case, the join has no filter, so you show the supplier name and company name. But your query shows two columns only: supplier_name from the product table, and company_name from the supplier table. However, what is the join condition here ? I guess that company_name and supplier_name are the same, however it does not make any sense to retrieve the same column from both tables, if you ask me.
Original query
SQL> SELECT PRODUCT.SUPPLIER_NAME, SUPPLIER.COMPANY_NAME FROM PRODUCT JOIN SUPPLIER;
Rewrite query
SQL> SELECT PRODUCT.SUPPLIER_NAME, SUPPLIER.COMPANY_NAME FROM PRODUCT JOIN SUPPLIER
on PRODUCT.SUPPLIER_NAME = SUPPLIER.COMPANY_NAME;
Try to write always the join condition, makes the query more readable. In your case you could create two indexes in both tables, as #Tejash has shown you before, but let me explain you a bit more something else.
If your SQL query only retrieves the columns present in the index, Oracle probably will use the indexes to access the data. In this case, accessing by index will be faster than by table because the indexes are smaller than the tables.
However, if your SQL query retrieves more columns than the ones contained in the indexes (for example, the product_name), then it would be very interesting see whether than indexes make the query faster when you have no filter on it. In this case Oracle probably would use a method called TABLE ACCESS BY INDEX ROWID. It means that Oracle access the index to retrieve the rowid, then it goes to the table to get the data using the rowid retrieved from the index. In this case, when more columns are involved, if the tables are big enough, I bet accessing by table full scan is faster than accessing by index.
My advice: Get statistics of both tables by using DBMS_STATS. And, if you have Oracle 11g or higher, that you most probably do, you might want to use Invisible Indexes to verify the performance of those queries when you add the indexes without affecting your environment, then when you are sure, you can make them visible.
SQL> CREATE INDEX IDX_PRO_SUP ON PRODUCT(SUPPLIER_NAME) INVISIBLE;
SQL> CREATE INDEX IDX_SUP_COM SUPPLIER(COMPANY_NAME) INVISIBLE;
To see how the indexes will work with your explain plan in your own session.
SQL> ALTER SESSION SET OPTIMIZER_USE_INVISIBLE_INDEXES=TRUE;
SQL> EXPLAIN PLAN FOR SELECT PRODUCT.SUPPLIER_NAME, SUPPLIER.COMPANY_NAME FROM
PRODUCT,SUPPLIER;
SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
Then when you are sure those indexes work as you expect:
SQL> ALTER INDEX IDX_PRO_SUP VISIBLE;
SQL> ALTER INDEX IDX_SUP_COM VISIBLE;
Hope it helps.
Best regards
I have 2 tablespaces, one to store tables and other on to store indexes. I created a script that can be run in any of my schemas and it will move objects (tables or indexes) to their respective tablespaces.
However, I am failing to come up with a script that will verify that objects have been moved to the correct tablespaces (meaning tables have been moved to the table tablespace, and indexes have been moved to the index tablespace).
Any thoughts?
You can use the query below to get the information through a spesific schema :
select t.table_name, t.tablespace_name as "TS Name For Table",
i.index_name, i.tablespace_name as "TS Name For Indexes"
from user_tables t
join user_indexes i on i.table_name = t.table_name
order by t.table_name, i.index_name;
Say, I have a table my_table with field kind:string and an index on this field.
I've noticed that Postgres builds two different query plans for the queries:
SELECT * FROM my_table
WHERE kind = 'kind1' OR kind IS NULL;
and
SELECT * FROM my_table
WHERE kind = 'kind1';
The first one does not use index whereas the second one does. Why?
I know there are a lot of conditions why indexes may be used or not, and I've read a lot about query plans but this case still is not clear to me.
Abelisto explains that the two versions of the query are not the same. SQL engines (in general) can do a poor job of using indexes for ORs. It is possible that there are so many NULL values, that Postgres simply does not think an index is useful when comparing to NULLs. That depends on the data.
You can try rewriting the query as:
SELECT *
FROM my_table
WHERE kind = 'type1'
UNION ALL
SELECT *
FROM my_table
WHERE kind IS NULL;
Postgres might choose to use indexes on each subquery, if they are appropriate for the data.
How does one go about selecting all indexes of a specific type in Oracle 10g, for instance I want all of the bitmap indexes that are declared.
I imagine the query would be something like this:
select * from system_indexes where type = 'bitmap'
but that is definitely not correct.
SELECT *
FROM dba_indexes
WHERE index_type IN ('BITMAP', 'FUNCTION-BASED BITMAP' )
is probably what you're looking for (though you may want just the indexes where index_type = 'BITMAP'. If you are only concerned with indexes on tables that you have SELECT access on, you can query all_indexes rather than dba_indexes. If you are only concerned with indexes in the current schema, you can query user_indexes rather than dba_indexes.
I created indexes like this:
--CREATE INDEXES for Tables
CREATE UNIQUE INDEX worker_name_index ON WORKER (worker_id);
CREATE UNIQUE INDEX company_name_index ON COMPANY (company_name);
CREATE UNIQUE INDEX project_name_index ON PROJECT (project_id);
But cant find where the indexes are:
SELECT * FROM USER_INDEXES;
Also not here:
SELECT * FROM ALL_INDEXES;
nor here:
SELECT * FROM DBA_INDEXES;
And also cant drop these indexes, because dropping throws ORA-01418:specified index does not exist error.
--REMOVE INDEXES
DROP INDEX project_name_index;
DROP INDEX company_name_index;
DROP INDEX project_name_index;
and can't recreate, because creation rise ORA-01408:such columnt in list already indexed error...
Edited (with select * all_ind_columns and the index is not there)
Your question seems to be a little misleading as you won't ever have been able to successfully create those named indexes. As shown by your subsequent queries against all_ind_columns, such as:
select * from all_ind_columns
where table_name = 'WORKER' and column_name = 'WORKER_ID'
... system-generated indexes already exist for the columns you are trying to index. The names (e.g. SYS_C0011015) indicate that they are system-generated backing indexes for primary key (or possibly unique) constraints defined against the tables.
The documentation notes in several places:
If you do not specify a constraint name, then Oracle generates a
system name for the constraint of the form SYS_Cn.
So you can't have created the named indexes; if the constraints already existed on the tables then you'd always have got an ORA-01408, and if you'd tried to add the constraints after the indexes were created then the alter would have failed. Since they really don't exist it's quite reasonable that they aren't listed in all_indexes and cannnot be dropped, and you can't recreate them for the same reason you can't have created them in the first place...
Probably you created the index with a different oracle user than the user you use for dropping or selecting this index.