一、需求

需求很简单,就是需要查询一个报表,只有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秒的更多相关文章

  1. SQL Server 性能调优培训引言

    原文:SQL Server 性能调优培训引言 大家好,这是我在博客园写的第一篇博文,之所以要开这个博客,是我对MS SQL技术学习的一个兴趣记录. 作为计算机专业毕业的人,自己对技术的掌握总是觉得很肤 ...

  2. sql server 性能调优之 资源等待PAGELATCH

    一.概述 在前几章介绍过 sql server 性能调优资源等待之PAGEIOLATCH,PAGEIOLATCH是出现在sql server要和磁盘作交互的时候,所以加个IO两个字.这次来介绍PAGE ...

  3. sql server 性能调优之 资源等待 LCk

    一.  概述 这次介绍实例级别资源等待LCK类型锁的等待时间,关于LCK锁的介绍可参考 “sql server 锁与事务拨云见日”.下面还是使用sys.dm_os_wait_stats 来查看,并找出 ...

  4. sql server 性能调优之 CPU消耗最大资源分析1 (自sqlserver服务启动以后)

    一. 概述 上次在介绍性能调优中讲到了I/O的开销查看及维护,这次介绍CPU的开销及维护, 在调优方面是可以从多个维度去发现问题如I/O,CPU,  内存,锁等,不管从哪个维度去解决,都能达到调优的效 ...

  5. sql server性能调优

    转自:https://www.cnblogs.com/woodytu/tag/%E6%80%A7%E8%83%BD%E8%B0%83%E4%BC%98%E5%9F%B9%E8%AE%AD/defaul ...

  6. [转]SQL Server 性能调优(io)

      目录 诊断磁盘io问题 常见的磁盘问题 容量替代了性能 负载隔离配置有问题 分区对齐配置有问题 总结 关于io这一块,前面的东西如磁盘大小,磁盘带宽,随机读取写入,顺序读取写入,raid选择,DA ...

  7. sql server 性能调优 资源等待之网络I/O

    原文:sql server 性能调优 资源等待之网络I/O 一.概述 与网络I/O相关的等待的主要是ASYNC_NETWORK_IO,是指当sql server返回数据结果集给客户端的时候,会先将结果 ...

  8. sql server 性能调优 资源等待之内存瓶颈的三种等待类型

    原文:sql server 性能调优 资源等待之内存瓶颈的三种等待类型 一.概述 这篇介绍Stolen内存相关的主要三种等待类型以及对应的waittype编号,CMEMTHREAD(0x00B9),S ...

  9. CPU开销sql server 性能调优

    sql server 性能调优 CPU开销分析 一. 概述 上次在介绍性能调优中讲到了I/O的开销查看及维护,这次介绍CPU的开销及维护, 在调优方面是可以从多个维度去发现问题如I/O,CPU, 内存 ...

随机推荐

  1. css代码初始化

    @charset "utf-8";/* 页面元素初始化和常用样式定义-start *//*======== 全局 ========*/body, div, dl, dt, dd, ...

  2. dedecms搜索提示"关键字不能小于2个字节!"

    在测试自己制作的搜索页模板时,如果遇到搜索时提示"关键字不能小于2个字节!"!打开plus/search.php把   if(($keyword=='' || strlen($keyword)< ...

  3. 快速排序(Quicksort)的Javascript实现

    日本程序员norahiko,写了一个排序算法的动画演示,非常有趣. 这个周末,我就用它当做教材,好好学习了一下各种排序算法. 排序算法(Sorting algorithm)是计算机科学最古老.最基本的 ...

  4. java基础:简单实现线程池

    前段时间自己研究了下线程池的实现原理,通过一些源码对比,发现其实核心的东西不难,于是抽丝剥茧,决定自己实现一个简单线程池,当自已实现了出一个线程池后.发现原来那么高大上的东西也可以这么简单. 先上原理 ...

  5. IOS机型margin属性无效问题

    这个问题很多小伙伴都有遇到,这次本猿也遇到了,记录一笔. 结论:简单的解决办法margin换padding!如有误,请大神不吝赐教.在Chrome浏览器移动端测试iphone5,打开的也是没问题的(这 ...

  6. 集成python双版本详解

    最近要准备学习Python,由于版本上的差异,不知道要学哪个,现在好多东西都是基于python2基础的,但是python2在2020年左右就可能停止了,所以干脆决定两个都装上吧!   首先上官网上下载 ...

  7. An abandoned sentiment from past

    An abandoned sentiment from past time limit per test 1 second memory limit per test 256 megabytes in ...

  8. Rest模式get,put,post,delete含义与区别(转)

    POST   /uri     创建 DELETE /uri/xxx 删除 PUT    /uri/xxx 更新或创建 GET    /uri/xxx 查看 GET操作是安全的.所谓安全是指不管进行多 ...

  9. js中数学运算的处理

    connum = Number(connum) + Number($(this).parents('.123').find(".views_core_hidden").val()) ...

  10. workday1

    前天是实习的第一天,现在补下感想 总的来说还是不错的,师兄很nice,师妹很羞涩,我很尴尬,我的交际能力还是有待提高(主要是普通话不标准~~~~(>_<)~~~~) 早上由华工C12穿梭到 ...