<strong>最近发现orcle 11g select count(*) from v$lock 查询很慢,觉得有必要进行详细的分析::</strong>
select count(*) from v$lock; -------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 50 | 0 (0)| 00:00:01 | | 1 | SORT AGGREGATE | | 1 | 50 | | | |* 2 | HASH JOIN | | 1 | 50 | 0 (0)| 00:00:01 | |<span style="color:#ff0000;"> 3 | MERGE JOIN CARTESIAN | | 100 | 3800 | 0 (0)| 00:00:01 | |* 4 | FIXED TABLE FULL | X$KSUSE | 1 | 19 | 0 (0)| 00:00:01 | | 5 | BUFFER SORT | | 100 | 1900 | 0 (0)| 00:00:01 | | 6 | FIXED TABLE FULL | X$KSQRS | 100 | 1900 | 0 (0)| 00:00:01 |</span> | 7 | VIEW | GV$_LOCK | 10 | 120 | 0 (0)| 00:00:01 | | 8 | UNION-ALL | | | | | | |* 9 | <span style="color:#3333ff;">FILTER | | | | | | | 10 | VIEW | GV$_LOCK1 | 2 | 24 | 0 (0)| 00:00:01 | | 11 | UNION-ALL | | | | | | |* 12 | FIXED TABLE FULL| X$KDNSSF | 1 | 64 | 0 (0)| 00:00:01 | |* 13 | FIXED TABLE FULL| X$KSQEQ | 1 | 64 | 0 (0)| 00:00:01 | |* 14 | FIXED TABLE FULL | X$KTADM | 1 | 64 | 0 (0)| 00:00:01 |-- |* 15 | FIXED TABLE FULL | X$KTATRFIL | 1 | 64 | 0 (0)| 00:00:01 | |* 16 | FIXED TABLE FULL | X$KTATRFSL | 1 | 64 | 0 (0)| 00:00:01 | |* 17 | FIXED TABLE FULL | X$KTATL | 1 | 64 | 0 (0)| 00:00:01 | |* 18 | FIXED TABLE FULL | X$KTSTUSC | 1 | 64 | 0 (0)| 00:00:01 | |* 19 | FIXED TABLE FULL | X$KTSTUSS | 1 | 64 | 0 (0)| 00:00:01 |</span>
生产库10046:
******************************************************************************** SQL ID: ct78468spkzrt Plan Hash: 2384831130 select count(*) from v$lock call count cpu elapsed disk query current rows ------- ------ -------- ---------- ---------- ---------- ---------- ---------- Parse 1 0.00 0.01 0 0 0 0 Execute 1 0.00 0.00 0 0 0 0 Fetch 2 13.09 21.12 0 0 0 1 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- total 4 13.09 21.13 0 0 0 1 Misses in library cache during parse: 1 Optimizer mode: ALL_ROWS Parsing user id: SYS Number of plan statistics captured: 1 select count(*) from X$KSQRS Rows (1st) Rows (avg) Rows (max) Row Source Operation ---------- ---------- ---------- --------------------------------------------------- 1 1 1 SORT AGGREGATE (cr=0 pr=0 pw=0 time=21123213 us) 355 355 355 HASH JOIN (cr=0 pr=0 pw=0 time=21083516 us cost=1 size=50 card=1) <span style="color:#ff0000;"> 10715136 10715136 10715136 MERGE JOIN CARTESIAN (cr=0 pr=0 pw=0 time=10072178 us cost=0 size=3800 card=100) 1536 1536 1536 FIXED TABLE FULL X$KSUSE (cr=0 pr=0 pw=0 time=6834 us cost=0 size=19 card=1) 10715136 10715136 10715136 BUFFER SORT (cr=0 pr=0 pw=0 time=3222054 us cost=0 size=1900 card=100)</span> 6976 6976 6976 FIXED TABLE FULL X$KSQRS (cr=0 pr=0 pw=0 time=1911 us cost=0 size=1900 card=100) 356 356 356 VIEW GV$_LOCK (cr=0 pr=0 pw=0 time=11637 us cost=0 size=120 card=10) 356 356 356 UNION-ALL (cr=0 pr=0 pw=0 time=11281 us) 352 352 352 FILTER (cr=0 pr=0 pw=0 time=10570 us) 352 352 352 VIEW GV$_LOCK1 (cr=0 pr=0 pw=0 time=10330 us cost=0 size=24 card=2) 352 352 352 UNION-ALL (cr=0 pr=0 pw=0 time=9978 us) 0 0 0 FIXED TABLE FULL X$KDNSSF (cr=0 pr=0 pw=0 time=594 us cost=0 size=64 card=1) 352 352 352 FIXED TABLE FULL X$KSQEQ (cr=0 pr=0 pw=0 time=8792 us cost=0 size=64 card=1) 4 4 4 FIXED TABLE FULL X$KTADM (cr=0 pr=0 pw=0 time=12004 us cost=0 size=64 card=1) 0 0 0 FIXED TABLE FULL X$KTATRFIL (cr=0 pr=0 pw=0 time=17 us cost=0 size=64 card=1) 0 0 0 FIXED TABLE FULL X$KTATRFSL (cr=0 pr=0 pw=0 time=6 us cost=0 size=64 card=1) 0 0 0 FIXED TABLE FULL X$KTATL (cr=0 pr=0 pw=0 time=9 us cost=0 size=64 card=1) 0 0 0 FIXED TABLE FULL X$KTSTUSC (cr=0 pr=0 pw=0 time=17 us cost=0 size=64 card=1) 0 0 0 FIXED TABLE FULL X$KTSTUSS (cr=0 pr=0 pw=0 time=11 us cost=0 size=64 card=1) 0 0 0 FIXED TABLE FULL X$KTSTUSG (cr=0 pr=0 pw=0 time=12 us cost=0 size=64 card=1) 0 0 0 FIXED TABLE FULL X$KTCXB (cr=0 pr=0 pw=0 time=6216 us cost=0 size=64 card=1) Elapsed times include waiting on following events: Event waited on Times Max. Wait Total Waited ---------------------------------------- Waited ---------- ------------ SQL*Net message to client 2 0.00 0.00 asynch descriptor resize 61 0.00 0.00 SQL*Net message from client 2 30.66 30.66
GV¥lock性能正常:
15:21:44 [email protected](newgsdb01)> select count(*) from gv$lock; COUNT(*) ---------- 706 Elapsed: 00:00:00.07 Execution Plan ---------------------------------------------------------- Plan hash value: 483924080 ----------------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib | ----------------------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | 1 (100)| 00:00:01 | | | | | 1 | SORT AGGREGATE | | 1 | | | | | | | | 2 | PX COORDINATOR | | 10 | | 1 (100)| 00:00:01 | | | | | 3 | PX SEND QC (RANDOM) | :TQ10000 | 10 | 370 | 1 (100)| 00:00:01 | Q1,00 | P->S | QC (RAND) | | 4 | VIEW | GV$LOCK | | | | | Q1,00 | PCWP | | |* 5 | HASH JOIN | | 10 | 370 | 1 (100)| 00:00:01 | Q1,00 | PCWP | | |* 6 | HASH JOIN | | 10 | 180 | 1 (100)| 00:00:01 | Q1,00 | PCWP | | | 7 | VIEW | GV$_LOCK | 10 | 120 | 0 (0)| 00:00:01 | Q1,00 | PCWP | | | 8 | UNION-ALL | | | | | | Q1,00 | PCWP | | |* 9 | FILTER | | | | | | Q1,00 | PCWP | | | 10 | VIEW | GV$_LOCK1 | 2 | 24 | 0 (0)| 00:00:01 | Q1,00 | PCWP | | | 11 | UNION-ALL | | | | | | Q1,00 | PCWP | | |* 12 | FIXED TABLE FULL| X$KDNSSF | 1 | 64 | 0 (0)| 00:00:01 | Q1,00 | PCWP | | |* 13 | FIXED TABLE FULL| X$KSQEQ | 1 | 64 | 0 (0)| 00:00:01 | Q1,00 | PCWP | | |* 14 | FIXED TABLE FULL | X$KTADM | 1 | 64 | 0 (0)| 00:00:01 | Q1,00 | PCWP | | |* 15 | FIXED TABLE FULL | X$KTATRFIL | 1 | 64 | 0 (0)| 00:00:01 | Q1,00 | PCWP | | |* 16 | FIXED TABLE FULL | X$KTATRFSL | 1 | 64 | 0 (0)| 00:00:01 | Q1,00 | PCWP | | |* 17 | FIXED TABLE FULL | X$KTATL | 1 | 64 | 0 (0)| 00:00:01 | Q1,00 | PCWP | | |* 18 | FIXED TABLE FULL | X$KTSTUSC | 1 | 64 | 0 (0)| 00:00:01 | Q1,00 | PCWP | | |* 19 | FIXED TABLE FULL | X$KTSTUSS | 1 | 64 | 0 (0)| 00:00:01 | Q1,00 | PCWP | | |* 20 | FIXED TABLE FULL | X$KTSTUSG | 1 | 64 | 0 (0)| 00:00:01 | Q1,00 | PCWP | | |* 21 | FIXED TABLE FULL | X$KTCXB | 1 | 64 | 0 (0)| 00:00:01 | Q1,00 | PCWP | | | <span style="color:#ff6666;"> 22 | FIXED TABLE FULL | X$KSUSE | 100 | 600 | 0 (0)| 00:00:01 | Q1,00 | PCWP | | | 23 | FIXED TABLE FULL | X$KSQRS | 100 | 1900 | 0 (0)| 00:00:01 | Q1,00 | PCWP | |</span>
<strong>并且查询select * from v$lock是正常的</strong>
对这两个表的信息应该是正确的,再看我测试环境:
-------------------------------------------------------------------------------- Plan hash value: 2329815124 -------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU -------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 40 | 1 (100 | 1 | SORT AGGREGATE | | 1 | 40 | | 2 | NESTED LOOPS | | 1 | 40 | 1 (100 |* 3 | HASH JOIN | | 1 | 31 | 1 (100 |* 4 | FIXED TABLE FULL | X$KSUSE | 1 | 19 | 0 (0 | 5 | VIEW | GV$_LOCK | 10 | 120 | 0 (0 | 6 | UNION-ALL | | | | |* 7 | FILTER | | | | | 8 | VIEW | GV$_LOCK1 | 2 | 24 | 0 (0 | 9 | UNION-ALL | | | | |* 10 | FIXED TABLE FULL | X$KDNSSF | 1 | 64 | 0 (0 |* 11 | FIXED TABLE FULL | X$KSQEQ | 1 | 64 | 0 (0 |* 12 | FIXED TABLE FULL | X$KTADM | 1 | 64 | 0 (0 |* 13 | FIXED TABLE FULL | X$KTATRFIL | 1 | 64 | 0 (0 |* 14 | FIXED TABLE FULL | X$KTATRFSL | 1 | 64 | 0 (0 |* 15 | FIXED TABLE FULL | X$KTATL | 1 | 64 | 0 (0 |* 16 | FIXED TABLE FULL | X$KTSTUSC | 1 | 64 | 0 (0 |* 17 | FIXED TABLE FULL | X$KTSTUSS | 1 | 64 | 0 (0 |* 18 | FIXED TABLE FULL | X$KTSTUSG | 1 | 64 | 0 (0 |* 19 | FIXED TABLE FULL | X$KTCXB | 1 | 64 | 0 (0 |* 20 | FIXED TABLE FIXED INDEX| X$KSQRS (ind:1) | 1 | 9 | 0 (0 --------------------------------------------------------------------------------
生产库和测试库的执行计划是不一样的,寻找生产库为啥有笛卡尔计:
根据经验处理办法有两种:
一:收集内存表所有的统计信息
execute dbms_stats.gather_fixed_objects_stats()
二:添加提示
select /*+ rule */count(*) from v$lock
遗憾的是当时我只考虑统计信息没有考虑添加提示:
思考:
对内存表信息的收集
SQL> begin 2 dbms_stats.gather_fixed_objects_stats(stattab => 'X$KSQRS'); 3 end; 4 / begin dbms_stats.gather_fixed_objects_stats(stattab => 'X$KSQRS'); end; ORA-02030: 只能从固定的表/视图查询 ORA-06512: 在 "SYS.DBMS_STATS", line 20508 ORA-06512: 在 "SYS.DBMS_STATS", line 20945 ORA-06512: 在 "SYS.DBMS_STATS", line 21498 ORA-06512: 在 line 3 SQL> SQL> select table_name, num_rows, last_analyzed 2 from dba_tab_statistics 3 where last_analyzed is not null 4 and table_name = 'X$KSQRS' 5 / TABLE_NAME NUM_ROWS LAST_ANALYZED ------------------------------ ---------- ------------- X$KSQRS 1312 2014/12/30 22 SQL> SQL> begin 2 dbms_stats.delete_table_stats('SYS','X$KSQRS'); 3 end; 4 / PL/SQL procedure successfully completed SQL> SQL> select table_name, num_rows, last_analyzed 2 from dba_tab_statistics 3 where last_analyzed is not null 4 and table_name = 'X$KSQRS' 5 / TABLE_NAME NUM_ROWS LAST_ANALYZED ------------------------------ ---------- ------------- SQL> SQL> begin 2 dbms_stats.gather_table_stats('SYS','X$KSQRS'); 3 end; 4 / PL/SQL procedure successfully completed SQL> SQL> select table_name, num_rows, last_analyzed 2 from dba_tab_statistics 3 where last_analyzed is not null 4 and table_name = 'X$KSQRS' 5 / TABLE_NAME NUM_ROWS LAST_ANALYZED ------------------------------ ---------- ------------- X$KSQRS 1312 2014/12/30 22
注:
gather_dictionary_stats--> 针对table$这样的表,存在于物理数据库中~
gather_fixed_objects_stats--> 针对x$table这样的内存表,不存在物理数据库中,只在内存中存在,动态试图的基表
gather_system_stats-->针cpu/io
固定对象统计信息
自动统计信息收集job不会收集固定对象的统计统计信息.当优化统计信息丢失时不象其它的数据库表对于sql语句中调用X$表是不能自动使用动态抽样的.如果它们的统计信息丢失优化器会使用预先定义的缺省统计信息.这些缺省的统计信息可能没有代表性且可能导致选择次优的执行计划,在系统中可能会导致严重的性能问题.如果是这个原因造成性能问题强烈建议你手动收集固定对象的统计信息.可以使用dbms_stats.gather_fixed_objects_stats过程来收集固定对象的统计信息.因为在系统如果存在一个有代表性的工作负载收集x$这些固定对象的统计信息是很重要的.在大型系统中由于收集固定对象统计信息需要额外的资源所以对固定对象收集统计信息不总是可行.如果不能在负载高峰期间收集固定对象的统计信息那么应该在系统负载降低之后对三种关键类型的固定对象表收集统计信息:
structural data--比如controlfile contents
Session based data - 比如 v$session, v$access
Workload data -比如 v$sql, v$sql_plan
建议当主数据库或应用程序升级后,实现新的模块或者改变数据库的配置后重新收集固定对象统计信息.例如,如果增加SGA的大小包含缓冲区缓存和共享池信息的x$表会显著的发生改变,比如v$buffer_pool或v$shared_pool_advice视图使用的x$表.系统统计信息系统统计信息能让优化器通过使用执行这个语句相关的实际系统硬件信息,比如,cpu速度和IO性能,来在执行计划中对每一个步骤获得更精确的成本值.系统统计信息缺省情况下是启用的,它使用缺省值自动初始化,这些值对于大多数系统来说是有代表性的.