SQL性能个人实践心得【持续更新】


20161111

首先祝大家光棍节快乐!

接下来,继续分享我的SQL性能优化小的心得。

这次是做的一个统计查询页面。

简化话表结构如下:

A表主表数据8万+,主要字段:主键、日期、部门、其他非统计列

B表明细表数据100万+,主要字段:外键ID、明细类型、明细值(最终要求sum)

C表另一个明细表数据2000+,主要字段:外键ID、值1、值2(最终要求sum,说实现数据小,对整体影响最小)

另外主表有几个关键查询字段:日期、部门

查询统计要实现的就是:针对每一条主表数据,查询出每个明细类型的值的sum(针对B表)、值1、值2的sum(针对C表)


1)直接子查询,肯定行不通,时间在1分钟以上

2)将B表、C表先GROUP BY、SUM分组汇总作为临时表,再与主表进行子查询

由于主表、子表数据量都不小,效果也不是很好,在30秒左右

3)经过沟通,决定页面默认筛选:筛选当前年数据

这个时候,又涉及到一个问题,主表可能是要做筛选,那么明细表分组汇总要不要做筛选?

答案是要!这个时候查询当前年数据,5秒左右

4)我们还有个部门查询,在日期的基础上,我增加了部门筛选,我靠,结果页面直接超时,查询分析器也30秒+

什么鬼??

只能试了到底是哪儿搞慢了。

a、尝试调整with  与 into 表 #表,结果没啥效果(貌似数据多的时候,#表好点)

b、尝试去掉对临时表的子查询,速度就上去了,那么应该和临时表有关系

c、尝试去掉明细表分组汇总的部门查询sql,还是挺慢,看来问题不在这

尝试去掉子查询明细表的部门查询sql,奇迹出现,速度反而更快!

那么指定就是主表针对部门的查询需要优化下了

加上主表针对部门的索引,3秒开!

欧耶,搞定!


结论:

1、数据量大的情况下,做统计数据的临时表,也要和主表一样增加筛选(数据量越大时间会越长)

2、有时候,或者应该说就是:主表查询+子查询,二者都会影响整体查询速度,应该是相乘的关系。

可能你主表数据不大,但是因为查询主表较与子查询慢,还是会影响整体查询效率

在给主表做了索引后,速度明显上去了(甚至于,由于明细表只是分组汇总查询,都需要增加索引)重点显然在数据相对较少的主表


2016-09-27

今天这个是无意发现的。SQL大概如下

SELECT TOP  10  字段A、B、C

FROM TABLE1 T1

JOIN TABLE 2 T2 ON T1.MID=T2.MID

直接这样执行,非常快不到1秒,毕竟就是从一堆数据中读取10条


接下来,增加ORDER BY T1.CODE1,T2.CODE2

速度立马下来了,3-4秒的时间,这样不行啊

马上想到索引处理下?

要不先试试ORDER BY T2.CODE1,T2.CODE2            (T2也有T1的CODE1字段,主要字段做冗余的)

想想什么效果啊,继续秒开!

个人猜测,排序的时候从一个表进行,效率会很好的缘故吧。

反正后续还会这么用的!

mark!



2016-08-26

就是今天,写了个SQL用来查询未进行历史数据迁移的数据,大概SQL如下

SELECT COL1,CLO2
FROM TABLE1 T1
JOIN TABLE2 T2 ON T1.C1=T2.C1
JOIN TABLE3 T3 ON T2.C2=T3.C2
WHERE T1.C3 IS NULL OR T1.C3='测试'
AND NOT EXISTS(SELECT 1 FROM TABLE4 WHERE C4=T1.C5)

执行的时候,很慢很慢,竟然服务器CPU 100%,内存也飙上去了!

于是去掉了EXISTS子查询,2-5秒搞定,但是一旦加上EXISTS就慢的要死!

但是这问题得破,于是各种试

然后有了个发现,将T1.C3 IS NULL OR T1.C3='测试'
改了下:ISNULL(T1.C3,'测试')='测试'


再次执行,奇迹在此刻出现,不要1秒,就出结果了!

问题的关键不是EXISTS,而是ORISNULL ,OR的罪更重


看来还是使用人家系统自带的功能比较高效!

欧耶,还是多试才知道啊!不能被困难吓倒!!


其他的就是诸如:使用UNION不使用IN

使用EXISTS不使用IN

这些。


后续有新的实践,继续分享。。。


你可能感兴趣的:(SQL,Server,SQL,性能,ISNULL)