In Oracle are indexes used when an UPDATE is fired without a WHERE clause
By "used", do you mean "referred to" or "modified"?
An UPDATE without a WHERE clause boils down to an iteration over the entire table; I see no good reason why Oracle should refer to an index in this case, as there's no benefit to be had from that. (Although that's little more than a qualified guess.) nonnb is right that the index will be affected depending on what column you touch.
If you update affects indexed columns, then the index pages will need to be replaced as well.
Will Oracle use the index to find the rows being updated? With no where clause, almost certainly not.
Will Oracle have to read one or more indexes, getting blocks in consistent mode to update them? If you're updating any columns that are indexed, have function-based indexes which will result in an updated indexed value, or cause row movement among partitions, then yes, indexes "will be used."
Related
Sorry if this is a dumb question but do i need to reindex my table every time i insert rows, or does the new row get indexed when added?
From the manual
Once an index is created, no further intervention is required: the system will update the index when the table is modified
http://postgresguide.com/performance/indexes.html
I think when you insert rows, the index does get updated. It maintains the sort on the index table as you insert data. Hence there are performance issues or downtimes on a table, if you try adding large number of rows at once.
On top of the other answers: PostgreSQL is a top notch Relational Database. I'm not aware of any Relational Database system where indices are not updated automatically.
It seems to depend on the type of index. For example, according to https://www.postgresql.org/docs/9.5/brin-intro.html, for BRIN indexes:
When a new page is created that does not fall within the last summarized range, that range does not automatically acquire a summary tuple; those tuples remain unsummarized until a summarization run is invoked later, creating initial summaries. This process can be invoked manually using the brin_summarize_new_values(regclass) function, or automatically when VACUUM processes the table.
Although this seems to have changed in version 10.
We are having a database design where we have table on which we have 1 Day Interval Partitioning on the column named as "5mintime" and on the same column we have created index also.
"5mintime" column can have data such as 1-Mar-2011,2-Mar-2011, in short there is no time component in it and from the UI also the user can select only one day period as minimum date.
My question is that while firing the select queries is there any advantage gained because of indexes since the partition is already there, on the flip side if i remove the indexes the insertion will be come faster, so any help on this would be greatly appreciated.
If I understand you right, then I think there's no need for the index:
A local index is indexed for every partition, which in your case has the same value in all rows (ie: 1-Mar-2011 in the 1-Mar-2011 partition, 2-Mar-2011 in the 2-Mar-2011 partiotion and so on).
A global Index will actually index the whole table but will find a whole partiotion, which is also not usefull since you already have partiones ...
But, why not check it?
If each day's data goes into its own partition and you can never search within days, but only for entire days worth of data, then, no, I don't see this index adding any value.
You can confirm whether or not SQL queries are using this index by enabling monitoring:
alter index myindex monitoring usage;
And then check to see if it's been used by querying v$object_usage for it some time later.
I have a relatively large table (81M rows) and an index on it.
I want to add a column to the existing index.
I searched for it on Google, but I couldn't find a way for it.
I've read somewhere that the only way to add a column to an index is to drop and recreate it.
However, here it says it's common practice to add columns to existing index. (Although the author doesn't recommend it.)
So, is it possible to add columns to existing index and if possible is it good practice?
It is not possible to add a new column to an existing index without dropping and recreating the index.
When Jonathan Lewis is talking about "adding a column to an existing index", he's talking about dropping the existing index and creating a new index. Note in his example, both the "original index" and "modified index" are listed with a CREATE INDEX statement. There are no ALTER INDEX statements in the example that would add a new column without dropping the old column.
Whether it is a good idea to drop & recreate the index with an additional column depends on a number of factors. As Jonathan Lewis points out, there are various situations where adding additional columns will affect the clustering factor of the index and cause some existing queries to perform more poorly. Without knowing anything about your system or the index we're talking about, it's impossible to advise.
Is there any way to force oracle to use index except Hints?
No. And if the optimizer doesn't use the index, it usually has a good reason for it. Index usage, if the index is poor, can actually slow your queries down.
Oracle doesn't use an index when it thinks the index is
disabled
invalid (for example, after a huge data load and the statistics about the index haven't been updated)
won't help (for example, when there are only two different values in 5 million rows)
So the first thing to check is that the index is enabled, then run the correct GATHER command on your index/table/schema. When that doesn't help, Oracle thinks that loading your index will actually take more time than loading the actual row values. In this case, add more columns to the index to make it appear more "diverse".
You might take a look at oracle stored outlines. You can take an existing query and create a stored outline and tweak the query just like hints. It is just very hard to use. Do some research before you decide to implement stored outlines.
You can add hints into the query that will cause it to look more favorably on one index over another index.
In general if you have collected good statistics on all the tables and indexes Oracle usually implements very good execution plans.
If your query doesn't include the indexed field in its conditions, then the DB would be foolish to use the index. Thus, I second Donnie's answer.
Yes, technically, you can force Oracle to use an index (without hints), in one scenario: if the table is an index-organized table, then logically the only way to query the table is via its index because there is no table to query.
What is the difference between Access and Filter predicates in Oracle execution plan?
If I understand correctly, "access" is used to determine which data blocks need to be read, and "filter" is applied after the blocks are read. Hence, filtering is "evil".
In the example of Predicate Information section of the execution plan below:
10 - access("DOMAIN_CODE"='BLCOLLSTS' AND "CURRENT_VERSION_IND"='Y')
filter("CURRENT_VERSION_IND"='Y')
why "CURRENT_VERSION_IND" is repeated in both Access and Filter sections?
The corresponding operation is INDEX RANGE scan on index, which is defined on fields (DOMAIN_CODE, CODE_VALUE, CURRENT_VERSION_IND, DECODE_DISPLAY).
My guess is that because CURRENT_VERSION_IND is not the second column in the index, Oracle can't use it during the Access stage. Hence, it accesses index by DOMAIN_CODE column, fetches all the blocks, and then filters them by CURRENT_VERSION_IND. Am I right?
No, the access predicates in this example indicates that the index is being traversed by both DOMAIN_CODE and CURRENT_VERSION_IND.
I wouldn't worry about the filter predicate that appears to be redundant - it seems to be a quirk of explain plan, probably something to do with the fact that it has to do a sort of skip-scan on the index (it does a range scan on the first column, then a skip scan over CODE_VALUE, searching for any matching CURRENT_VERSION_INDs).
Whether you need to modify the index or create another index is another matter entirely.
Also, just to correct a minor misunderstanding: the blocks have to be fetched from the index BEFORE it can do anything, whether executing the "access" or "filter" steps. If you're referring to fetching blocks from the table, then also the answer is no - you said the filter predicate "10" was on the index access, not on a table access; and anyway, there's no reason Oracle can't evaluate the filter on CURRENT_VERSION_IND on the index - it doesn't need to access the table at all, unless it needs other columns not included in the index.
I believe you are correct in your assessment of what Oracle is doing, but wrong to say that the filter step (or any other optimizer choice) is always "evil". It doesn't make sense to index absolutely every possible combination of columns that may be queried on, so filtering is frequently required.
However, if in this case adding CURRENT_VERSION_IND as the second column of the index improves performance significantly on frequently run queries and doesn't harm the performance of other queries, then it may make sense to do so.