始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优化案例及思路的更多相关文章

  1. SQL优化案例—— RowNumber分页

    将业务语句翻译成SQL语句不仅是一门技术,还是一门艺术. 下面拿我们程序开发工程师最常用的ROW_NUMBER()分页作为一个典型案例来说明. 先来看看我们最常见的分页的样子: WITH CTE AS ...

  2. mysql的sql优化案例

    前言 mysql的sql优化器比较弱,选择执行计划貌似很随机. 案例 一.表结构说明mysql> show create table table_order\G***************** ...

  3. SQL 优化案例 1

    create or replace procedure SP_GET_NEWEST_CAPTCHA( v_ACCOUNT_ID in VARCHAR2, --接收短信的手机号 v_Tail_num i ...

  4. SQL 优化案例

    create or replace procedure SP_GET_NEWEST_CAPTCHA( v_ACCOUNT_ID in VARCHAR2, --接收短信的手机号 v_Tail_num i ...

  5. 数栈SQL优化案例:隐式转换

    MySQL是当下最流行的关系型数据库之一,互联网高速发展的今天,MySQL数据库在电商.金融等诸多行业的生产系统中被广泛使用. 在实际的开发运维过程中,想必大家也常常会碰到慢SQL的困扰.一条性能不好 ...

  6. SQL夯实基础(四):子查询及sql优化案例

    首先我们先明确一下sql语句的执行顺序,如下有前至后执行: (1)from  (2) on   (3) join  (4) where  (5)group by  (6) avg,sum...  (7 ...

  7. 百倍性能的PL/SQL优化案例(r11笔记第13天)

    我相信你是被百倍性能的字样吸引了,不过我所想侧重的是优化的思路,这个比优化技巧更重要,而结果嘛,其实我不希望说成是百倍提升,“”自黑“”一下. 有一个真实想法和大家讨论一下,就是一个SQL语句如果原本 ...

  8. SQL 优化案例之变更表结构

    从慢日志报表中看到一条很长的SQL select id from myinfo and (( SUBSTRING_INDEX(location_axis, ) ) ) ), '$%') ) or ( ...

  9. 一则SQL优化案例

    原始sql: select CASE ) counts ,) else deadline end as deadline from t_product_credit) c group by sort ...

随机推荐

  1. mpvue小程序图片404

    mpvue开发小程序时候,要添加静态本地图片 <img src="../../images/bg.png" alt=""> 会报错: VM14878 ...

  2. 高可用的MongoDB集群-实战篇

    1.概述 最近有同学和网友私信我,问我MongoDB方面的问题:这里我整理一篇博客来赘述下MongoDB供大家学习参考,博客的目录内容如下: 基本操作 CRUD MapReduce 本篇文章是基于Mo ...

  3. 基于Web Service的客户端框架搭建三:代理层(Proxy)

    前言 代理层的主要工作是调用Web Service,将在FCL层序列化好的Json数据字符串Post到Web Service,然后获得Reponse,再从响应流中读取到调用结果Json字符串,在Dis ...

  4. Unity生成WebService代理类

    普通的.net程序中,如果我们想引用webService,只需在项目中右键选择添加服务引用,然后在地址栏中输入Webservice地址,单击“转到”按钮,找到服务后再单击确定,Visual Studi ...

  5. Deep learning with Python 学习笔记(6)

    本节介绍循环神经网络及其优化 循环神经网络(RNN,recurrent neural network)处理序列的方式是,遍历所有序列元素,并保存一个状态(state),其中包含与已查看内容相关的信息. ...

  6. 【LeetCode题解】232_用栈实现队列(Implement-Queue-using-Stacks)

    目录 描述 解法一:在一个栈中维持所有元素的出队顺序 思路 入队(push) 出队(pop) 查看队首(peek) 是否为空(empty) Java 实现 Python 实现 解法二:一个栈入,一个栈 ...

  7. 关于Markdown插入图片路径错误的问题

    关于Markdown插入图片路径错误的问题 开发问题 解决方法  妈耶,连续一天写2篇博客,也是醉了,这篇博客主要是介绍关于Markdown插入图片路径错误的问题 在上篇中,我介绍了一下Markdow ...

  8. ffplay源码分析2-数据结构

    ffplay是FFmpeg工程自带的简单播放器,使用FFmpeg提供的解码器和SDL库进行视频播放.本文基于FFmpeg工程4.1版本进行分析,其中ffplay源码清单如下: https://gith ...

  9. 微信公众号开发笔记1-获取Access Token

    获取你的Access Token a)可以采用网址的形式: 用appid和appsecert获得access token,接口为https://api.weixin.qq.com/cgi-bin/to ...

  10. 分布式理论(八)—— Consistent Hash(一致性哈希算法)

    前言 在分布式系统中,常常需要使用缓存,而且通常是集群,访问缓存和添加缓存都需要一个 hash 算法来寻找到合适的 Cache 节点.但,通常不是用取余hash,而是使用我们今天的主角-- 一致性 h ...