oracle select query - 多列索引

时间:2010-04-26 12:36:19

标签: oracle indexing

我正在进行SQL查询,并尝试对其进行优化,因为执行时间太长。

我之间有一些选择和UNION。 每个select都在同一个表上,但在WHERE子句中具有不同的条件。 基本上我总是喜欢这样的东西:

select * from A
where field1 <=TO_DATE ('01/01/2010', 'DD/MM/YYYY')
AND field1 >= TO_DATE(some date)
and field2 IN (...)

UNION 
select * from A
where field1 <=TO_DATE ('01/01/2010', 'DD/MM/YYYY')
AND field1 >= TO_DATE(some date2)
and field2 =(...)

UNION
....

我在field1上有一个索引(它是一个日期字段,而field2是一个数字)。 现在,当我选择时,如果我只选择

WHERE field1 <TO_DATE ('01/01/2010', 'DD/MM/YYYY')

它不使用索引。 我正在使用Toad看到解释清楚,它说:

SELECT STAITEMENT Optimiser Mode = CHOOSE
TABLE ACCESS FULL 

这是一个庞大的表,此列的索引就在那里。

关于这个优化器的任何想法?为什么它不使用索引?

另一个问题是,如果我在field1和field2上有where子句,我必须为每个字段只创建​​一个索引或一个索引吗?

5 个答案:

答案 0 :(得分:1)

如果没有联盟并且在你的不同条款之间使用OR,你会不会感觉更好?

select * from A
where (
  field1 <"toto"
  and field2 IN (...)
)
OR
(
  field1 >"toto2"
  and field2 IN (...)
)
OR
....

也可以在2列上建立索引。

CREATE INDEX index_name
ON A (field1, field2);

答案 1 :(得分:0)

您可以在两列上创建一个索引。但是您的问题将field1视为上面的字符串,然后像下面的日期一样。这是故意的吗?此外,优化器根据其思考选择。那么你的统计数据是最新的吗?如果没有,它可能会认为FTS是找到所需记录的最佳方式。

答案 2 :(得分:0)

  

关于这个优化器的任何想法?为什么它不使用索引?

最可能是因为这种情况

field1 < '12/12/2010'

返回所有或几乎所有行。

在这种情况下,FULL TABLE SCAN更好。

  

另一个问题是,如果我在field1和field2上有where子句,我必须为每个字段只创建​​一个索引或一个索引吗?

对于此查询:

select * from A
where field1 <"toto"
and field2 IN (...)

,您需要创建一个复合索引:

CREATE INDEX ix_a_2_1 ON A (field2, field1)

这将使用INLIST ITERATOR将查询拆分为多个连续范围,并使用INDEX RANGE SCAN返回每个范围的值。

答案 3 :(得分:0)

  • 由于您正在处理field1的日期,因此您想使用TO_DATE。例如,WHERE field1 < TO_DATE('2010/12/12 12:00:00', 'yyyy/mm/dd hh24:mi:ss')

  • 该字段的索引类型是什么?我假设一个b树索引,在这种情况下,less-than运算符是正常的,但优化器可能决定不使用它,具体取决于当前表统计信息。如果要强制使用索引,可以在提示中指定它,看看它如何影响性能。

    SELECT /*+ index(tbl.INDEX_NAME) */
    tbl.*
    FROM A tbl WHERE field1 < TO_DATE('2010/12/12 12:00:00','yyyy/mm/dd hh24:mi:ss');

  • 至于最后一个问题,您可以单独为每列创建索引,也可以使用两列创建复合索引。如果您总是要根据两列中的值进行选择,那么这两列上的复合索引可能会更好。

答案 4 :(得分:-1)

我不是最大的Oracle专家,但我想你在使用'&gt;'时无法获得索引的优势或'&lt;'运营商。索引提供了一种快速查找特定值的方法,而不是一系列值。因此,当您查找“小于”特定值的值时,索引不执行任何操作。