作一个查询的性能优化。

先清缓存

DBCC DROPCLEANBUFFERS

DBCC FREEPROCCACHE

原查询 前人遗留。

 declare @total float,@total_person float,@times_person float,@date varchar(50)
select @date=CONVERT(char(10),GETDATE(),120) select @total=sum(price*person)*1.0 from db_time t inner join db_movie m on t.movieid=m.id inner join db_cinema c on t.cinemaid=c.id
where CAST(showdate as date)='2014-02-27' and t.sta=1 select @times_person=sum(1) from db_time t inner join db_movie m on t.movieid=m.id inner join db_cinema c on t.cinemaid=c.id
where CAST(showdate as date)='2014-02-27' and t.sta=1 select @total_person=sum(person) from db_time t inner join db_movie m on t.movieid=m.id inner join db_cinema c on t.cinemaid=c.id
where CAST(showdate as date)='2014-02-27' and t.sta=1 ; with sr as(
select
--ROW_NUMBER() over(order by SUM(price*person) desc) as 'index'
--,
movieid id
,m.name name
,m.enname
,SUM(price*person)*1.0 as BoxOffice
,SUM(price*person)*1.0/@total BoxPercent
,sum(1) ShowCount
,sum(1)*1.0/@times_person ShowPercent
,sum(person) AudienceCount
,sum(person)*1.0/@total_person AudiencePercent
,cast(round(sum(price*person)*1.0/sum(person),0) as int) Price
--,sum(person)*1.0/sum(1) as test
--,sum(person)*1.0 as t1
--,sum(1) as t2
,cast(round(sum(person)*1.0/sum(1),0) as int) as Renci
,round(CAST(sum(person) as float)/sum(seat),4) as Shangzl
from db_time t inner join db_movie m on t.movieid=m.id inner join db_cinema c on t.cinemaid=c.id
where CAST(showdate as date)='2014-02-27' and t.sta=1
group by movieid,m.name,m.enname
) select * from sr order by BoxOffice desc

执行时间18S

最开始想着是把上面3条求总量的查询改成在一条里完成,where条件重复多次,想想开脆改成开窗函数好了

经开窗函数改造后的查询。

 with sr as(
select
distinct
--ROW_NUMBER() over(order by SUM(price*person) desc) as 'index'
--,
movieid id
,m.name name
,m.enname
,(SUM(price*person) OVER(PARTITION BY movieid))*1.0 as BoxOffice
,(SUM(price*person) OVER(PARTITION BY movieid))*1.0/(SUM(price*person) OVER()) as BoxPercent
,sum(1) OVER(PARTITION BY movieid) as ShowCount
,(sum(1) OVER(PARTITION BY movieid))*1.0/(sum(1) OVER()) ShowPercent
,sum(person) OVER(PARTITION BY movieid) AudienceCount
,((sum(person) OVER(PARTITION BY movieid))*1.0)/((sum(person) OVER())) AudiencePercent
,cast(round((sum(price*person) OVER(PARTITION BY movieid))*1.0/(sum(person) OVER(PARTITION BY movieid)),0) as int) Price
,cast(round(((sum(person) OVER(PARTITION BY movieid))*1.0/(count(0) OVER(PARTITION BY movieid))),0) as int) as Renci
,round(CAST((sum(person) OVER(PARTITION BY movieid)) as float)/(sum(seat) OVER(PARTITION BY movieid)),4) as Shangzl
from db_time t inner join db_movie m on t.movieid=m.id inner join db_cinema c on t.cinemaid=c.id
where CAST(showdate as date)='2014-02-27' and t.sta=1
)
select * from sr order by BoxOffice desc

代码确实精简不少,同样的where子句消除了。(两个查询中的rownumber完全没用,注掉了)

执行时间17S,心里隐隐期待的是查询时间有明显减少,实际查询时间在误差范围内,基本未变化,看来开发开窗函数的目的不是为性能提升,而是为了方便开发人员编写查询代码,减少查询难度,提高查询可读性。

查询计划有很大变化,经开窗函数改造后的查询计划,多了很多“表假脱机”的执行步骤

但两种查询最耗时的依然是97%聚集索引扫描(表上只有id的自增聚集索引)

sqlserver开窗函数改造样例的更多相关文章

  1. sqlserver开窗函数

    从 http://jimshu.blog.51cto.com/3171847/1376637/ 转 开窗函数是在 ISO 标准中定义的.SQL Server 提供排名开窗函数和聚合开窗函数. 在开窗函 ...

  2. sqlserver开窗函数在财务对账中的用法

    曾几何时发现开窗函数在财务对账总特别好用.但是每次可能很久没用,逻辑都要重头来过.特此留一份完整的思考逻辑待日后参考. 以下是数据源: 从上面的数据可以看到通过C列,那么只需要两个条件即可获得已经用对 ...

  3. sqlserver 开窗函数Over()的使用

    利用over(),将统计信息计算出来,然后直接筛选结果集 declare @t table(ProductID int,ProductName varchar(20),ProductType varc ...

  4. C#调用 Oracle 存储过程样例代码

    -- 建表 CREATE TABLE sale_report (      sale_date DATE NOT NULL ,      sale_item VARCHAR(2) NOT NULL , ...

  5. Lambda 表达式的演示样例-来源(MSDN)

    本文演示怎样在你的程序中使用 lambda 表达式. 有关 lambda 表达式的概述.请參阅 C++ 中的 Lambda 表达式. 有关 lambda 表达式结构的具体信息,请參阅 Lambda 表 ...

  6. openssl之EVP系列之6---EVP_Encrypt系列函数编程架构及样例

    openssl之EVP系列之6---EVP_Encrypt系列函数编程架构及样例     ---依据openssl doc/crypto/EVP_EncryptInit.pod和doc/ssleay. ...

  7. SQLServer学习笔记<>.基础知识,一些基本命令,单表查询(null top用法,with ties附加属性,over开窗函数),排名函数

    Sqlserver基础知识 (1)创建数据库 创建数据库有两种方式,手动创建和编写sql脚本创建,在这里我采用脚本的方式创建一个名称为TSQLFundamentals2008的数据库.脚本如下:   ...

  8. SQLserver 连接+开窗函数+视图+事务

    今天学习SQLserver 连接以及开窗函数..加油! 1.复习:查询(检索)->筛选列->筛选行:distinct top where 运算符与关键字:比较运算符,逻辑运算符,betwe ...

  9. VB.net数据库编程(03):一个SQLserver连接查询的简单样例

    这个样例,因为在ADO.net入门已经专门学了,再次进行复习 一下. 主要掌握连接字串的情况. 过程就是: 1.引用System.Data.SqlClient.而Access中引用 的是System. ...

随机推荐

  1. Django框架(十一):模板介绍、模板语言、模板继承、HTML转义

    1. 模板介绍 1.1 模板的功能 产生html,控制页面上展示的内容.模板文件不仅仅是一个html文件. 模板文件包含两部分内容: 静态内容:css.js.html. 动态内容:用于动态去产生一些页 ...

  2. Animate.css 一款强大的预设css3动画库

    Animate.css是一个有趣的,跨浏览器的css3动画库.很值得我们在项目中引用. 用法 1.首先引入animate css文件 <head> <link rel="s ...

  3. Linux 配置单机yum源--ISO镜像做源

    前提:防火墙关闭.SElinus关闭 1.上传ISO镜像(建议传到home目录下) [root@localhost home]# ls iso/ CentOS-.iso 2.挂载目录 [root@lo ...

  4. PAT Basic 1083 是否存在相等的差 (20) [hash映射,map STL]

    题目 给定 N 张卡⽚,正⾯分别写上 1.2.--.N,然后全部翻⾯,洗牌,在背⾯分别写上 1.2.--. N.将每张牌的正反两⾯数字相减(⼤减⼩),得到 N 个⾮负差值,其中是否存在相等的差? 输⼊ ...

  5. flask框架-下

    Local与偏函数 threasing.local 多个线程修改同一个数据,复制多份变量给每个线程用,为每个线程开辟一块空间进行数据存储. 不使用therading.local # 不用local f ...

  6. Vue专题-生命周期

    有时候,我们需要在实例创建过程中进行一些初始化的工作,以帮助我们完成项目中更复杂更丰富的需求开发,针对这样的需求,Vue提供给我们一系列的钩子函数. 本文详细介绍了Vue实例在创建和销毁的过程中,我们 ...

  7. 小白学习之pytorch框架(6)-模型选择(K折交叉验证)、欠拟合、过拟合(权重衰减法(=L2范数正则化)、丢弃法)、正向传播、反向传播

    下面要说的基本都是<动手学深度学习>这本花书上的内容,图也采用的书上的 首先说的是训练误差(模型在训练数据集上表现出的误差)和泛化误差(模型在任意一个测试数据集样本上表现出的误差的期望) ...

  8. 吴裕雄--天生自然Linux操作系统:Linux常用命令大全

    系统信息 arch 显示机器的处理器架构 uname -m 显示机器的处理器架构 uname -r 显示正在使用的内核版本 dmidecode -q 显示硬件系统部件 - (SMBIOS / DMI) ...

  9. JS中的7种设计模式

    第九章Refactoring to OOP Patterns 重构为OOP模式 7种设计模式: 1,模版方法模式(template method) 2,策略模式(strategy) 3,状态模式(st ...

  10. Java实现生产与消费(完美注释版)

    /** * 2019年8月8日17:42:23 * 目的:Java多线程实现生产与消费 * @author 张涛 * * 多态: * 一个父类的引用既可以指向父类对象 * 也可以指向子类对象 * 它会 ...