Oracle执行计划突变诊断之统计信息收集问题

前端之家收集整理的这篇文章主要介绍了Oracle执行计划突变诊断之统计信息收集问题前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

Oracle执行计划突变诊断之统计信息收集问题

1.情形描述

DB version11.2.0.4

WITHsql1AS
(SELECTLAC,CI,TO_NUMBER(C.LONGITUDE)LONGITUDE,TO_NUMBER(C.LATITUDE)LATITUDE
FROMMB_SYS_CELL_INFOC
WHEREC.CONTY_NAME='道孚县'),sql2AS
(SELECTDISTINCTIMSI,LAC,CI
FROMMB_BSS_USER_LOCATION
WHEREHOURIN(16,15,14,13)
ANDTIME=TO_TIMESTAMP('20170621','YYYYMMDD')),sql3AS
(SELECTC.LONGITUDE,C.LATITUDE,WM_CONCAT(C.SITE_NAME)SITE_NAME
FROM(SELECTDISTINCTTO_NUMBER(A.LONGITUDE)LONGITUDE,TO_NUMBER(A.LATITUDE)LATITUDE,A.SITE_NAME
FROMMB_SYS_CELL_INFOA
WHEREA.CONTY_NAME='道孚县')C
GROUPBYC.LONGITUDE,C.LATITUDE)
SELECTsql1.LONGITUDELNG,sql1.LATITUDELAT,COUNT(DISTINCTsql2.IMSI)COUNT,TO_CHAR(sql3.SITE_NAME)SITE_NAME
FROMsql1,sql2,sql3
WHEREsql2.LAC=sql1.LACANDsql2.CI=sql1.CIANDsql1.LONGITUDE=sql3.LONGITUDEANDsql1.LATITUDE=sql3.LATITUDEGROUPBYsql1.LONGITUDE,sql1.LATITUDE,TO_CHAR(sql3.SITE_NAME)ORDERBYCOUNTDESC;

最初的报错,临时表空间不足,

上述sql为开发应用sql,当执行上述sql时,通过以下命令监控临时表空间。

使用 V$TEMPSEG_USAGE 可监视空间使用情况和分配情况:

SELECTsession_num,username,segtype,blocks,tablespace
FROMV$TEMPSEG_USAGE;


使用 V$SORT_SEGMENT 可确定空间真实使用率百分比:

SELECT(s.tot_used_blocks/f.total_blocks)*100aspctused
FROM(SELECTSUM(used_blocks)tot_used_blocks
FROMV$SORT_SEGMENT
WHEREtablespace_name='TEMP')s,(SELECTSUM(blocks)total_blocks
FROMDBA_TEMP_FILES
WHEREtablespace_name='TEMP')f;


发现一条sql能把64G的临时表空间exhaust,查看对应之行划,发现merge join cartesian

这部分无法回现了。

补:数据库为新建数据库,大量基础表为其他库同步过来的,应用表为实时入库的表(MB_BSS_USER_LOCATION),且很清晰记得当时开启了auto maintaining任务。

查看统计信息任务是否开启:

selectclient_name,statusfromdba_autotask_client;


2.处理步骤

1

2

2.1查看大表的统计信息

selecttable_name,partition_name,last_analyzed,STATTYPE_LOCKEDfromuser_tab_statistics
wheretable_name='MB_BSS_USER_LOCATION';
STATTYPE_LOCKEDVARCHAR2(5)Typeofstatisticslock:
■DATA
■CACHE
■ALL

last_analyzed,STATTYPE_LOCKED分析得来,该表并没有收集过统计信息,且统计信息被锁。

查看库中其他表的统计信息。

selectcount(distincttable_name)fromuser_tab_statisticswherestattype_lockedisnotnull;

发现还有98张表统计信息被锁定。

2.2强制收集对应表统计信息

sql>execdbms_stats.gather_table_stats(ownname=>'GZ_SAFETY',tabname=>'MB_BSS_USER_LOCATION',force=>TRUE);
PL/sqlproceduresuccessfullycompleted

再次查看执行计划。

--------------------------------------------------------------------------------------------------------
|Id|Operation|Name|Rows|Bytes|Cost|Time|
--------------------------------------------------------------------------------------------------------
|0|SELECTSTATEMENT||16|32608|41343|00:08:17|
|1|SORTORDERBY||16|32608|41343|00:08:17|
|2|HASHGROUPBY||16|32608|41343|00:08:17|
|3|VIEW|VM_NWVW_1|16|32608|41341|00:08:17|
|4|HASHGROUPBY||16|33744|41341|00:08:17|
|*5|HASHJOIN||16|33744|41340|00:08:17|
|*6|HASHJOIN||1|2069|138|00:00:02|
|*7|TABLEACCESSFULL|MB_SYS_CELL_INFO|448|18368|68|00:00:01|
|8|VIEW||448|908544|70|00:00:01|
|9|SORTGROUPBY||448|26880|70|00:00:01|
|10|VIEW||448|26880|69|00:00:01|
|11|HASHUNIQUE||448|22400|69|00:00:01|
|*12|TABLEACCESSFULL|MB_SYS_CELL_INFO|448|22400|68|00:00:01|
|13|PARTITIONRANGESINGLE||3237748|129509920|41192|00:08:15|
|14|PARTITIONLISTINLIST||3237748|129509920|41192|00:08:15|
|*15|TABLEACCESSFULL|MB_BSS_USER_LOCATION|3237748|129509920|41192|00:08:15|

发现笛卡尔积merge join消失,执行计划正常。

2.3查看其他表的统计信息情况(分区表)

selecttable_name,stattype_locked
fromuser_tab_statisticswherestattype_lockedisnotnullandobject_typein('PARTITION','SUBPARTITION');

因为是测试环境,暂不关注这些表,先把MB_BSS_USER_LOCATION表的统计信息锁定打开。

sql>execdbms_stats.unlock_table_stats(ownname=>'GZ_SAFETY',tabname=>'MB_BSS_USER_LOCATION');
PL/sqlproceduresuccessfullycompleted,打开后可通过user_tab_statistics.stattype_locked查看。
补:打开对应用户统计信息。
DBMS_STATS.UNLOCK_schema_STATS(user);

猜你在找的Oracle相关文章