我有一张表table
,其中包含21百万条记录,其中有20百万条符合标准col1= 'text'
。然后我迭代地开始将col2的值设置为不等于NULL的值。在我改变了1000万条记录之后,下面的查询变慢了,开始时很快:
SELECT T_PK
FROM (SELECT T_PK
FROM table
WHERE col1= 'text' AND col2 IS NULL
ORDER BY T_PK DESC)
WHERE ROWNUM < 100;
我注意到,只要删除DESC
,整个订单按ORDER BY T_PK DESC
或整个外部查询条件WHERE ROWNUM < 100
,它就会再次快速(快速意味着一对夫妇)秒,&lt; 10s)。
执行计划如下:
其中索引全扫描降序索引在表的PK上执行。除了PK上的索引,我在col2
上定义了一个索引。
查询速度快然后变慢的原因可能是什么?无论已将多少条记录设置为非空值,如何快速进行查询?
答案 0 :(得分:2)
对于此查询:
SELECT T_PK
FROM (SELECT T_PK
FROM table
WHERE col1= 'text' AND col2 IS NULL
ORDER BY T_PK DESC
) t
WHERE ROWNUM < 100;
最佳指数为table(col1, col2, t_pk)
。
我认为问题在于优化器可以选择两个索引 - where
子句(col1
和 - 可能 - col2
)或{ {1}}。如果您有一个处理两个子句的索引,那么性能应该会提高。
t_pk
可能产生影响的一个原因是匹配行的位置。如果所有匹配的行都在表的前100,000行中,那么当您按顺序降序时,查询可能必须在找到匹配项之前抛出2090万行。
答案 1 :(得分:-2)
我认为 Burleson 很好地解释了这一点: http://www.dba-oracle.com/t_sql_tuning_rownum_equals_one.htm
当心!
使用 rownum< 会导致性能问题。使用 rownum 可能会将查询的 all_rows 优化器模式更改为 first_rows,从而导致意外的次优执行计划。一种解决方案是在使用 rownum 执行 top-n 查询时始终包含 all_rows 提示。