作一个查询的性能优化。

先清缓存

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. 学习SEO之7天精通SEO

    这本书大致看了一下,对于SEO基本上有了一个初步的认识,附上链接以供学习之用. 百度网盘:https://pan.baidu.com/s/1Bntzh2YF4tBd2AYAL1Q8vQ 心得:1.SE ...

  2. -mtime

    大家在使用find命令中的mtime参数时候,会看到官方的解释如下:  -mtime n               File's data was last modified n*24 hours ...

  3. javascript编程中极易出现的错误(个人)

    2018-08-10 1,setInterval打错字写成ser 2,document.getElementById().innerHTML;HTML需要全部大写 3,在for循环中定义一个i时要记住 ...

  4. 如何在 main() 执行之前先运行其它函数

    摘要:我们知道 C++ 的全局对象的构造函数会在 main 函数之前先运行,其实在 c 语言里面很早就有啦,在 gcc 中可以使用 __attribute__ 关键字指定如下(在编译器编译的时候就绝决 ...

  5. javascript阻止事件冒泡和浏览器的默认行为

    1.阻止事件冒泡,使成为捕获型事件触发机制. 1 function stopBubble(e) { 2 //如果提供了事件对象,则这是一个非IE浏览器 3 if ( e && e.st ...

  6. apt源换国内源

    vim /etc/apt/sources.list deb http://mirrors.163.com/debian/ jessie main non-free contribdeb http:// ...

  7. hdu2896&&3065

    题:http://acm.hdu.edu.cn/showproblem.php?pid=2896 分析:ac自动机模板 注意细节,1.128个ascii码都要: 2.只要关键码含有只输出一个编号就行 ...

  8. mysql查看变量

    在MySQL客户端执行如下命令查看MySQL的数据存放位置: show global variables like "%datadir%"; 查看端口号 show global v ...

  9. Debian8.8解决双系统访问windows磁盘时,有时能成功挂载,有时不能成功挂载的情况

    1.确保在debian下安装了挂载工具.2.进入windows关闭windows快速启动功能,关闭办法是控制面板,在电源管理中,选择关闭盖子的功能,点击“更改不能更改的选项”,去掉快速启动的钩,重启进 ...

  10. 前端Js复习-前后台的搭建-结合Bootstrap和JQuery搭建vue项目

    流式布局思想 """ 页面的尺寸改变动态改变页面布局,或是通过父集标签控制多个子标签,这种布局思想就称之为 - 流式布局思想 1) 将标签宽高设置成 百分比,就可以随屏幕 ...