简体   繁体   English

Oracle中如何查看索引是否被使用

[英]How to check whether index is being used or not in Oracle

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; 

Am running above queries and seeing performance degradation in the second query compare to the first one.我正在运行上述查询,发现第二个查询与第一个查询相比性能下降。 The only difference is being the additional filter AND PRODUCT_VIEW IN ('PView') in second query.唯一的区别是第二个查询中的附加过滤器和 PRODUCT_VIEW IN ('PView')。 But it has index on that column.但它在该列上有索引。 Please let me know what can be the reason for performance degradation and how can I check whether index being used or not?请让我知道性能下降的原因是什么以及如何检查索引是否被使用? Am using Oracle SQL developer and tried checking explain plan but couldn't get much details.我正在使用 Oracle SQL 开发人员并尝试检查解释计划但无法获得更多详细信息。

In Oracle SQL Developer, when you have SQL in the worksheet, there is a button "Explain Plan", you can also hit F10. 在Oracle SQL Developer中,当工作表中包含SQL时,会有一个“说明计划”按钮,您也可以按F10键。 After you execute Explain plan, it will show in the bottom view of SQL Developer. 执行Explain计划后,它将显示在SQL Developer的底部视图中。 There is a column "OBJECT_NAME", it will tell you what index is being used. 有一列“ OBJECT_NAME”,它将告诉您正在使用什么索引。 For example, in a query I just ran, in the left column (OPERATION) it shows "SELECT STATEMENT" first, then SORT (AGGREGATE) and then INDEX (RANGE SCAN) and then in the OBJECT_NAME column it shows TICKER_IDX1, which is the name of an index on my table. 例如,在我刚运行的查询中,左列(OPERATION)首先显示“ SELECT STATEMENT”,然后显示SORT(AGGREGATE),然后显示INDEX(RANGE SCAN),然后在OBJECT_NAME列中显示TICKER_IDX1,即我表上索引的名称。

So you can see via the OBJECT_NAME column what indexes are being used. 因此,您可以通过OBJECT_NAME列查看正在使用的索引。

It can happen that the Oracle Cost Based Optimizer chooses a sub-optimal execution plan. Oracle基于成本的优化器可能会选择次优的执行计划。 Many times updating statistics will solve the issue. 许多次更新统计信息将解决此问题。 Other choices are to add additional indexes, in other words a multi-column index. 其他选择是添加其他索引,换句话说就是多列索引。 You can hint a SQL statement, but that is rarely needed. 您可以提示一条SQL语句,但这很少需要。 Also, it's possible to rewrite the query. 另外,可以重写查询。

The EXPLAIN PLAN statement is the best way to check the execution plan. EXPLAIN PLAN语句是检查执行计划的最佳方法。 Graphical execution plans considered harmful. 图形执行计划被认为是有害的。

EXPLAIN PLAN has many benefits over common graphical representation of execution plans: EXPLAIN PLAN对于执行计划的常见图形表示, EXPLAIN PLAN具有许多优点:

  1. Simple, Standard Format DBMS_XPLAN.DISPLAY works in any environment and produces output that every Oracle professional is familiar with. 简单,标准格式的 DBMS_XPLAN.DISPLAY可在任何环境中工作,并产生Oracle专业人员所熟悉的输出。 Anyone with access to Oracle can reproduce the issue, and everyone can discuss the issue with the same standard names. 有权使用Oracle的任何人都可以重现该问题,并且每个人都可以使用相同的标准名称讨论该问题。 SQL Developer may be free but most developers and DBAs do not use it. SQL Developer可能是免费的,但大多数开发人员和DBA都不使用它。
  2. Easy to Process Output The output is easy to save and share - store the output in a table, copy the text into Notepad, etc. It's also much easier to compare using a program like WinMerge. 易于处理输出输出易于保存和共享-将输出存储在表格中,将文本复制到记事本中,等等。使用WinMerge之类的程序进行比较也更加容易。 Large queries may produce hundreds of lines in the execution plan, using a diff utility can make tuning much easier. 大型查询可能会在执行计划中产生数百行,使用diff实用程序可使调整变得更加容易。 For programming tasks text is better than a picture. 对于编程任务,文本胜于图片。
  3. Includes Important Sections For some bizarre reason IDEs never include the Note section in execution plans. 包括重要部分由于某些奇怪的原因,IDE从未在执行计划中包括“ Note部分。 That section often includes important information. 该部分通常包含重要信息。 In your example, it's possible that a DBA fixed a SQL Plan Baseline for one of the queries but not the other. 在您的示例中,DBA可能为其中一个查询而不是其他查询固定了SQL Plan Baseline。 Without the Notes section we'll just have to guess if there's something weird going on. 如果没有“ Notes部分,我们只需要猜测是否发生了奇怪的事情。
  4. More Accurate Some tools use a separate session to generate graphical execution plans and produce wrong results. 更准确一些工具使用单独的会话来生成图形执行计划并产生错误的结果。 For example, plans may be very different without alter session enable parallel dml; 例如,如果没有alter session enable parallel dml; ,计划可能会大不相同alter session enable parallel dml; . This doesn't appear to be an issue with SQL Developer but I've seen it with other programs. 对于SQL Developer来说这似乎不是问题,但是我在其他程序中已经看到了。
  5. More Powerful DBMS_XPLAN can be scripted and has many powerful features, like format => '+outline' , dbms_xplan.display_awr , etc. 可以编写更强大的 DBMS_XPLAN脚本,并具有许多强大的功能,例如format => '+outline'dbms_xplan.display_awr等。

Below is a simple example of EXPLAIN PLAN . 以下是EXPLAIN PLAN的简单示例。 This plan is fine but it does have a huge red flag that most graphical execution plans would not show. 这个计划很好,但是它确实有一个巨大的危险信号,大多数图形执行计划都不会显示。 The last line, dynamic statistics used: dynamic sampling (level=2) implies that one of the tables is missing optimizer statistics. 最后一行,使用的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)

For a quick check it's easier to hit F10, F5, ctrl+E, or whatever the shortcut is in your specific IDE. 快速检查可以轻松按F10,F5,Ctrl + E或您特定IDE中的任何快捷键。 But for serious analysis that will be shared with others, always use EXPLAIN PLAN . 但是对于要与他人共享的严肃分析,请始终使用EXPLAIN PLAN

Best thing to understand reason of poor performance is to get SQL*Trace. 了解性能低下的原因的最好的办法是获取SQL * Trace。 There are several ways to enable tracing http://docs.oracle.com/cd/B19306_01/server.102/b14211/sqltrace.htm#g33356 For example 有多种启用跟踪的方法http://docs.oracle.com/cd/B19306_01/server.102/b14211/sqltrace.htm#g33356例如

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

You need to enable trace, run these queries, fetch data to the end (because usually most of work Oracle perform during fetch), close session (cursor need to be closed to make execution plan with time statistics appear in trace file). 您需要启用跟踪,运行这些查询,最后获取数据(因为通常Oracle在获取期间执行大部分工作),关闭会话(需要关闭游标以使带有时间统计信息的执行计划出现在跟踪文件中)。
Then you should go to dump folder on database server, get trace file, user tkprof utility to convert it to more readable way, find these queries inside, enjoy :). 然后,您应该转到数据库服务器上的转储文件夹,获取跟踪文件,使用tkprof实用程序将其转换为更具可读性的方式,在其中找到这些查询,然后享受:)。
Benefits of SQL Trace is that it gives real plan that was used during SQL execution, and it gives very precise time,reads,gets, consistent reads, cpu statistics for each step of the plan (unfortunately I don't know any other tool that can do this). SQL Trace的好处在于,它提供了在SQL执行过程中使用的真实计划,并且为计划的每个步骤提供了非常精确的时间,读取,获取,一致读取,cpu统计信息(不幸的是,我不知道任何其他工具可以可以做到)。
Disadvantage is that you need privilege to start tracing and you need access to dump folder (or you need to ask DBA to execute query with tracing and server admin to get file). 缺点是您需要特权才能开始跟踪,并且需要访问转储文件夹(或者您需要让DBA使用跟踪来执行查询,并且需要服务器管理员来获取文件)。
More rough option is to enable monitoring for this SQL (for example by /*+ monitor */ hint) and use DBMS_SQLTUNE.REPORT_SQL_MONITOR http://docs.oracle.com/cd/B28359_01/appdev.111/b28419/d_sqltun.htm#CHDBHIBG - it may generate pretty HTML with stats for each step of execution plan (like in SQL Trace) 更粗糙的选择是启用对此SQL的监视(例如,通过/ * + monitor * /提示)并使用DBMS_SQLTUNE.REPORT_SQL_MONITOR http://docs.oracle.com/cd/B28359_01/appdev.111/b28419/d_sqltun.htm #CHDBHIBG-可能会为执行计划的每个步骤生成带有统计信息的漂亮HTML(例如在SQL Trace中)
Advantage is ease of use (you don't need to have access to server folder to use this). 优点是易于使用(您无需访问服务器文件夹即可使用此功能)。
Disadvantage is that grain of statistics in this case is usually 1 second, so it is useful only for long-running queries (10 seconds and more). 缺点是这种情况下的统计数据通常为1秒,因此仅对长时间运行的查询(10秒或更长时间)有用。
If you need just check if index was used during SQL execution, you may query v$sql_plan view and v$sql, v$sql_monitor views to find appropriate plan. 如果仅需要检查在SQL执行期间是否使用了索引,则可以查询v $ sql_plan视图和v $ sql,v $ sql_monitor视图以找到适当的计划。

You can Run this query to check usage of index.您可以运行此查询来检查索引的使用情况。

select ius.* , 
(select  sum(trunc(bytes / 1024 / 1024/ 1024  ,2)) 
 from dba_segments sgm 
 where  sgm.owner = ius.OWNER
   and sgm.segment_name = ius.name ) Used_Space 
   ,ind.DISTINCT_KEYS, ind.Total_Ind_Rows , ind.Total_Leaf_Block,
   trunc((ius.bucket_0_access_count / nullif(ius.total_access_count,0)) *100 ,2)Access_0_PCT,
   trunc((ius.bucket_1_access_count / nullif(ius.total_access_count,0)) *100 ,2) Access_1_PCT,
   trunc((ius.bucket_2_10_access_count / nullif(ius.total_access_count,0)) *100,2) Access_2_10_PCT,
   trunc((ius.bucket_11_100_access_count / nullif(ius.total_access_count,0)) *100,2) Access_11_100_PCT,
   trunc((ius.bucket_101_1000_access_count / nullif(ius.total_access_count,0)) *100,2) Access_101_1000_PCT,
   trunc((ius.bucket_1000_plus_access_count / nullif(ius.total_access_count,0)) *100,2) Access_1000_plus_PCT
from dba_index_usage ius , 
 (select ind.OWNER,ind.INDEX_NAME,ind.DISTINCT_KEYS, sum(ind.num_rows)Total_Ind_Rows,sum(ind.LEAF_BLOCKS)Total_Leaf_Block,
         trunc(sum(ind.num_rows)/nullif(sum(ind.LEAF_BLOCKS),0),2) RowsInBlocks
  from all_indexes ind 
  where ind.owner = &SchemaName
  group by ind.OWNER,ind.INDEX_NAME,ind.DISTINCT_KEYS
  ) ind
where ius.owner = &SchemaName 
  and ius.name = ind.INDEX_NAME

Also, you can add v$sql_plan and dba_hist_sql_plan to filter unused indexes.此外,您可以添加 v$sql_plan 和 dba_hist_sql_plan 来过滤未使用的索引。

and not exists 
      (select 'x'
       from v$sql_plan pln
       where  pln.OPERATION = 'INDEX'
        and pln.OBJECT_OWNER = ius.owner
        and pln.OBJECT_NAME = ius.name)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM