【问题标题】:How to check whether index is being used or not in OracleOracle如何检查索引是否被使用
【发布时间】:2018-12-23 06:21:28
【问题描述】:
SELECT * 
FROM   (SELECT TEMP.*, 
               ROWNUM RNUM 
        FROM   (SELECT entry_guid 
                FROM   alertdevtest.ENTRY 
                WHERE  Upper(alert_name) = 'alertname' 
                       AND user_guid = 'AlertProductClientTest' 
                       AND product_code = '-101' 
                       AND status_code != 13) TEMP 
        WHERE  ROWNUM <= 2500) 
WHERE  rnum >= 0; 

SELECT * 
FROM   (SELECT TEMP.*, 
               ROWNUM RNUM 
        FROM   (SELECT entry_guid 
                FROM   alertdevtest.ENTRY 
                WHERE  Upper(alert_name) = 'alertname' 
                       AND user_guid = 'AlertProductClientTest' 
                       AND product_code = '-101' 
                       AND status_code != 13 
                       AND product_view IN ( 'PView' )) TEMP 
        WHERE  ROWNUM <= 2500) 
WHERE  rnum >= 0; 

我在查询上方运行,发现第二个查询与第一个查询相比性能下降。唯一的区别是第二个查询中的附加过滤器 AND PRODUCT_VIEW IN ('PView')。但它在该列上有索引。请让我知道性能下降的原因以及如何检查是否使用了索引?我正在使用 Oracle SQL 开发人员并尝试检查解释计划,但无法获得太多详细信息。

【问题讨论】:

  • 你能用PRODUCT_VIEW = 'PView'代替PRODUCT_VIEW IN ('PView')吗?它会给你更好的表现。另外,你能分享一下你的解释计划吗?
  • 我必须使用 IN,因为搜索可以使用多个字符串值。我无法在此处上传解释计划的图片。对于第一个查询,我主要看到 2 个部分,

标签: sql oracle


【解决方案1】:

在Oracle SQL Developer中,当工作表中有SQL时,有一个“Explain Plan”按钮,也可以按F10。执行解释计划后,它将显示在 SQL Developer 的底部视图中。有一列“OBJECT_NAME”,它会告诉你正在使用什么索引。例如,在我刚刚运行的查询中,在左列 (OPERATION) 中首先显示“SELECT STATEMENT”,然后是 SORT (AGGREGATE),然后是 INDEX (RANGE SCAN),然后在 OBJECT_NAME 列中显示 TICKER_IDX1,即我表上的索引名称。

因此您可以通过 OBJECT_NAME 列查看正在使用哪些索引。

Oracle 基于成本的优化器可能会选择次优的执行计划。多次更新统计数据将解决问题。其他选择是添加附加索引,即多列索引。您可以提示 SQL 语句,但这很少需要。此外,还可以重写查询。

【讨论】:

  • 两个查询在 object_name 字段下显示不同的索引名称。那么这就是响应时间慢的原因吗?第一个查询显示 product_code 索引,第二个查询显示 product_View 索引。为什么不在第二个查询中使用两个索引?
  • Oracle CBO 计算成本,并尝试执行它认为的最佳解决方案。因此,如果它不使用第二个索引,那是因为它认为这实际上会减慢查询速度。当它明显错误时 - 这通常是因为它没有有效的统计数据。所以,这是要检查的一件事,最近是否更新了统计数据?您可以重新运行表和索引的统计信息吗?
  • 如果您的查询运行时间相对较长,并且在多列上使用谓词,动态采样也可以提供帮助。
【解决方案2】:

EXPLAIN PLAN 语句是检查执行计划的最佳方式。 被认为有害的图形执行计划。

EXPLAIN PLAN 与执行计划的常见图形表示相比有很多好处:

  1. 简单、标准格式 DBMS_XPLAN.DISPLAY 可以在任何环境中工作,并生成每个 Oracle 专业人员都熟悉的输出。任何有权访问 Oracle 的人都可以重现该问题,并且每个人都可以使用相同的标准名称讨论该问题。 SQL Developer 可能是免费的,但大多数开发人员和 DBA 并不使用它。
  2. 易于处理输出 输出易于保存和共享 - 将输出存储在表格中,将文本复制到记事本等。使用 WinMerge 等程序进行比较也容易得多。大型查询可能会在执行计划中产生数百行,使用 diff 实用程序可以使调整更容易。对于编程任务,文字胜于图片。
  3. 包括重要部分 出于某些奇怪的原因,IDE 从不将Note 部分包含在执行计划中。该部分通常包含重要信息。在您的示例中,DBA 可能为其中一个查询而不是另一个查询修复了 SQL 计划基线。如果没有 Notes 部分,我们只能猜测是否发生了一些奇怪的事情。
  4. 更准确 一些工具使用单独的会话来生成图形执行计划并产生错误的结果。例如,如果没有alter session enable parallel dml;,计划可能会大不相同。这似乎不是 SQL Developer 的问题,但我在其他程序中看到过。
  5. 更强大 DBMS_XPLAN 可以编写脚本并具有许多强大的功能,例如format =&gt; '+outline'dbms_xplan.display_awr 等。

下面是EXPLAIN PLAN 的简单示例。这个计划很好,但它确实有一个大多数图形执行计划不会显示的巨大危险信号。最后一行, dynamic statistics used: dynamic sampling (level=2) 表示其中一张表缺少优化器统计信息。

drop table test1;
create table test1(a number);
explain plan for insert into test1 select * from test1;
select * from table(dbms_xplan.display);

Plan hash value: 4122059633

----------------------------------------------------------------------------------
| Id  | Operation                | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------
|   0 | INSERT STATEMENT         |       |     1 |    13 |     2   (0)| 00:00:01 |
|   1 |  LOAD TABLE CONVENTIONAL | TEST1 |       |       |            |          |
|   2 |   TABLE ACCESS FULL      | TEST1 |     1 |    13 |     2   (0)| 00:00:01 |
----------------------------------------------------------------------------------

Note
-----
   - dynamic statistics used: dynamic sampling (level=2)

为了快速检查,按 F10、F5、ctrl+E 或您特定 IDE 中的任何快捷方式更容易。但是对于将与他人分享的严肃分析,请始终使用EXPLAIN PLAN

【讨论】:

    【解决方案3】:

    了解性能不佳原因的最佳方法是获取 SQL*Trace。 有几种方法可以启用跟踪http://docs.oracle.com/cd/B19306_01/server.102/b14211/sqltrace.htm#g33356 例如

    EXECUTE DBMS_SESSION.SESSION_TRACE_ENABLE(waits => TRUE, binds => TRUE);
    

    您需要启用跟踪,运行这些查询,获取数据到最后(因为通常 Oracle 在获取期间执行的大部分工作),关闭会话(需要关闭光标以使执行计划与时间统计信息出现在跟踪文件中) .
    然后你应该去数据库服务器上的转储文件夹,获取跟踪文件,用户 tkprof 实用程序将其转换为更易读的方式,在里面找到这些查询,享受:)。
    SQL Trace 的好处是它提供了在 SQL 执行期间使用的真实计划,并且它为计划的每个步骤提供了非常精确的时间、读取、获取、一致读取、cpu 统计信息(不幸的是,我不知道任何其他工具可以这样做)。
    缺点是您需要特权才能开始跟踪,并且需要访问转储文件夹(或者您需要要求 DBA 使用跟踪和服务器管理员执行查询以获取文件)。
    更粗略的选择是启用对该 SQL 的监控(例如通过 /*+ monitor */hint)并使用 DBMS_SQLTUNE.REPORT_SQL_MONITOR http://docs.oracle.com/cd/B28359_01/appdev.111/b28419/d_sqltun.htm#CHDBHIBG - 它可能会为执行计划的每个步骤生成漂亮的 HTML 统计信息(如在 SQL Trace 中)
    优点是易于使用(您无需访问服务器文件夹即可使用它)。
    缺点是这种情况下的统计粒度通常为 1 秒,因此它仅适用于长时间运行的查询(10 秒或更长时间)。
    如果只需要检查 SQL 执行过程中是否使用了索引,可以查询 v$sql_plan 视图和 v$sql、v$sql_monitor 视图以找到合适的计划。

    【讨论】:

      猜你喜欢
      • 2013-08-23
      • 1970-01-01
      • 1970-01-01
      • 2011-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-22
      相关资源
      最近更新 更多