Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 使用rownum的查询速度变慢_Sql_Oracle_Performance_Oracle11g - Fatal编程技术网

Sql 使用rownum的查询速度变慢

Sql 使用rownum的查询速度变慢,sql,oracle,performance,oracle11g,Sql,Oracle,Performance,Oracle11g,我得到了一个有2100万条记录的表,其中有2000万条符合标准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 <

我得到了一个有2100万条记录的表,其中有2000万条符合标准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,整个orderby子句order by T_PK DESC,或者整个外部查询,条件是ROWNUM<100,它又快了,fast意味着几秒钟,<10s

执行计划如下所示:

其中,对表的主键执行索引完全扫描降序索引。除了PK上的索引之外,我在col2上定义了一个索引

是什么原因导致查询很快,然后又变得很慢?无论有多少条记录已设置为非空值,如何快速查询

对于此查询:

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;
最佳指标为表COL1、col2、t_pk

我认为问题在于优化器有两个索引可供选择——要么针对where子句col1,要么可能针对col2,要么针对t_pk选择一个。如果只有一个索引处理这两个子句,那么性能应该会提高


DESC可能产生不同的一个原因是匹配行所在的位置。如果所有匹配的行都在表的前100000行中,那么当您按降序排序时,查询可能必须抛出2090万行才能找到匹配项。

我认为Burleson很好地解释了这一点:

当心!
使用rownum<会导致性能问题。使用rownum可能会将查询的“所有行”优化器模式更改为“第一行”,从而导致意外的次优执行计划。一种解决方案是在使用rownum执行top-n查询时始终包含一个all_rows提示。

您正在跨提交进行选择,这意味着您正在从回滚中读取。也许你可以告诉你的DBA你想做什么,不管怎样,只运行一个update语句现在col2中的数据看起来与以前有很大的不同,使用DBMS_STATS.GATHER_table_STATS收集表统计信息可能会让你受益匪浅。您可能还希望在col2上重新创建索引,以允许通过NULL进行查找:DROP index index_on_col2;在表col2上的_col2上创建索引_,'1';