SQL Server 性能调优之查询从20秒至2秒的处理方法

一、需求

需求很简单,就是需要查询一个报表,只有1个表,数据量大约60万左右,但是中间有些逻辑。

先说明一下服务器配置情况:1核CPU、2GB内存、机械硬盘、Sqlserver 2008 R2、Windows Server2008 R2 SP1和阿里云的服务器,简单说就是阿里云最差的服务器。

1、原始表结构

非常简单的一张表,这次不讨论数据冗余和表字段的设计,如是否可以把Project和Baojian提出成一个表等等,这个是原始表结构,这个目前是没有办法改变的。

2、查询的sql语句为

select *from( select *,ROW_NUMBER() OVER (ORDER BY sc desc) as rank from( select *, case when ( 40-(a.p*(case when a.p > 0 then 1 else -0.5 end)))<=30 then 30 else ( 40-(a.p*(case when a.p > 0 then 1 else -0.5 end))) end as sc from ( select * from ( select a.ProjectNumber, a.ProjectName, a.BaojianNumber, a.BaojianName, a.ToubiaoPerson, sum(UnitPrice) as sumPrice, b.price as avgPrice, ((sum(UnitPrice)-b.price)/nullif(b.price,0)*100) as p, sum(case when UnitPrice>b.price then b.price else UnitPrice end )as pprice, sum(case when UnitPrice>MaxPrice then 1 else 0 end ) as countChao from ToubiaoDetailTest1 a join ( select ProjectNumber, ProjectName, BaojianNumber, BaojianName, avg(price) as price from( select * from( select ProjectNumber, ProjectName, BaojianNumber, BaojianName, ToubiaoPerson, SUM(UnitPrice) as price, SUM(case when UnitPrice>MaxPrice then 1 else 0 end ) as countChao from ToubiaoDetailTest1 group BY ProjectNumber, ProjectName, BaojianNumber, BaojianName, ToubiaoPerson ) tt where tt.countChao = 0 ) t group by ProjectNumber, ProjectName, BaojianNumber, BaojianName ) b on a.ProjectNumber=b.ProjectNumber and a.ProjectName=b.ProjectName and a.BaojianNumber=b.BaojianNumber and a.BaojianName=b.BaojianName group by a.BaojianNumber, a.BaojianName, a.ProjectNumber, a.ProjectName, a.ToubiaoPerson, b.price ) tt where tt.countChao=0 ) a ) b ) t order by rank

此段sql语句主要的功能是:

1、根据ProjectNumber, ProjectName, BaojianNumber, BaojianName, ToubiaoPerson分组,查询所有数据的sum(UnitPrice)

  其中UnitPrice>MaxPrice的判断是为了逻辑,如果有一条数据满足,则此分组所有的数据不查询。

2、根据ProjectNumber, ProjectName, BaojianNumber, BaojianName 分组,查询所有数据的avg(price),以上两步主要就是为了查询根据ProjectNumber, ProjectName, BaojianNumber, BaojianName分组的avg(price)值。

3、然后根据逻辑获取相应的值、分数和按照分数排序分页等等操作。

二、性能调优

在未做任何优化之前,查询一次的时间大约为20秒左右。

1、建立索引

根据sql语句我们可以知道,会根据5个字段(ProjectNumber, ProjectName, BaojianNumber, BaojianName, ToubiaoPerson)进行分组聚合,所以尝试添加非聚集索引idx_calc。

在索引键列添加ProjectNumber, ProjectName, BaojianNumber, BaojianName, ToubiaoPerson。如图:

然后执行查询sql语句,发现执行时间已经减半了,只要10610毫秒。

2、索引包含列

分析查询sql可以得知,我们需要计算的值只有UnitPrice和MaxPrice,所以想到把UnitPrice和MaxPrice添加到idx_calc的包含列中。如图

然后执行查询sql语句,发现执行时间再次减半,只要6313毫秒,现在已经从之前的20多秒优化成6秒多。

3、再次优化查询Sql

再次分析sql语句可以把计算所有数据的avg(price)语句暂时放置临时表(#temp_table)中,再计算其他值的时候直接从临时表中(#temp_table)获取数据。

然后执行查询sql语句,执行时间只有2323毫秒。

在硬件、表数据量和查询稍复杂的情况下,这样已经可以基本上满足查询需求了。

三、总结

经过三步:1、建立索引,2、添加包含列,3、用临时表。用三步可以把查询时间从20秒优化至2秒。

以上所述是小编给大家介绍的SQL Server 性能调优之查询从20秒至2秒,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

时间: 2024-09-20 16:41:04

SQL Server 性能调优之查询从20秒至2秒的处理方法的相关文章

SQL Server 性能调优培训引言

原文:SQL Server 性能调优培训引言      大家好,这是我在博客园写的第一篇博文,之所以要开这个博客,是我对MS SQL技术学习的一个兴趣记录.       作为计算机专业毕业的人,自己对技术的掌握总是觉得很肤浅,博而不专,到现在我才发现自己的兴趣所在,于是我通过网络找了各种MS SQL技术的相关文档,总觉得讲得比较干涩,没有一个系统性,今年3月底我无意浏览到一个网站提供免费的性能调优的半年培训(http://www.sqlpassion.at/academy/performance

SQL Server 性能调优(一)——从等待状态判断系统资源瓶颈

原文:SQL Server 性能调优(一)--从等待状态判断系统资源瓶颈 通过DMV查看当时SQL SERVER所有任务的状态(sleeping.runnable或running) 2005.2008提供了以下三个视图工详细查询: DMV 用处 Sys.dm_exec_requests 返回有关在SQL Server中执行的每个请求的信息,包括当前的等待状态 Sys.dm_exec_sessions 对于每个通过身份验证的会话都返回相应的一行.此时图是服务器范围的视图.此视图首先可以查到服务器负

SQL Server性能调优之缓存

在执行任何查询时,SQL Server都会将数据读取到内存,数据使用之后,不会立即释放,而是会缓存在内存Buffer中,当再次执行相同的查询时,如果所需数据全部缓存在内存中,那么SQL Server不会产生Disk IO操作,立即返回查询结果,这是SQL Server的性能优化机制. 一,主要的内存消费者(Memory Consumer) 1,数据缓存(Data Cache) Data Cache是存储数据页(Data Page)的缓冲区,当SQL Server需要读取数据文件(File)中的数

SQL Server性能调优杂记(一)----傻瓜机的失效效应

最近,下面的一个项目遇到紧急问题,我这匹老马也要和年轻人一起奋斗一下.问题是当把一倍压力 数据灌入数据库,很多查询都奇慢无比. 说道这里必须要说一下性能问题的基本准则.性能问题 Tunning的次序 1)架构设计(软件架构和数据库设计,糟糕的设计几乎是致命的) 2)代码缺 陷(导致性能问题的90%) 3)增加索引(这个是要根据实际情况来确定) 4)资源调优(CPU- >内存->Disk IO) 这里网络不是考虑因素. 把程序的SQL文拿出来一看,有的一看一 堆子查询构成的JOIN,基本上一眼就

SQL Server 性能调优1

server|性能 1. 用程序中,保证在实现功能的基础上,尽量减少对数据库的访问次数:通过搜索参数,尽量减少对表的访问行数,最小化结果集,从而减轻网络负担:能够分开的操作尽量分开处理,提高每次的响应速度:在数据窗口使用SQL时,尽量把使用的索引放在选择的首列:算法的结构尽量简单:在查询时,不要过多地使用通配符如SELECT * FROM T1语句,要用到几列就选择几列如:SELECT COL1,COL2 FROM T1:在可能的情况下尽量限制尽量结果集行数如:SELECT TOP 300 CO

SQL Server性能调优杂记(四)

系统上线完,性能问题往往是Warranty和后期维护的一个重要问题. 这些天,客户又来反映, 有一个查询非常慢.这个查询用的是主关键字查询,由于主键是聚集索引,而且又做了碎片处理.应该是 非常快.但是看到的现象就是很慢(10秒左右,最差有18秒之多).排除了硬件.资源锁定等问题,还不 用到达Database端的Tunning级别.基本判断和SQL文有关,要细看SQL文的执行计划. 首先把SQL 文找出来 SELECT a.AWB_NO, a.BWB_NO, a.CWB_NO, a.ORIGIN,

SQL Server性能调优杂记(二)----傻瓜机的失效效应续

上文说道了失效效应.只想说明在Performance Tunning方面只能根据情况来寻求原因并解决.这是一 个有意思的过程.大原则是经验,帮助我们少犯错误.因此,糟糕的设计,必然导致性能问题.没有经验 的程序员必然会写出糟糕的代码.但是良好的设计可以弥补程序员的经验不足.这个到此打住,这个 topic涉及品质管理,实在太大了. 再看一例,失效效应的体现. 还是上文数说道了2种SQL文 写法产生的执行计划.我选用一台双核的PC,相当于2个单核CPU. 有一个大表TB_CWB.记录约30 -40万

SQL Server性能调优杂记(三)

这个例子和上面一个例子结果相反. SQL文1 declare @CWB_NO varchar(50) set @cwb_no='31301379874' SELECT a.AWB_NO, a.BWB_NO, a.CWB_NO, a.ORIGIN, a.DEST, a.MODIFY_ON, a.CREATED_ON, a.CONSIGNOR_CUSTOMER_CODE, a.CONSIGNOR_CODE, a.CONSIGNOR_NAME, a.CONSIGNEE_NAME, a.CWB_STAT

2年SQL Server DBA调优方面总结

原文:2年SQL Server DBA调优方面总结 2年SQL Server DBA调优方面总结 当2年dba 我觉得,有些东西需要和大家分享探讨,先书单. 书单 1.<深入解析SQL Server 2008 系列> 这个就是mssql 2005 的技术内幕系列.2012版的也出了有兴趣可以看看,技术内幕系列是我接触最早的书,里面内容涵盖量很大,但是都是点到为止.所以很多都是可以细细品味,回头再看的. 2.<Troubleshooting SQL Server A Guide for t