一、需求

需求很简单,就是需要查询一个报表,只有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. 错误处理1: D:\a1-C++\C++作业\第五次1.cpp undefined reference to `vtable for Shape'

    在编译程序的时候遇到此误,在google上查,很多地方都说是因为虚基类里面的虚拟析构函数没有提供实现导致的.但是我的已经提供了实现,也不行.最后发现是其他没有提供实现的虚函数造成的.所以,在一个虚基类 ...

  2. .NET MVC页面生命周期及传统ASP.NET页面周期

    目前我主要使用.Net MVC框架进行网页创建,数据库是MSSQL Server.所以,我就用.NET MVC框架的web页面周期来说明页面的生命周期,但是我觉着其他MVC框架也是大同小异的. 本文主 ...

  3. MQL语句大全

    mysql sql语句大全 1.说明:创建数据库 CREATE DATABASE database-name 2.说明:删除数据库 drop database dbname 3.说明:备份sql se ...

  4. html加javascript和canvas类似超级玛丽游戏

    html加javascript和canvas制作 代码来源于网上 复制可用 <!doctype html><html lang="en"> <head ...

  5. JavaWeb系列:Servlet

    个人整理,欢迎转载与批评建议,转载请添加索引,谢谢. ---------------------------------------------------------------2017.06.10 ...

  6. Dubbox中开发REST风格的远程调用

    转载: http://zyg345646335.iteye.com/blog/2208899

  7. less函数

    问题描述: 在编写页面时,有以下几种按钮: 这时候我们CSS代码毫无疑问写一个公共类,然后再为每个按钮增加独自的样式如下: HTML: <div class="common a&quo ...

  8. lvs之 lvs原理架构介绍

    一. 概念 lvs的术语: Router:GWIP vs:virtual server,director rs:real server CIP:client IP VIP:virtual server ...

  9. react 基础

    一.组件 函数式定义的无状态组件 es5原生方式React.createClass定义的组件 es6形式的extends React.Component定义的组件 React.Component是以E ...

  10. SQL之删除触发器

    比如要删除的触发器名字叫dbo.test_trigger. 先判断这个触发器是否存在,判断存在后删除 if exists (select * from sysobjects where name = ...