作一个查询的性能优化。

先清缓存

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. Linux(CENTOS7) Tomcat服务成功发布但局域网浏览器无法访问

    问题 : 我在linux搭建了一个tomcat服务器,tomcat开启后,发现在局域网浏览器上无法访问该tomcat,浏览器报无法访问服务器错误,我查看了tomcat的日志,路径..../tomcat ...

  2. 27. docker compose 单机 均衡负载

    1.编写Dockerfile #Dockerfile FROM python:2.7 LABEL maintaner="eaon eaon123@docker.com" COPY ...

  3. lvm镜像卷

    镜像能够分配物理分区的多个副本,从而提高数据的可用性.当某个磁盘发生故障并且其物理分区变为不可用时,你仍然可以访问可用磁盘上的镜像数据.LVM在逻辑卷内执行镜像. 系统版本 # cat /etc/ce ...

  4. web标准介绍

    web标准介绍 web标准: w3c:万维网联盟组织,用来制定web标准的机构(组织) web标准:制作网页遵循的规范 web标准规范的分类:结构标准.表现标准.行为标准. 结构:html.表示:cs ...

  5. Anaconda环境安装

    Anaconda环境安装 一.Anaconda Anaconda是Python的一个开源的发行版本,里面包含了很多科学计算相关的包,它和Python的关系就像linux系统中centos和Ubuntu ...

  6. Microsoft .NET Framework 4.5.2 (Offline Installer)

    Microsoft .NET Framework 4.5.2 (Offline Installer) for Windows Vista SP2, Windows 7 SP1, Windows 8, ...

  7. TFRecord 的使用

    什么是 TFRecord PS:这段内容摘自 http://wiki.jikexueyuan.com/project/tensorflow-zh/how_tos/reading_data.html 一 ...

  8. 33)new和delete关键字

    ---------------------------------------------------------------------------------------------------- ...

  9. jenkins推送docker镜像到远程仓库

    参考链接:https://blog.csdn.net/qq_34252622/article/details/92791262

  10. mysql命令行操作大全

    Mysql安装目录 数据库目录/var/lib/mysql/配置文件/usr/share/mysql(mysql.server命令及配置文件)相关命令/usr/bin(mysqladmin mysql ...