SQL优化案例——统计信息让SQL飞起

涉及知识点:
1.NL连接的优化
2.收集统计信息方式
3.查看执行计划的6种方式及其优缺点
4.SQL执行计划的执行顺序查看方法

问题现象:在进行压力测试登录的时候,发现有大量查询消息的操作。SQL卡顿时间长达1分钟。


image.png

具体SQL如下:
select
*
from
( select
row_. * ,
rownum rownum_
from
( select
。。COLORKEY ,
RESENDTIMES
from
sm_msg_content
where
receiver = '1001WW1000000000054U'
and msgtype = 'nc'
and destination = 'inbox'
and msgsourcetype in (
select
typecode
from
sm_msg_msgtype
where
displocation = 'worklist'
)
and (
pk_detail in (
select
nt.pk_checkflow
from
pub_workflownote nt
where
nt.PK_BILLTYPE in (
select
bt.pk_billtypecode
from
bd_billtype bt
where
(
bt.pk_billtypecode in (
select
acbt.billtype
from
wfm_acceptnctype acbt
where
acbt.ext4 = 'ALLOW_MSG'
oracbt.ext4 is null
)
andbt.parentbilltype = '~'
)
or (
bt.parentbilltype < > '~'
andbt.parentbilltype in (
select
accbt.billtype
from
wfm_acceptnctype accbt
where
accbt.ext4 = 'ALLOW_MSG'
oraccbt.ext4 is null
)
)
)
)
or pk_detail is null
)
and not exists (
select
PK_CHECKFLOW
from
pub_workflownote nt
where
nt.ACTIONTYPE ='MAKEBILL'
and nt.PK_CHECKFLOW =PK_DETAIL
)
order by
sendtime desc ) row_
where
rownum < = 100
)
where
rownum_ > 0
问题分析:
针对问题现象,可以得到初步结论。该SQL返回结果集很少,SQL解析的时间长达50秒左右。所以应该是可以优化到2s以内。
由于可以执行出SQL结果,并且不需要查看物理读和逻辑读。
因此,通过statistics_level=all的方式查看执行计划。
查看执行顺序的时候,我们可以将执行计划拷贝到TXT文本里,用光标大法进行查询。
找到缩进的最深的第一个语句,就是SQL执行的第一条语句,然后按照从上到下,逐步向外合并的顺序进行阅读。


| Id | Operation | Name |Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem |

| 0 | SELECT STATEMENT | | 1 | | 100 |00:00:49.67 | 952K| | | |
|* 1 | VIEW | | 1 | 100 | 100 |00:00:49.67 | 952K| | | |
|* 2 | COUNT STOPKEY | | 1 | | 100 |00:00:49.67 | 952K| | | |
| 3 | VIEW | | 1 | 199 | 100 |00:00:49.67 | 952K| | | |
|* 4 | SORT ORDER BY STOPKEY | | 1 | 199 | 100 |00:00:49.67 | 952K| 160K| 160K| 142K (0)|
|* 5 | FILTER | | 1 | | 14017 |00:00:49.34 | 952K| | | |
|* 6 | HASH JOIN RIGHT ANTI | | 1 | 3933 | 14487 |00:00:01.63 | 41121 | 2616K| 2616K| 161K (0)|
|* 7 | TABLE ACCESS FULL |PUB_WORKFLOWNOTE | 1 | 1| 0 |00:00:00.67 | 26438 | | | |
| 8 | NESTED LOOPS | | 1 | 3934 | 14487 |00:00:00.85 | 14683 | | | |
| 9 | NESTED LOOPS | | 1 | 3934 | 14487 |00:00:00.19 | 203 | | | |
| 10 | SORT UNIQUE | | 1 | 11 | 11 |00:00:00.01 | 6 | 2048 | 2048 | 2048 (0)|
|* 11 | TABLE ACCESS FULL | SM_MSG_MSGTYPE | 1 | 11 | 11 |00:00:00.01 | 6 | | | |
|* 12 | INDEX RANGE SCAN | I_RCVMSGTYPE | 11 | 183 | 14487 |00:00:00.18 | 197 | | | |
|* 13 | TABLE ACCESSBY INDEX ROWID| SM_MSG_CONTENT | 14487 | 1311 | 14487 |00:00:00.61 | 14480 | | | |
|* 14 | FILTER | | 14487 | | 14017 |00:00:47.06 | 911K| | | |
| 15 | NESTED LOOPS | | 14487 | 1| 14017 |00:00:46.80 | 911K| | | |
| 16 | TABLE ACCESS BY INDEX ROWID| PUB_WORKFLOWNOTE | 14487 | 1 | 14017 |00:00:02.25 | 56851 | | | |
|* 17 | INDEX UNIQUE SCAN | PK_PUB_WORKFLOWNOT| 14487 | 1 | 14017 |00:00:01.72| 42834 | | | |
|* 18 | TABLE ACCESSFULL | BD_BILLTYPE | 14017 | 1 | 14017 |00:00:44.46 | 854K| | | |
|* 19 | TABLE ACCESS FULL |WFM_ACCEPTNCTYPE | 1 | 1| 1 |00:00:00.01 | 2 | | | |
|* 20 | TABLE ACCESS FULL |WFM_ACCEPTNCTYPE | 0 | 1| 0 |00:00:00.01 | 0 | | | |


可以明显发现,时间在第| 15 | NESTED LOOPS | | 14487 | 1 | 14017 |00:00:46.80 | 911K| | | |有了突然的上涨。
该处属于NL连接。而细看我们可以发现,驱动表为PK_PUB_WORKFLOWNOT 而 被驱动表为WFM_ACCEPTNCTYPE 。
驱动表为1W4的行数,而被驱动表为1行。由于NL的机制,在两表进行合并操作的时候会进行被驱动表次数的循环。
这里显然是驱动表的顺序错误,变成了大表驱动小表。而这样情况的发生,很多时候是由于统计信息不准确导致。
这也就是为什么采用statistics_level=all的方式进行执行计划的查看。该方法是唯一可以看到预估行数E-ROWS和实际行数A-ROWs的方式。
这里我们看到,PK_PUB_WORKFLOWNOT 预估值为1,而实际值为14017。显然是这里的预估出现了问题。
问题解决:
知道是统计信息不准确导致的问题,就比较好解决了。这里注意,需要使用oracle 11g推荐的方式来收集统计信息。
exec dbms_stats.gather_table_stats(‘nc_user','PUB_WORKFLOWNOTE',CASCADE=>true,method_opt=>'for all indexed columns');
同时,由于NL的机制比较关注关联列的效率问题,而第18
18 - filter("NT"."PK_BILLTYPE"="BT"."PK_BILLTYPECODE")走了filter。而这里是可以通过走索引来避免全表扫描的。于是在这两个关联列上都添加了索引。
最终,该SQL的执行时间从50秒变为了1秒以内,达到了优化的效果。使得压力测试顺利进行。


| Id | Operation | Name |Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem |

| 0 | SELECT STATEMENT | | 1 | | 100 |00:00:00.58 | 181K| | | |
|* 1 | VIEW | | 1 | 1| 100 |00:00:00.58 | 181K| | | |
|* 2 | COUNT STOPKEY | | 1 | | 100 |00:00:00.58 | 181K| | | |
| 3 | VIEW | | 1 | 1| 100 |00:00:00.58 | 181K| | | |
|* 4 | SORT ORDER BY STOPKEY | | 1 | 1| 100 |00:00:00.58 | 181K| 142K| 142K| 126K (0)|
|* 5 | FILTER | | 1 | | 17988 |00:00:00.55 | 181K| | | |
| 6 | NESTED LOOPS ANTI | | 1 | 4| 18458 |00:00:00.33 | 73030 | | | |
|* 7 | HASH JOIN | | 1 | 376 | 18458 |00:00:00.14 | 18589 | 1645K| 1645K| 1298K (0)|
| 8 | SORT UNIQUE | | 1 | 11 | 11|00:00:00.01 | 6 | 2048 | 2048 | 2048 (0)|
|* 9 | TABLE ACCESS FULL | SM_MSG_MSGTYPE | 1 | 11 | 11|00:00:00.01 | 6 | | | |
|* 10 | TABLE ACCESSBY INDEX ROWID| SM_MSG_CONTENT | 1 | 1377 | 18458 |00:00:00.12 | 18583 | | | |
|* 11 | INDEX RANGE SCAN |I_RCV_ISREAD | 1 | 548 | 18459 |00:00:00.01 | 133 | | | |
|* 12 | TABLE ACCESS BYINDEX ROWID | PUB_WORKFLOWNOTE | 18458 | 6048 | 0 |00:00:00.17| 54441 | | | |
|* 13 | INDEX UNIQUESCAN | PK_PUB_WORKFLOWNOT | 18458 | 1| 17988 |00:00:00.10 | 36453 | | | |
|* 14 | FILTER | | 18458 | | 17988 |00:00:00.18 | 108K| | | |
| 15 | NESTED LOOPS | | 18458 | 2| 17988 |00:00:00.17 | 108K| | | |
| 16 | TABLE ACCESS BY INDEX ROWID| PUB_WORKFLOWNOTE | 18458| 1 | 17988 |00:00:00.08 | 72722 | | | |
|* 17 | INDEX UNIQUE SCAN |PK_PUB_WORKFLOWNOT | 18458 | 1 | 17988 |00:00:00.06 | 54734 | | | |
| 18 | TABLE ACCESS BY INDEX ROWID| BD_BILLTYPE | 17988 | 2| 17988 |00:00:00.07 | 35981 | | | |
|* 19 | INDEX RANGE SCAN |PK_BILLTYPEIDCODE | 17988 | 2| 17988 |00:00:00.04 | 17993 | | | |
|* 20 | TABLE ACCESS FULL | WFM_ACCEPTNCTYPE | 1 | 1 | 1 |00:00:00.01 | 2 | | | |

|* 21 | TABLE ACCESS FULL | WFM_ACCEPTNCTYPE | 0 | 1 | 0 |00:00:00.01 | 0 | | | |

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容