sqlserver sql优化案例及思路
始sql:
SELECT TOP 100 PERCENT ZZ.CREW_NAME AS 机组, ZZ.CREW_ID, AA.年度时间,
CC.当月时间, DD.连续七天时间 AS 最近七天
FROM (SELECT *
FROM CABIN_CREW_INFO
WHERE QUIT_DATE > CONVERT(VARCHAR, YEAR(43381)) + '-01-01')
ZZ LEFT OUTER JOIN
(SELECT CREW_ID, DBO.HOURFORMAT(SUM(FLIGHT_TIME) / 60.0, 4)
AS 年度时间
FROM (SELECT A.FLTID AS FLTID, dbo.TOTTime2(C.OFFBLK, A.ETD, A.ATD, A.ATA, A.ETA,
C.ONBLK, A.STATUS,D.QAR_OUT,D.QAR_OFF,D.QAR_ON,D.QAR_IN) AS FLIGHT_TIME, B.*
FROM dbo.FLY A LEFT OUTER JOIN
(SELECT DISTINCT TASK_ID, CREW_ID, ALLPOS
FROM dbo.CABIN_CREW_TASK_COPOS) B ON
A.CABIN_CREW_GROUP = B.TASK_ID LEFT OUTER JOIN
dbo.FLIGHTS_CREW_REPORT C ON A.FLTID = C.FLTID LEFT OUTER JOIN
dbo.FLIGHTS_QAR D ON A.FLTID = D.FLTID
WHERE (A.STC <> 'K') AND (A.STATUS <> 'CNL') AND
(A.CABIN_CREW_GROUP > 0) AND (A.ATD BETWEEN
CONVERT(VARCHAR, CONVERT(DATETIME, CONVERT(VARCHAR,
YEAR(43381)) + '-1-1') - 3.0 / 24, 120) AND CONVERT(VARCHAR,
CONVERT(DATETIME, (FLOOR(CONVERT(FLOAT, 43381)) + 1)
- 3.0 / 24 - 1.0 / (24 * 60 * 60)), 120)) AND
((SELECT COUNT(*)
FROM CABIN_SPECIAL_FLIGHTS
WHERE (CREW_ID = B.CREW_ID) AND (FLTID = A.FLTID)) = 0))
DEL
GROUP BY CREW_ID) AA ON ZZ.CREW_ID = AA.CREW_ID LEFT OUTER JOIN
(SELECT CREW_ID, DBO.HOURFORMAT(SUM(FLIGHT_TIME) / 60.0, 4)
AS 当月时间
FROM (SELECT A.FLTID AS FLTID, dbo.TOTTime2(C.OFFBLK, A.ETD, A.ATD, A.ATA, A.ETA,
C.ONBLK, A.STATUS,D.QAR_OUT,D.QAR_OFF,D.QAR_ON,D.QAR_IN) AS FLIGHT_TIME, B.*
FROM dbo.FLIGHTS A LEFT OUTER JOIN
(SELECT DISTINCT TASK_ID, CREW_ID, ALLPOS
FROM dbo.CABIN_CREW_TASK_COPOS) B ON
A.CABIN_CREW_GROUP = B.TASK_ID LEFT OUTER JOIN
dbo.FLIGHTS_CREW_REPORT C ON A.FLTID = C.FLTID LEFT OUTER JOIN
dbo.FLIGHTS_QAR D ON A.FLTID = D.FLTID
WHERE (A.STC <> 'K') AND (A.STATUS <> 'CNL') AND
(A.CABIN_CREW_GROUP > 0) AND (A.ATD BETWEEN
CONVERT(VARCHAR, CONVERT(DATETIME, CONVERT(VARCHAR,
YEAR(43381)) + '-' + CONVERT(VARCHAR, MONTH(43381)) + '-1')
- 3.0 / 24, 120) AND CONVERT(VARCHAR, CONVERT(DATETIME,
(FLOOR(CONVERT(FLOAT, 43381)) + 1)
- 3.0 / 24 - 1.0 / (24 * 60 * 60)), 120)) AND
((SELECT COUNT(*)
FROM CABIN_SPECIAL_FLIGHTS
WHERE (CREW_ID = B.CREW_ID) AND (FLTID = A.FLTID)) = 0))
DEL
GROUP BY CREW_ID) CC ON ZZ.CREW_ID = CC.CREW_ID LEFT OUTER JOIN
(SELECT CREW_ID, DBO.HOURFORMAT(SUM(FLIGHT_TIME) / 60.0, 4)
AS 连续七天时间
FROM (SELECT A.FLTID AS FLTID, dbo.TOTTime2(C.OFFBLK, A.ETD, A.ATD, A.ATA, A.ETA,
C.ONBLK, A.STATUS,D.QAR_OUT,D.QAR_OFF,D.QAR_ON,D.QAR_IN) AS FLIGHT_TIME, B.*
FROM dbo.FLIGHTS A LEFT OUTER JOIN
(SELECT DISTINCT TASK_ID, CREW_ID, ALLPOS
FROM dbo.CABIN_CREW_TASK_COPOS) B ON
A.CABIN_CREW_GROUP = B.TASK_ID LEFT OUTER JOIN
dbo.FLIGHTS_CREW_REPORT C ON A.FLTID = C.FLTID LEFT OUTER JOIN
dbo.FLIGHTS_QAR D ON A.FLTID = D.FLTID
WHERE (A.STC <> 'K') AND (A.STATUS <> 'CNL') AND
(A.CABIN_CREW_GROUP > 0) AND (A.ATD BETWEEN
CONVERT(VARCHAR, CONVERT(DATETIME, CONVERT(VARCHAR,
YEAR(DATEADD(DD, - 6, 43381))) + '-' + CONVERT(VARCHAR,
MONTH(DATEADD(DD, - 6, 43381))) + '-' + CONVERT(VARCHAR,
DAY(DATEADD(DD, - 6, 43381)))) - 3.0 / 24, 120) AND
CONVERT(VARCHAR, CONVERT(DATETIME, (FLOOR(CONVERT(FLOAT,
43381)) + 1) - 3.0 / 24 - 1.0 / (24 * 60 * 60)), 120)) AND
((SELECT COUNT(*)
FROM CABIN_SPECIAL_FLIGHTS
WHERE (CREW_ID = B.CREW_ID) AND (FLTID = A.FLTID)) = 0))
DEL
GROUP BY CREW_ID) DD ON ZZ.CREW_ID = DD.CREW_ID
ORDER BY DD.连续七天时间 DESC
优化思路
1:分析最慢点:
-----分解sql执行,问题出现在这个sql
SELECT CREW_ID, DBO.HOURFORMAT(SUM(FLIGHT_TIME) / 60.0, 4)
AS 年度时间
FROM (SELECT A.FLTID AS FLTID, dbo.TOTTime2(C.OFFBLK, A.ETD, A.ATD, A.ATA, A.ETA,
C.ONBLK, A.STATUS,D.QAR_OUT,D.QAR_OFF,D.QAR_ON,D.QAR_IN) AS FLIGHT_TIME, B.*
FROM dbo.fly A LEFT OUTER JOIN
(SELECT DISTINCT TASK_ID, CREW_ID, ALLPOS
FROM dbo.CABIN_CREW_TASK_COPOS) B ON
A.CABIN_CREW_GROUP = B.TASK_ID LEFT OUTER JOIN
dbo.fly_CREW_REPORT C ON A.FLTID = C.FLTID LEFT OUTER JOIN
dbo.fly_QAR D ON A.FLTID = D.FLTID
WHERE (A.STC <> 'K') AND (A.STATUS <> 'CNL') AND
(A.CABIN_CREW_GROUP > 0) AND (A.ATD BETWEEN
CONVERT(VARCHAR, CONVERT(DATETIME, CONVERT(VARCHAR,
YEAR(43381)) + '-1-1') - 3.0 / 24, 120) AND CONVERT(VARCHAR,
CONVERT(DATETIME, (FLOOR(CONVERT(FLOAT, 43381)) + 1)
- 3.0 / 24 - 1.0 / (24 * 60 * 60)), 120)) AND
((SELECT COUNT(*)
FROM CABIN_SPECIAL_fly
WHERE (CREW_ID = B.CREW_ID) AND (FLTID = A.FLTID)) = 0))
DEL
GROUP BY CREW_ID
2:根据sqlserver提示建立索引,未达到效果。
------tunning1
-USE [ISA]
GO
CREATE NONCLUSTERED INDEX [<Missing_INDEX_20181009]
ON [dbo].[fly] ([STATUS],[ATD],[STC],[CABIN_CREW_GROUP])
INCLUDE ([FLTID],[ETD],[ETA],[ATA])
GO
3:红色部分大部分重复,出去一个and 条件谓词都一样,这种sql难以迭代更新维护,考虑with as 语句改写
with SS as
(SELECT A.FLTID AS FLTID,A.ATD AS ATD ,dbo.TOTTime2(C.OFFBLK, A.ETD, A.ATD, A.ATA, A.ETA,
C.ONBLK, A.STATUS,D.QAR_OUT,D.QAR_OFF,D.QAR_ON,D.QAR_IN) AS FLIGHT_TIME, B.*
FROM dbo.FLIGHTS A LEFT OUTER JOIN
(SELECT DISTINCT TASK_ID, CREW_ID, ALLPOS FROM dbo.CABIN_CREW_TASK_COPOS) B ON
A.CABIN_CREW_GROUP = B.TASK_ID LEFT OUTER JOIN
dbo.FLIGHTS_CREW_REPORT C ON A.FLTID = C.FLTID LEFT OUTER JOIN
dbo.FLIGHTS_QAR D ON A.FLTID = D.FLTID
WHERE (A.STC <> 'K') AND (A.STATUS <> 'CNL') AND (A.CABIN_CREW_GROUP > 0) AND ((SELECT COUNT(*)
FROM CABIN_SPECIAL_FLIGHTS WHERE (CREW_ID = B.CREW_ID) AND (FLTID = A.FLTID)) = 0))
SELECT TOP 100 PERCENT ZZ.CREW_NAME AS 机组, ZZ.CREW_ID, AA.年度时间,
CC.当月时间, DD.连续七天时间 AS 最近七天
FROM (SELECT *
FROM CABIN_CREW_INFO
WHERE QUIT_DATE > CONVERT(VARCHAR, YEAR(43381)) + '-01-01')
ZZ LEFT OUTER JOIN
(SELECT CREW_ID, DBO.HOURFORMAT(SUM(FLIGHT_TIME) / 60.0, 4)
AS 年度时间
FROM ( SELECT * FROM SS WHERE (ATD BETWEEN
CONVERT(VARCHAR, CONVERT(DATETIME, CONVERT(VARCHAR,
YEAR(43381)) + '-1-1') - 3.0 / 24, 120) AND CONVERT(VARCHAR,
CONVERT(DATETIME, (FLOOR(CONVERT(FLOAT, 43381)) + 1)
- 3.0 / 24 - 1.0 / (24 * 60 * 60)), 120))
)
DEL
GROUP BY CREW_ID) AA ON ZZ.CREW_ID = AA.CREW_ID LEFT OUTER JOIN
(SELECT CREW_ID, DBO.HOURFORMAT(SUM(FLIGHT_TIME) / 60.0, 4)
AS 当月时间
FROM (SELECT * FROM SS WHERE (ATD BETWEEN
CONVERT(VARCHAR, CONVERT(DATETIME, CONVERT(VARCHAR,
YEAR(43381)) + '-' + CONVERT(VARCHAR, MONTH(43381)) + '-1')
- 3.0 / 24, 120) AND CONVERT(VARCHAR, CONVERT(DATETIME,
(FLOOR(CONVERT(FLOAT, 43381)) + 1)
- 3.0 / 24 - 1.0 / (24 * 60 * 60)), 120))
)
DEL
GROUP BY CREW_ID) CC ON ZZ.CREW_ID = CC.CREW_ID LEFT OUTER JOIN
(SELECT CREW_ID, DBO.HOURFORMAT(SUM(FLIGHT_TIME) / 60.0, 4)
AS 连续七天时间
FROM (SELECT * FROM SS WHERE
(ATD BETWEEN
CONVERT(VARCHAR, CONVERT(DATETIME, CONVERT(VARCHAR,
YEAR(DATEADD(DD, - 6, 43381))) + '-' + CONVERT(VARCHAR,
MONTH(DATEADD(DD, - 6, 43381))) + '-' + CONVERT(VARCHAR,
DAY(DATEADD(DD, - 6, 43381)))) - 3.0 / 24, 120) AND
CONVERT(VARCHAR, CONVERT(DATETIME, (FLOOR(CONVERT(FLOAT,
43381)) + 1) - 3.0 / 24 - 1.0 / (24 * 60 * 60)), 120))
)
DEL
GROUP BY CREW_ID) DD ON ZZ.CREW_ID = DD.CREW_ID
ORDER BY DD.连续七天时间 DESC
改写之后,sql临时表逻辑清晰,易于维护和性能优化,临时表SS,只是条件不同。在oracle这样能大幅度减少临时表扫描次数,可惜在sqlserver 效果不明显。
4:终极杀手锏,分析执行计划
查看上述sql红框sql进行了全表扫描及排序,可以考虑合适的索引替代:
create index CABIN_CREW_TASK_COPOS_20181009 on CABIN_CREW_TASK_COPOS(TASK_ID) INCLUDE(CREW_ID,ALLPOS)
立即可以看到优化效果
SQL Server 执行时间:
CPU 时间 = 25859 毫秒,占用时间 = 29679 毫秒。
总结:拿到sql,首先看整体框架,然后进行慢sql 分解,然后进行分布优化。通常情况下都是索引缺缺失,在OLTP环境中添加索引dba 需要权衡。
sqlserver sql优化案例及思路的更多相关文章
- SQL优化案例—— RowNumber分页
将业务语句翻译成SQL语句不仅是一门技术,还是一门艺术. 下面拿我们程序开发工程师最常用的ROW_NUMBER()分页作为一个典型案例来说明. 先来看看我们最常见的分页的样子: WITH CTE AS ...
- mysql的sql优化案例
前言 mysql的sql优化器比较弱,选择执行计划貌似很随机. 案例 一.表结构说明mysql> show create table table_order\G***************** ...
- SQL 优化案例 1
create or replace procedure SP_GET_NEWEST_CAPTCHA( v_ACCOUNT_ID in VARCHAR2, --接收短信的手机号 v_Tail_num i ...
- SQL 优化案例
create or replace procedure SP_GET_NEWEST_CAPTCHA( v_ACCOUNT_ID in VARCHAR2, --接收短信的手机号 v_Tail_num i ...
- 数栈SQL优化案例:隐式转换
MySQL是当下最流行的关系型数据库之一,互联网高速发展的今天,MySQL数据库在电商.金融等诸多行业的生产系统中被广泛使用. 在实际的开发运维过程中,想必大家也常常会碰到慢SQL的困扰.一条性能不好 ...
- SQL夯实基础(四):子查询及sql优化案例
首先我们先明确一下sql语句的执行顺序,如下有前至后执行: (1)from (2) on (3) join (4) where (5)group by (6) avg,sum... (7 ...
- 百倍性能的PL/SQL优化案例(r11笔记第13天)
我相信你是被百倍性能的字样吸引了,不过我所想侧重的是优化的思路,这个比优化技巧更重要,而结果嘛,其实我不希望说成是百倍提升,“”自黑“”一下. 有一个真实想法和大家讨论一下,就是一个SQL语句如果原本 ...
- SQL 优化案例之变更表结构
从慢日志报表中看到一条很长的SQL select id from myinfo and (( SUBSTRING_INDEX(location_axis, ) ) ) ), '$%') ) or ( ...
- 一则SQL优化案例
原始sql: select CASE ) counts ,) else deadline end as deadline from t_product_credit) c group by sort ...
随机推荐
- springboot-31-springboot静态注入
springboot中 使用 @Autowired 注入时, 是可以为静态变量进行注入的 package com.iwhere.footmark.tools; import org.springfra ...
- 【胡思乱想】命令模式 与 Thread Runnable
实现线程任务有两种方式,一种是创建Runnable/Callable对象,传递给Thread.另一种是子类重写Thread的run方法. 我觉得前一种像极了命令模式,或者说应该是命令模式的一个使用案例 ...
- Linux下自动清理超过指定大小文件的方法
由于线上业务用的squid,根据经验值如果长时间运行则缓存目录下的swap.state会慢慢变大,一旦超过60M,squid的性能就会急剧下降,因此需要定时去清理大于60M的swap.state文件. ...
- Linux 下面解压.tar.gz 和.gz文件解压的方式
Linux 下面解压.tar.gz 和.gz文件解压的方式 两种解压方式 1 .tar.gz 使用tar命令进行解压 tar -zxvf java.tar.gz 解压到指定的文件夹 tar -zxvf ...
- js 之 this的用法
该篇文章混合了比较多文章,由于自己也水平有限,大家就将就着看下吧,详情可以参看<JavaScript语言精粹>,不过文章提供了很多例子,供大家参阅思考. 首先关于this我想说一句话,这句 ...
- Spring学习之路-注解
Spring的注解总结. 地址:https://docs.spring.io/spring/docs/4.3.12.RELEASE/spring-framework-reference/htmlsin ...
- Docker基础-容器操作
1.创建容器 1.新建容器 可以使用docker create命令新建一个容器. [root@linux-node1 ~]# docker create -it ubuntu:latest ffc90 ...
- ASP.NET Repeater控件实现简单分页
早上,有看MSDN,看到了 PagedDataSource 类 http://msdn.microsoft.com/zh-cn/library/system.web.ui.webcontrols.pa ...
- 关于ASPxComboBox通过ClientInstanceName,js获取不到控件的问题
今天突然遇到一个很奇葩的问题 ASPxComboBox中设置了ClientInstanceName.但是通过cmbOrganization.GetValue()获取不到值. 报错cmbOrganiza ...
- Spring基础(8) : 延迟加载,Bean的作用域,Bean生命周期
1.延迟加载 <bean id="p" class="com.Person" lazy-init="true"/> @Confi ...