一、需求

需求很简单,就是需要查询一个报表,只有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. 部署项目到weblogic时提示文件被锁,导致报错

    部署项目到weblogic中出现一个“黄叹号!”.报错如下: (1) Deployment is out of date due to changes in the underlying projec ...

  2. springcloud(九):配置中心和消息总线(配置中心终结版)

    我们在springcloud(七):配置中心svn示例和refresh中讲到,如果需要客户端获取到最新的配置信息需要执行refresh,我们可以利用webhook的机制每次提交代码发送请求来刷新客户端 ...

  3. python——爬虫&问题解决&思考(三)

    继续上一篇文章的内容,上一篇文章中,将爬虫调度器已经写好了,调度器是整个爬虫程序的"大脑",也可以称之为指挥中心.而现在,我们要做的就是去将调度器中用到的其他组件写好.首先是url ...

  4. JavaSE教程-03Java中分支语句与四种进制转换

    一.分支语句 计算机源于生活,程序模拟现实生活,从而服务生活 行为模式 1,起床,刷牙,洗脸,吃早餐,上课,回家,睡觉(顺序性) 2,如果时间不太够,打个滴滴快车,如果时间够,坐个地铁(选择性) 3, ...

  5. Spring Task每次都会调用两次的问题

    最近一个Spring Mvc的项目中需要定时执行一个任务,所以使用了spring 自带的Task功能.本地调试的时候一切都正常,可是部署到服务器上后,每次任务都会被调用两次.在网上搜索了相关的问题,排 ...

  6. JAVA设计模式初探之装饰者模式

    定义:动态给一个对象添加一些额外的职责,就象在墙上刷油漆.使用Decorator模式相比用生成子类方式达到功能的扩充显得更为灵活.设计初衷:通常可以使用继承来实现功能的拓展,如果这些需要拓展的功能的种 ...

  7. 加载jquery插件注意了

    1.尽量放在</body>之前,不要放在</head>标签之前,如果执意要放也要放在css之后,例如: <link href="style.css" ...

  8. 安装Mysql5.7并修改初始密码

    Centos 安装MySQL可以参考之前写的一篇文章 Centos7.3 安装Mysql5.7并修改初始密码 windows安装mysql5.7有两种方式 1.下载.msi安装文件直接根据界面提示进行 ...

  9. zookeeper 应用场景概述

    Zookeeper主要可以干哪些事情:配置管理,名字服务,提供分布式同步以及集群管理. 一 .配置管理 在我们的应用中除了代码外,还有一些就是各种配置.比如数据库连接,远程服务访问地址等.一般我们都是 ...

  10. 我的第一个jQuery插件--表格隔行变色

    虽然网上有大量的插件供我们去使用,但不一定有一款适合你的,必要的时候还是要自己动手去敲的.下面,开始我的第一个插件... 参考<锋利的JQuery>,JQuery为开发插件增设了俩个方法: ...