【问题标题】:Query with rownum got slow使用 rownum 查询变慢
【发布时间】:2015-05-29 16:09:05
【问题描述】:

我有一张表table,其中有 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、整个 order by 子句 ORDER BY T_PK DESC 或带有条件 WHERE ROWNUM &lt; 100 的整个外部查询,它就会再次快速(快速意味着几秒钟,

执行计划如下:

其中索引全扫描降序索引是对表的PK进行的。除了 PK 上的索引,我在col2 上定义了一个索引。

查询先快后变慢的原因可能是什么?无论有多少记录已设置为非空值,如何使查询快速?

【问题讨论】:

  • 您正在跨提交进行选择,这意味着您正在从回滚中读取。也许告诉您的 DBA 您正在尝试做什么(无论如何都要提醒)并运行单个更新语句
  • 现在col2 中的数据看起来与以前大不相同,您可能会从使用DBMS_STATS.GATHER_TABLE_STATS 收集表统计信息中受益。您可能还想在 col2 上重新创建索引以允许通过 NULL 进行查找:DROP INDEX index_on_col2; CREATE INDEX index_on_col2 ON table (col2, '1');

标签: sql oracle performance oracle11g


【解决方案1】:

对于这个查询:

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),要么用于t_pk。如果您有一个同时处理两个子句的索引,那么性能应该会提高。

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

【讨论】:

    【解决方案2】:

    我认为 Burleson 很好地解释了这一点: http://www.dba-oracle.com/t_sql_tuning_rownum_equals_one.htm

    小心!
    这种使用 rownum

    【讨论】:

      猜你喜欢
      • 2013-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-04
      • 1970-01-01
      相关资源
      最近更新 更多