SQL优化中的Statistic更新问题

背景

最近小伙伴们在开发过程中遇到一个有趣的问题:原本很快的SQL在LEFT JOIN了两张表,并增加了一个WHERE id IN list的查询条件之后,查询性能急剧下降导致性能问题。

分析执行计划后,一直没有办法解释为什么新增了一个查询条件之后会导致性能下降。后来经过DBA帮助后发现,在更新了SQL Server的Statistic信息后,问题解决。以前一直没有怎么关注过statistics这个,觉得问题很有意思,于是记录下来作为备忘。

解决过程

因为此次修改仅仅是在之前的存储过程的基础上,增加了两个表的LEFT JOIN和WHERE语句中增加了一个IN的条件。经过排查,基本排除了索引之类的问题,分析执行计划后发现有个表异常查询次数异常的多。

但是问题在于,此次新增的条件和该问题表并无关系,所以无法解释为什么带上新的条件和不带新的条件性能差距达到了几十倍的差距。问题SQL大致如下:

//  这里的table2的join子查询本身就不太好,因此最好使用临时表来替代
//  而且table2也是执行计划反应出来的主要问题点
SELECT * 
FROM table1 as t1
  LEFT JOIN (SELECT * from table2 group by name) as t2 on t1.id = t2.id
  LEFT JOIN table3 as t3 ON t1.id = t3.id
WHERE t.valid>0 AND t1.id in (1,2,3,4,5)

后来经过DBA的帮助,手动更新了SQL Server的Statistics信息后,发现不仅之前的查询性能得到了改善,而且性能问题也消失了。结合相关资料分析后,认为可能是因为Statistic信息不准确导致了执行计划不准确,从而导致的性能问题。

后续思考

在以前的SQL调优过程中,最多的还是关注了在B+树上的索引情况,来进一步优化SQL,但是对于实际上数据库本身所维护的statistic(这些信息没怎么关注过。其实,这些信息本身不仅仅能够完成本身的工作,还能给我们是否有必要建立索引,以及索引的有效性等提供很大的帮助。

例如在SQL Server中可以通过执行如下命令,可以获取到statistics的相关信息。

DBCC SHOW_STATISTICS(<table_name> , <index_name>)
  • 首先我们可以看到statistic相关的一些更新时间和采样数量之类的信息。这里最重要的一个个人觉得就是统计信息的更新时间了。虽然在数据库中(不同数据库不同版本间的策略是不一样的,比如mysql5.5和5.6之间就有差异)统计信息的更新一般默认是由数据库自动创建和维护的,但是鉴于性能等因素的考量,这个更新并非是及时的。因此有的DBA会定期会手动(脚本也算手动的一种吧)去触发它的更新从而维持数据的性能。这也是本次问题造成的原因之一吧。
    其次就是采样之类的数据表明了统计的准确性,这里可以看到由于数据量不多所以进行的全表采样,所以准确性是比较高的。


    statistic的更新时间、采样数量等信息
  • 其次第二张表主要可以看到density(简单的可以认为是数据的重复性)这一类给我们的索引的必要性提供了很好的依据,如果这个值比较小其实索引的意义相对就不大。原因也很简单,如果大部分数据都是重复的,那么其实索引的效果肯定不会很好,比如性别可能就不是一个很好的索引列,因为无论如何取值就只有两个(当然这里是为了简单,其实性别也可以有很多个)。
    p.s. 但是凡事无绝对,虽然普通的索引来说性别不是个好的索引列,但是bitmap索引来说,情况就不一样了。


    索引的唯一性等分析
  • 最后一张表中,通常也称为Histogram,主要描述了数据的分布情况。


    数据的分布情况 Histogram

结语

虽然以往的sql优化中主要还是以sql语句本身的优化为主,但是更好的了解数据库本身的执行原理,能够帮助我们更好的做好优化和问题排查,从而实现高性能的服务。
在优化sql语句本身,分析执行计划一筹莫展的时候,更新更新statistics,然后在结合统计信息分析分析也是一个好办法。

参考资料

SQL语句调优 - 统计信息的含义与作用及维护计算
SQL Server 统计信息维护策略的选择
MySQL中Cardinality值的介绍
MySQL 5.6为什么关闭元数据统计信息自动更新&统计信息收集源代码探索

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

推荐阅读更多精彩内容