作一个查询的性能优化。

先清缓存

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. Feign整合测试

    1.测试使用 (1)服务调用方引入依赖 <dependency> <groupId>org.springframework.cloud</groupId> < ...

  2. 深入分析Java反射(七)-简述反射调用的底层实现

    前提 Java反射的API在JavaSE1.7的时候已经基本完善,但是本文编写的时候使用的是Oracle JDK11,因为JDK11对于sun包下的源码也上传了,可以直接通过IDE查看对应的源码和进行 ...

  3. Java Keyword Static 学习记录

    Static Java编程思想:一旦将什么东西设为static,数据或方法就不会同那个类的任何对象实例联系到一起. 特点:随着类的加载而加载,随着类的销毁而销毁. 作用:可以修饰成员变量,代码块,方法 ...

  4. leetcode中二分查找的具体应用

    给定一个按照升序排列的整数数组 nums,和一个目标值 target.找出给定目标值在数组中的开始位置和结束位置. 你的算法时间复杂度必须是 O(log n) 级别. 如果数组中不存在目标值,返回 [ ...

  5. 吴裕雄--天生自然深度学习TensorBoard可视化:命名空间

    # 1. 不同的命名空间. import tensorflow as tf with tf.variable_scope("foo"): a = tf.get_variable(& ...

  6. Java之多线程方式一(继承Thread类)

    /** * 多线程的创建,方式一:继承于Thread类 * 1. 创建一个继承于Thread类的子类 * 2. 重写Thread类的run() --> 将此线程执行的操作声明在run()中 * ...

  7. Java 实现 栈

    package Test; import java.util.*; public class Stack_test { public static void main(String[] args) { ...

  8. python——logging模块

    简介: 日志是一种可以追踪某些软件运行时所发生事件的方法.软件开发人员可以向他们的代码中调用日志记录相关的方法来表明发生了某些事情.不同的事件,被区分在不同的等级中,故通过log分析,可以很轻易地分析 ...

  9. HTML5中的data-*属性

    data-* 属性包括两部分: 属性名不应该包含任何大写字母,并且在前缀 "data-" 之后必须有至少一个字符: 属性值可以是任意字符串: 注释:用户代理会完全忽略前缀为 &qu ...

  10. 判断1/N是否为无限小数

    给定一个正整数N,请判断1/N是否为无限小数,若是输出YES,若不是请输出NO. 思路: 只要被除数n可以转换成2的次幂或者2与5的组合即为有限小数,否则为无线小数 代码如下: #include &l ...