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 ...
随机推荐
- discuz 文件模板edit
1.修改title Power by discuz! 位置:template/default/common --->header_common.htm 2.discuz.htm 文件路径(修 ...
- tomcat 配置文件server.xml 详解 Connector Engine Host Context
目录 一 server.xml 1.1 server 配置 1.2 service 配置 1.3 Executor 1.4 Connector 配置 1.5 Engine 其他tocmat 文章 一 ...
- psql工具使用(二)
所有psql命令都以 \ 开头 一.使用psql -l查看有哪些数据库: -bash-4.2$ psql -l List of databases Name | Owner | Encodin ...
- 散列算法-SHA
一种生成信息摘要的算法.主要用于数据一致性和完整性的校验 SHA算法分很多版本,最大的分类是SHA-1和SHA-2.SHA-2包括很多子版本,SHA-224,SHA-256,SHA-384,SHA-5 ...
- WPF设置控件获取键盘焦点时的样式FocusVisualStyle
控件获取焦点除了用鼠标外,可以通过键盘来获取,比如Tab键或者方向键等,需要设置控件获取键盘焦点时的样式,可以通过设置FrameworkElemnt.FocusVisualStyle属性, 因为几乎所 ...
- CRM项目测试第一天
经过前几天代码的修改,界面的完善.主要的功能都实现了!今天主要是交换各组的项目,互相来测试,找bug. 在互相测试的过程,我听见有一组应该算是讨论的比价激烈的!我们组我们自己找到了bug,但是测试我们 ...
- Postsharp 破解工具(通杀版,持续更新)
2019.04.18 重要说明 VS2019 正式版已经发布了,Postsharp v6.2.2-Preview(预览版)也开始支持VS2019.不过截至目前,该预览版还不是特别稳定,因此提醒下大家在 ...
- [转]Winform开发框架的重要特性总结
本文转自:https://www.cnblogs.com/wuhuacong/p/3199829.html 从事Winform开发框架的研究和推广,也做了有几个年头了,从最初的项目雏形到目前各种重要特 ...
- DataTable数据显示于MVC应用程序
这篇博文是把DataTable的数据显示于MVC的应用程序上. 首先我们在数据库中创建一个表,并添加数据,然后创建存储过程: 接下来,我们去下载一个BusinessBase组件:http://www. ...
- SQL-Server多表关联查询并分页
一.多表关联查询 1,left join RelaTimeLog表 和 ValidFlight表关联查询 order by t.FlightId desc 2,与group by连用 group by ...