SQLServer性能优化之活用临时表

本文涉及的产品
云数据库 RDS SQL Server,基础系列 2核4GB
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
简介:
继续调优,今天上午分析了以下一条处理时间达40秒的SQL语句
select *
  from table 
 where T_table_ID in  
  (
   select  distinct s.t_table_id 
     from 
     (  
      select distinct a.t_table_id,a.bt 
        from   
        (select left(bt,4) as bbt,* from table where fsrq>getdate()-1 and gkbz=1 and scbz=0) a,  
        (select distinct left(bt,4) as bbt,t_table_id from table where fsrq>getdate()-1 and gkbz=1 and scbz=0) b  
       where b.bbt like a.bbt and a.t_table_id<>b.t_table_id  
         and a.bbt not like '%aaaa%' and a.bbt not like '%bbbb%' and a.bbt not like '%cccc%' 
         and a.bbt not like '%dddd%' and a.bbt not like '%eeee%' and a.bbt not like '%ffff%' 
         and a.bbt not like '%aaaa%' and a.bbt not like '%bbbb%' and a.bbt not like '%cccc%' 
         and a.bbt not like '%dddd%' and a.bbt not like '%eeee%' and a.bbt not like '%ffff%' 
         -- order by a.bt  
      union all  
      select distinct a.t_table_id,a.bt 
        from   
        (select right(bt,5) as bbt,* from table where fsrq>getdate()-1 and gkbz=1 and scbz=0) a,  
        (select distinct right(bt,5) as bbt,t_table_id from table where fsrq>getdate()-1 and gkbz=1 and scbz=0) b  
       where b.bbt like a.bbt and a.t_table_id<>b.t_table_id   
         and a.bbt not like '%aaaa%' and a.bbt not like '%bbbb%' and a.bbt not like '%cccc%' 
         and a.bbt not like '%dddd%' and a.bbt not like '%eeee%' and a.bbt not like '%ffff%' 
         and a.bbt not like '%aaaa%' and a.bbt not like '%bbbb%' and a.bbt not like '%cccc%' 
         and a.bbt not like '%dddd%' and a.bbt not like '%eeee%' and a.bbt not like '%ffff%' 
         and a.bbt not like '%'+(select right(convert(varchar(10),getdate()-1,20),2)+')') +'%'  
         and b.bbt not like '%'+(select right(convert(varchar(10),getdate()-1,20),2)+')') +'%'  
       ) s   
   )order by bt  
基本上可以认为是对同一张表的反复操作,而且语句中夹杂了太多的全表扫描
SQLServer的执行计划我个人认为图形化界面固然是好,但是有些时候对于量化的I/O,CPU,COST输出却很不直观,此外像该SQL这样的执行计划,估计1600*1200的整个屏幕都无法显示,可以认为基本是没法看的

只能将SQL分解成若干小SQL,逐步找到瓶颈所在,例如
select left(bt,4) as bbt,* from table where fsrq>getdate()-1 and gkbz=1 and scbz=0
select distinct left(bt,4) as bbt,t_table_id from table where fsrq>getdate()-1 and gkbz=1 and scbz=0
这两个语句的执行都非常快,并且结果集也比较小,但是两条语句合并后并加上相关条件就非常缓慢。
干脆直接构建两个临时表,反正都是全表扫描,用两个临时表做相互的join,测试之后发现只需要1秒
再构建下面的两个SQL临时表,也做同样的测试
最后再全部合并到一起进行测试,发现也就是2~3秒
实际上还可以再优化一些临时表的构建,但效果达到了也就不愿意尝试了

也尝试过用CTE,不过似乎效果不佳
以下为优化后的SQL样例
/*
with temp1 as
(select left(bt,4) as bbt,* from table where fsrq>getdate()-1 and gkbz=1 and scbz=0),
temp2 as
(select distinct left(bt,4) as bbt,t_table_id from table where fsrq>getdate()-1 and gkbz=1 and scbz=0),
temp3 as
(select left(bt,5) as bbt,* from table where fsrq>getdate()-1 and gkbz=1 and scbz=0),
temp4 as
(select distinct left(bt,5) as bbt,t_table_id from table where fsrq>getdate()-1 and gkbz=1 and scbz=0)
*/
print convert(varchar,getdate(),9)
select left(bt,4) as bbt,* into #temp1 from table where fsrq>getdate()-1 and gkbz=1 and scbz=0
select distinct left(bt,4) as bbt,t_table_id into #temp2 from table where fsrq>getdate()-1 and gkbz=1 and scbz=0
select right(bt,5) as bbt,* into #temp3 from table where fsrq>getdate()-1 and gkbz=1 and scbz=0
select distinct right(bt,5) as bbt,t_table_id into #temp4 from table where fsrq>getdate()-1 and gkbz=1 and scbz=0
select 
(select ms from xtclb where dm=lmxz and lb in (130,131) ) as '栏目选择',
 bt,mtly,czy 
  from table 
 where T_table_ID in  
  (
   select  distinct s.t_table_id 
     from 
     (  
      select distinct a.t_table_id,a.bt 
        from   
        #temp1 a,  
        #temp2 b  
       where b.bbt like a.bbt and a.t_table_id<>b.t_table_id  
         and a.bbt not in ('aaaa','bbbb','cccc','dddd','eeee','ffff')
         and b.bbt not in ('aaaa','bbbb','cccc','dddd','eeee','ffff')
      union all  
      select distinct a.t_table_id,a.bt 
        from   
        #temp3 a,  
        #temp4 b  
       where b.bbt like a.bbt and a.t_table_id<>b.t_table_id   
         and a.bbt not like '%aaaa%' and a.bbt not like '%bbbb%' and a.bbt not like '%cccc%' 
         and a.bbt not like '%dddd%' and a.bbt not like '%eeee%' and a.bbt not like '%ffff%' 
         and a.bbt not like '%'+(select right(convert(varchar(10),getdate()-1,20),2)+')') +'%'  
         and a.bbt not like '%aaaa%' and a.bbt not like '%bbbb%' and a.bbt not like '%cccc%' 
         and a.bbt not like '%dddd%' and a.bbt not like '%eeee%' and a.bbt not like '%ffff%' 
         and b.bbt not like '%'+(select right(convert(varchar(10),getdate()-1,20),2)+')') +'%'  
       ) s   
   )order by bt  
   --OPTION (loop join); 
   --34
print convert(varchar,getdate(),9)   
/*
drop table #temp1   
drop table #temp2
drop table #temp3
drop table #temp4
*/

   








本文转自baoqiangwang51CTO博客,原文链接:http://blog.51cto.com/baoqiangwang/361039,如需转载请自行联系原作者

相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS&nbsp;SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/sqlserver
相关文章
|
6月前
|
SQL 存储 数据库
SQL Server性能优化策略与实践
在使用Microsoft SQL Server(简称MSSQL)进行数据库管理时,性能优化是确保系统高效运行、提升用户体验的关键环节
|
8月前
|
SQL 关系型数据库 数据库
阿里云数据库 RDS SQL Server版实战【性能优化实践、优点探析】
本文探讨了Amazon RDS SQL Server版在云数据库中的优势,包括高可用性、可扩展性、管理便捷、安全性和成本效益。通过多可用区部署和自动备份,RDS确保数据安全和持久性,并支持自动扩展以适应流量波动。可视化管理界面简化了监控和操作,而数据加密和访问控制等功能保障了安全性。此外,弹性计费模式降低了运维成本。实战应用显示,RDS SQL Server版能有效助力企业在促销高峰期稳定系统并保障数据安全。阿里云的RDS SQL Server版还提供了弹性伸缩、自动备份恢复、安全性和高可用性功能,进一步优化性能和成本控制,并与AWS生态系统无缝集成,支持多种开发语言和框架。
456 2
|
SQL 索引
SQL Server性能优化之CPU
SQL Server CPU性能优化
1337 0
|
SQL 存储 缓存
sqlserver 存储过程中使用临时表到底会不会导致重编译
原文:sqlserver 存储过程中使用临时表到底会不会导致重编译 曾经在网络上看到过一种说法,SqlServer的存储过程中使用临时表,会导致重编译,以至于执行计划无法重用,运行时候会导致重编译的这么一个说法,自己私底下去做测试的时候,根据profile的跟踪结果,存储过程中使用临时表,如果不是统...
1022 0
|
SQL 索引 存储
SQL Server SQL性能优化之--pivot行列转换减少扫描计数优化查询语句
原文:SQL Server SQL性能优化之--pivot行列转换减少扫描计数优化查询语句 原文出处:http://www.cnblogs.com/wy123/p/5933734.html     先看常用的一种表结构设计方式:   那么可能会遇到一种典型的查询方式,主子表关联,查询子表中的某些(或者全部)Key点对应的Value,横向显示(也即以行的方式显示)   这种查询方式很明显的一个却显示多次对字表查询(暂时抛开索引)   相比这种查询方式很多人都遇到过,如果子表是配置信息之类的小表的话,问题不大,如果字表数据量较大,可能就会有影响了。
1265 0
|
SQL 缓存 数据库
SqlServer性能优化之获取缓存的查询计划中的聚合性能统计信息
SqlServer性能优化之获取缓存的查询计划中的聚合性能统计信息
4381 0