Can Multiple Indexes Work Together?

前端 未结 9 1386
情书的邮戳
情书的邮戳 2021-02-19 07:13

Suppose I have a database table with two fields, \"foo\" and \"bar\". Neither of them are unique, but each of them are indexed. However, rather than being indexed together, th

相关标签:
9条回答
  • 2021-02-19 07:50

    I'm sure you can also have Oracle display a query plan so you can see exactly which index is used first.

    0 讨论(0)
  • 2021-02-19 07:56

    Oracle will almost certainly use the most selective index to drive the query, and you can check that with the explain plan.

    Furthermore, Oracle can combine the use of both indexes in a couple of ways -- it can convert btree indexes to bitmaps and perform a bitmap ANd operation on them, or it can perform a hash join on the rowid's returned by the two indexes.

    One important consideration here might be any correlation between the values being queried. If foo='hello' accounts for 80% of values in the table and bar='world' accounts for 10%, then Oracle is going to estimate that the query will return 0.8*0.1= 8% of the table rows. However this may not be correct - the query may actually return 10% of the rwos or even 0% of the rows depending on how correlated the values are. Now, depending on the distribution of those rows throughout the table it may not be efficient to use an index to find them. You may still need to access (say) 70% or the table blocks to retrieve the required rows (google for "clustering factor"), in which case Oracle is going to perform a ful table scan if it gets the estimation correct.

    In 11g you can collect multicolumn statistics to help with this situation I believe. In 9i and 10g you can use dynamic sampling to get a very good estimation of the number of rows to be retrieved.

    To get the execution plan do this:

    explain plan for
    SELECT *
    FROM   sometable
    WHERE  foo='hello' AND bar='world'
    /
    select * from table(dbms_xplan.display)
    /
    

    Contrast that with:

    explain plan for
    SELECT /*+ dynamic_sampling(4) */
           *
    FROM   sometable
    WHERE  foo='hello' AND bar='world'
    /
    select * from table(dbms_xplan.display)
    /
    
    0 讨论(0)
  • 2021-02-19 07:56

    Yes, you can give "hints" with the query to Oracle. These hints are disguised as comments ("/* HINT */") to the database and are mainly vendor specific. So one hint for one database will not work on an other database.

    I would use index hints here, the first hint for the small table. See here.

    On the other hand, if you often search over these two fields, why not create an index on these two? I do not have the right syntax, but it would be something like

    CREATE INDEX IX_BAR_AND_FOO on sometable(bar,foo);
    

    This way data retrieval should be pretty fast. And in case the concatenation is unique hten you simply create a unique index which should be lightning fast.

    0 讨论(0)
提交回复
热议问题