【问题标题】:Optimizing select top N query in oracle优化oracle中的select top N查询
【发布时间】:2017-08-19 19:07:34
【问题描述】:

我使用 sort 和 rownum 查询以获得大表中的前 N ​​条记录(超过 21M 条记录)。我使用 order 和 rownum 选择 n 最近的记录,如下所示。我在可为空的 create_date 列上定义了索引,但执行时间超过 30 秒。这次我该如何改进?

select * from(
  select *
  from my_table t
  order by t.create_date
)
where rownum<N

解释计划:

----------------------------------------------------------------------------------------------------
| Id  | Operation                 | Name             | Rows     | Bytes       | Cost    | Time     |
----------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT          |                  |        9 |       31446 | 1153573 | 03:50:43 |
| * 1 |   COUNT STOPKEY           |                  |          |             |         |          |
|   2 |    VIEW                   |                  | 21335585 | 74546533990 | 1153573 | 03:50:43 |
| * 3 |     SORT ORDER BY STOPKEY |                  | 21335585 |  4544479605 | 1153573 | 03:50:43 |
|   4 |      TABLE ACCESS FULL    |     MY_TABLE     | 21335585 |  4544479605 |  165097 | 00:33:02 |
----------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
------------------------------------------
* 1 - filter(ROWNUM<10)
* 3 - filter(ROWNUM<10)

【问题讨论】:

  • Oracle 的哪个版本?
  • 可以发布查询计划吗?
  • 请附加解释计划 - 运行 EXPLAIN PLAN FOR your-query 然后运行 ​​SELECT * FROM table(DBMS_XPLAN.Display),并复制最后一个查询的结果(作为纯文本 - 不要打印屏幕)并将其附加到问题中。
  • 请注意,11g 不是版本标识符,它只是 Oracle 使用的营销名称。版本是 11.1 或 11.2(通常 full 版本号,如 11.2.0.2.0,也是相关的)。想知道完整版本号,不知道的可以跑select * from v$version
  • @trincot 11.2.0.4.0

标签: oracle oracle11g


【解决方案1】:

您可以尝试first_rows 提示。

FIRST_ROWS(n)

提示 FIRST_ROWS(n)(其中 n 是任何正整数)或 FIRST_ROWS 指示 Oracle 优化单个 SQL 语句以实现快速响应。 FIRST_ROWS(n) 提供更高的精度,因为它指示 Oracle 选择最有效地返回前 n 行的计划。 FIRST_ROWS 提示优化了返回第一行的最佳计划,为了向后兼容和计划稳定性而保留。

例如,优化器使用基于成本的方法来优化此语句以获得最佳响应时间:

SELECT /*+ FIRST_ROWS(10) */employee_id、last_name、salary、job_id 来自员工 WHERE department_id = 20;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-12
    • 1970-01-01
    • 2011-10-13
    • 1970-01-01
    • 2013-11-27
    相关资源
    最近更新 更多