(function() { var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })();

Tunning tunning

Categories: 未分类
Tags: No Tags
Comments: 1 Comment
Published on: 2009 年 06 月 03 日

之前无论做项目还是POC,总是要尽自己所能将产品的性能发挥到最大,这次做得POC让我非常的郁闷,客户的条条框框搞得我非常郁闷,不但要优化还要在很多限制上进行优化,虽然产品功能和性能无法正常发挥,但是还要不断努力,毕竟这种数据量和服务器还是很少能够遇到。

客户测试案例中有一些还是比较有特点,随便拿来说说。

删除重复数据

有一张用于出报表的临时数据表,4个列,a char,b char ,c datetime, d char,group by a,b ,保留最大的c,d. 类似与删除重复数据的场景。客户提供的实例SQL使用了一个临时表,然后通过max(C),max(d)的方法将最大值放到临时表中,然后在原表中删除。这种做法的日志开销、logcial read都会很大。

比较好的处理方式是将最大值插入的其他表中,然后删除源表,将新表重新命名,另外还要注意逻辑,删除最小值并不等于保留最大值,因为最大值可能会出现重复,也就是相同的最大值其实可能有多条。这个过程可以使用CTE和DENSE_RANK,目前我看到这个是最快的方法

with d as

(

select a,b,c,d

from t where desnese_rank() over(partition by a,b order c desc,d desc)=1

)

inser into t2

select a,b,c,d from d

注意多线程并行执行计划

这次测试中还遇到一个问题就是clustered index和排序。

以前总是认为如果一个表上定义了clustered index在查询中如果没有特定使用order by,则返回的记录应该按照clustered index的排序返回。这种想法不是100%可靠,虽然你看到的多数情况是这样。但是如果这个表有分区并且在多核环境上执行,结果基本上可以肯定的说不是排序的,因为生成的查询计划是并行的,虽然数据是Clustered index scan读的,但是不保证顺序。因为我在后续的SSIS处理中需要使用Merge join(这个组件需要输入的2路数据是排序的),所以导致我在数据源的查询上没有加Order by,导致Merge过程的结果都不正确,而且每次都是随机值,每次都不一样。如果在查询上加了Order by,可以保证顺序,但是性能上会有很大的影响,如果影响大,可以根据情况考虑将Sort放到SSIS中来进行操作。

还有就是在Load Test前千万别忘了update statistics,否则查询计划可能都是错误的

 

今天还看了一篇Lubor的文章谈到如何按顺序删除数据的问题,其实那个问题也可以使用CTE来解决,1次Scan解决问题。也可以大幅提高性能

with d  as
(
select top (10000) a from t3
)
delete from d;

1 Comment - Leave a comment
  1. luke说道:

    你不用order by的话,直接delete top (10000) from d不就行了?

Leave a comment


Welcome , today is 星期四, 2017 年 03 月 30 日