某日同事丢给我一个看上去复杂的查询(实际就涉及两张表,套来套去)说只是换了日期条件,但一个查询5秒出数据,一个根本查不出来。现在整理下解决过程,及涉及的知识点。

  若有不正之处,请多多谅解并欢迎批评指正,不甚感激。

  请尊重作者劳动成果,转载请标明原文链接:

  http://www.cnblogs.com/zzry/p/5857751.html

一.问题描述


环境:sqlserver 2008r2

现象:

查询涉及到两张表

ODS_TABLE_A     每日数据700万现在总计60多亿。   已建立索引+分区

MID_TABLE_B      每日数据20万 总计3000万。         已建立索引未分区

当etldate为 '2016-08-12' 及以前的时间时,本查询5秒出数据,

当etldate为 '2016-08-16' 及以后的时间时,本查询出不来数据。

贴上问题sql:做过数据字段处理,针对本篇主题注意点放在查询因为日期的选择不同导致查询时间变的超级慢,而不是改变sql写法比如用临时表,强制索引上。

----------《代码开始》

select 

COUNT(distinct(case when COL_USERID3 is null then COL_USERID6 end)) as 'aa',

COUNT(distinct(case when COL_USERID3 is null and COL_USERID7 is not null then COL_USERID6 end)) as 'bb',

COUNT(distinct(case when COL_USERID3 is not null then COL_USERID6 end)) as 'cc',

COUNT(distinct(case when COL_USERID3 is not null and COL_USERID7 is not null then COL_USERID6 end)) as 'dd',

SUM(case when COL_USERID3 IS not null then ee end) as 'ee'

from

(

    select c.COL_USERID3,c.ee,g.COL_USERID6

    from

    (

        select  b.COL_USERID2 as COL_USERID3,COUNT(b.COL_USERID2) as ee

        from

        (

            select COL_USERID as COL_USERID1,min(EventTime) as time1

                from ODS_TABLE_A    

                where  EtlDate = '2016-08-12'

                    and colid LIKE 'heihei%'

                    group by COL_USERID

        )as a
join
(
select COL_USERID as COL_USERID2,eventtime as time2 from ODS_TABLE_A where EtlDate = '2016-08-12' and ItemId = '' and colid like 'haha-%' and colid not like 'haha-skill%' and colid not like 'haha-fine%' )as b on a.COL_USERID1 = b.COL_USERID2 and a.time1 > b.time2 group by b.COL_USERID2 )as c
right join
( select DISTINCT d.COL_USERID4 as COL_USERID6 from (
select distinct COL_USERID as COL_USERID4 from MID_TABLE_B where etldate = '2016-08-12' )as d join (
select COL_USERID AS COL_USERID5 from ODS_TABLE_A where EtlDate = '2016-08-12' and colid LIKE 'heihei%' )as f on d.COL_USERID4 = f.COL_USERID5 )as g on c.COL_USERID3 = g.COL_USERID6 )as i left join
(
select COL_USERID as COL_USERID7 from MID_TABLE_B where EtlDate = '2016-08-12' and IsTodayPay = '' )as h on i.COL_USERID6 = h.COL_USERID7

----------《代码结束》

二。解决过程


 1.先看了下上述代码的执行计划如下图初看上去需要用索引的地方都用到了。应该没啥大问题。

可能你注意到系统提示的缺少索引信息,加上去一样效果,不能解决‘2016-08-16’ 查询慢的问题。

 

 2.在修改下日期 ,就是把 【所有】  etldate=‘2016-08-12’  的改成  etldate=‘2016-08-16’
看下执行计划:
对不起跑了半个小时没出来,查看估计的执行执行和上面的图类似。
减少涉及到数据集的量 加top 1 我再看执行计划:
不贴图了 结果就是比上面的图少了个 【并行度
 
初步以为是优化器因为估计行数等不准的原因没选择并行度,赶紧找代码让它强行这样走。
找到一篇宋大师的:强制SQL Server执行计划使用并行提升在复杂查询语句下的性能
http://www.cnblogs.com/CareySon/p/3851113.html
 
 二话不说加关键字
OPTION(querytraceon 8649)
 
可是应用到实际发现查询效率无任何改善,久久不出结果。后来问宋大师(感谢宋大神)。他说有些操作是没法并行的,更新统计信息试试先。
一击命中!一击命中!一击命中!
执行如下代码:
update STATISTICS ODS_TABLE_A  --(把ODS_TABLE_A  这个大表统计信息更新)
 
默认情况下,查询优化器已根据需要更新统计信息以改进查询计划;但在某些情况下,你可以通过使用 UPDATE STATISTICS 或存储过程 sp_updatestats 来比默认更新更频繁地更新统计信息,提高查询性能。针对文中此种情况新插入的数据没统计信息,大表自动更新统计信息触发自动更新机制频率不够,最好定期更新。
关于update STATISTICS 就不累述了 :给出相关技术贴连接
更新统计相关知识点传送门https://msdn.microsoft.com/zh-cn/library/ms187348.aspx
至此问题解决。

三。总结


  对于大表新插入的数据没及时更新统计信息,导致出现上面文中的现象,一个日期导致查询效率天壤之别的分水岭(查12号前5秒出数据,查12号后死活不出来。)

解决办法是大表自动更新统计信息触发自动更新机制频率不够,定期更新。

SQL调优--记一次表统计信息未及时更新导致查询超级慢的更多相关文章

  1. 数据库性能调优之始: analyze统计信息

    摘要:本文简单介绍一下什么是统计信息.统计信息记录了什么.为什么要收集统计信息.怎么收集统计信息以及什么时候收集统计信息. 1 WHY:为什么需要统计信息 1.1 query执行流程 下图描述了Gau ...

  2. 记一次SQL调优/优化(SQL tuning)——性能大幅提升千倍以上

    好久不写东西了,一直忙于各种杂事儿,恰巧昨天有个用户研发问到我一个SQL调优的问题,说性能太差,希望我能给调优下,最近有些懒,可能和最近太忙有关系,本来打算问问现在的情况,如果差不多就不调了,那哥们儿 ...

  3. SQL调优常用方法

    在使用DBMS时经常对系统的性能有非常高的要求:不能占用过多的系统内存和 CPU资源.要尽可能快的完成的数据库操作.要有尽可能高的系统吞吐量.如果系统开发出来不能满足要求的所有性能指标,则必须对系统进 ...

  4. SQL调优

    # 问题的提出 在应用系统开发初期,由于开发数据库数据比较少,对于查询SQL语句,复杂视图的的编写等体会不出SQL语句各种写法的性能优劣,但是如果将应用 系统提交实际应用后,随着数据库中数据的增加,系 ...

  5. Oracle SQL 调优健康检查脚本

    Oracle SQL 调优健康检查脚本 我们关注数据库系统的性能,进行数据库调优的主要工作就是进行SQL的优化.良好的数据架构设计.配合应用系统中间件和写一手漂亮的SQL,是未来系统上线后不出现致命性 ...

  6. Oracle中SQL调优(SQL TUNING)之最权威获取SQL执行计划大全

    该文档为根据相关资料整理.总结而成,主要讲解Oracle数据库中,获取SQL语句执行计划的最权威.最正确的方法.步骤,此外,还详细说明了每种方法中可选项的意义及使用方法,以方便大家和自己日常工作中查阅 ...

  7. 《高性能SQL调优精要与案例解析》一书谈SQL调优(SQL TUNING或SQL优化)学习

    <高性能SQL调优精要与案例解析>一书上市发售以来,很多热心读者就该书内容及一些具体问题提出了疑问,因读者众多外加本人日常工作的繁忙 ,在这里就SQL调优学习进行讨论并对热点问题统一作答. ...

  8. Oracle SQL调优之分区表

    目录 一.分区表简介 二.分区表优势 三.分区表分类 3.1 范围分区 3.2 列表分区 3.3 散列分区 3.4 组合分区 四.分区相关操作 五.分区相关查询 附录:分区表索引失效的操作 一.分区表 ...

  9. /*+parallel(t,4)*/在SQL调优中的重要作用!

    谈谈HINT /*+parallel(t,4)*/在SQL调优中的重要作用! /*+parallel(t,4)*/在大表查询等操作中能够起到良好的效果,基于并行查询要启动并行进程.分配任务与系统资源. ...

随机推荐

  1. 《敏捷软件开发:原则、模式与实践(C#版)》源代码下载

    Agile Software Development: Principles, Patterns and Practice (C# Edition)  Source Code 这本书的经典性无需多言 ...

  2. 【解决】Git failed with a fatal error. Authentication failed for ‘http://......’

    今天在visual studio中运行项目,打算pull最新的代码的时候,报错: Git failed with a fatal error. Authentication failed for ‘h ...

  3. js识别中英文字符的字节长度并进行裁切

    //调用方法,传入字符串和需要返回的字节长度即可function cutstr(str,len){ var str_length = 0; var str_len = 0; str_cut = new ...

  4. Ubuntu 16.04 远程登入root 用户

    安装 open ssh: sudo apt-get install openssh-server   修改 root 密码 sudo passwd root   以其他账户登录,通过 sudo nan ...

  5. Android 桌面悬浮窗效果实现,仿360手机卫士悬浮窗效果

    首先是一个小的悬浮窗显示的是当前使用了百分之多少的内存,点击一下小悬浮窗,就会弹出一个大的悬浮窗,可以一键加速.好,我们现在就来模拟实现一下类似的效果. 先谈一下基本的实现原理,这种桌面悬浮窗的效果很 ...

  6. Android——dpi相关知识总结

    1.术语和概念 术语 说明 备注 Screen size(屏幕尺寸) 指的是手机实际的物理尺寸,比如常用的2.8英寸,3.2英寸,3.5英寸,3.7英寸...... nexus4手机是4.7英寸 As ...

  7. javascript字符串格式化string.format

    String.prototype.format = function () { var values = arguments; return this.replace(/\{(\d+)\}/g, fu ...

  8. mysql服务器系统优化

    1.选择合适的IO调度 对于mysql的系统,如果是SSD,那么应该使用NOOP调度算法,如果是磁盘,就应该使用Deadline调度算法.默认是CFQ echo dealine > /sys/b ...

  9. hihoCoder hiho一下 第一周 #1032 : 最长回文子串 (Manacher)

    题意:给一个字符串,求最长回文子串的长度. 思路: (1)暴力穷举.O(n^3) -----绝对不行. 穷举所有可能的出现子串O(n^2),再判断是否回文O(n).就是O(n*n*n)了. (2)记录 ...

  10. IDA逆向:结构体的逆向

    源代码: int _tmain(int argc, _TCHAR* argv[]) { struct v1 { int a; short b; char c; int d; double e; }; ...