SQL Server SQL性能优化之--pivot行列转换减少扫描计数优化查询语句

本文涉及的产品
云数据库 RDS SQL Server,基础系列 2核4GB
简介: 原文:SQL Server SQL性能优化之--pivot行列转换减少扫描计数优化查询语句原文出处:http://www.cnblogs.com/wy123/p/5933734.html     先看常用的一种表结构设计方式:   那么可能会遇到一种典型的查询方式,主子表关联,查询子表中的某些(或者全部)Key点对应的Value,横向显示(也即以行的方式显示)   这种查询方式很明显的一个却显示多次对字表查询(暂时抛开索引)   相比这种查询方式很多人都遇到过,如果子表是配置信息之类的小表的话,问题不大,如果字表数据量较大,可能就会有影响了。
原文: SQL Server SQL性能优化之--pivot行列转换减少扫描计数优化查询语句

原文出处:http://www.cnblogs.com/wy123/p/5933734.html

 

 

先看常用的一种表结构设计方式:

 

那么可能会遇到一种典型的查询方式,主子表关联,查询子表中的某些(或者全部)Key点对应的Value,横向显示(也即以行的方式显示)

 

这种查询方式很明显的一个却显示多次对字表查询(暂时抛开索引)

 

相比这种查询方式很多人都遇到过,如果子表是配置信息之类的小表的话,问题不大,如果字表数据量较大,可能就会有影响了。

这个查询目的是将”纵表”存储的结果“横向”显示,相当于横列转换的感觉了。
可以将子表的结果一次性将纵表的结果转换成横标,再跟主表连接,
然后得到一个最终一样的查询结果(格式),就能够减少子表的查询次数
这里将子表的结果“一次性将纵表的结果转换成横标”,是典型的行列转换操作

 

首先先看一下这里所说的一次转换成横标的这一步骤,需要借助pivot,一步一步来

 

然后看跟主表join之后,两种查询方式的整体查询结果

 

那么看一下后一种查询方式也即通过行业转换之后做join的执行计划,可以看到只对字表进行了一次查找(这里是index seek,但是暂抛开索引)

 

观察一下两条SQL的IO信息,可以发现,前者的Scan count是5,逻辑读是65,后者的Scan count是1,逻辑读是13,65=13*5。可见后者是一次性将表中的几个Key值读取出来的,而前者每个Key值读取一次表。

 

总结:

  改写SQL是实现优化的思路之一,当然改写SQL技巧有很多种,本文仅对某一类典型查询提供一个改写思路,避免对一个表进行多次读取的方式来实现的查询。
  通过改写一个常用的查询写法,从而实现一个等价的逻辑来减少对基表的读取次数来达到SQL优化的目的。
  当然实际情况可能更加复杂,采用该思路改写的时候要注意针对SQL语句测试验证。

附上本文的测试脚本

create table HeaderTable
(
    HeaderId int ,
    OtherColumn varchar(50)
)


create table DetailTable
(
    HeaderId int,
    DetailId int identity(1,1),
    DetailKey varchar(50),
    DetailValues int
)


declare @i int = 0
while @i<1000000
begin
    insert into HeaderTable values (@i,NEWID())
    insert into DetailTable (HeaderId,DetailKey,DetailValues)values(@i,'A0001',RAND()*10000)
    insert into DetailTable (HeaderId,DetailKey,DetailValues)values(@i,'A0002',RAND()*10000)
    insert into DetailTable (HeaderId,DetailKey,DetailValues)values(@i,'A0003',RAND()*10000)
    insert into DetailTable (HeaderId,DetailKey,DetailValues)values(@i,'A0004',RAND()*10000)
    insert into DetailTable (HeaderId,DetailKey,DetailValues)values(@i,'A0005',RAND()*10000)
    insert into DetailTable (HeaderId,DetailKey,DetailValues)values(@i,'A0006',RAND()*10000)
    insert into DetailTable (HeaderId,DetailKey,DetailValues)values(@i,'A0007',RAND()*10000)
    insert into DetailTable (HeaderId,DetailKey,DetailValues)values(@i,'A0008',RAND()*10000)
    insert into DetailTable (HeaderId,DetailKey,DetailValues)values(@i,'A0009',RAND()*10000)
    insert into DetailTable (HeaderId,DetailKey,DetailValues)values(@i,'A0010',RAND()*10000)
    set @i=@i+1
end

create index idx_HeaderId on HeaderTable(HeaderId)

create index idx_HeaderId on DetailTable(HeaderId)

create index idx_DetailKey on DetailTable(DetailKey)



select *,
(select DetailValues from DetailTable t where t.HeaderId = a.HeaderId and  t.DetailKey = 'A0001') as 'Key1的值',
(select DetailValues from DetailTable t where t.HeaderId = a.HeaderId and  t.DetailKey = 'A0002') as 'Key2的值',
(select DetailValues from DetailTable t where t.HeaderId = a.HeaderId and  t.DetailKey = 'A0003') as 'Key3的值',
(select DetailValues from DetailTable t where t.HeaderId = a.HeaderId and  t.DetailKey = 'A0004') as 'Key4的值',
(select DetailValues from DetailTable t where t.HeaderId = a.HeaderId and  t.DetailKey = 'A0005') as 'Key5的值'
from HeaderTable a 
where a.HeaderId = 10000


SELECT 
a.*,
t.A0001 as  'Key1的值',
t.A0002 as  'Key2的值',
t.A0003 as  'Key3的值',
t.A0004 as  'Key4的值',
t.A0005 as  'Key5的值'
from HeaderTable a inner join
(select HeaderId ,DetailKey ,DetailValues from DetailTable)t
 pivot( MAX(DetailValues) FOR DetailKey IN (A0001,A0002,A0003,A0004,A0005)
)t  on t.HeaderId = a.HeaderId
where a.HeaderId = 10000

 

  

目录
相关文章
|
4月前
|
SQL 数据挖掘 数据库
第三篇:高级 SQL 查询与多表操作
本文深入讲解高级SQL查询技巧,涵盖多表JOIN操作、聚合函数、分组查询、子查询及视图索引等内容。适合已掌握基础SQL的学习者,通过实例解析INNER/LEFT/RIGHT/FULL JOIN用法,以及COUNT/SUM/AVG等聚合函数的应用。同时探讨复杂WHERE条件、子查询嵌套,并介绍视图简化查询与索引优化性能的方法。最后提供实践建议与学习资源,助你提升SQL技能以应对实际数据处理需求。
301 1
|
1月前
|
SQL 人工智能 数据库
【三桥君】如何正确使用SQL查询语句:避免常见错误?
三桥君解析了SQL查询中的常见错误和正确用法。AI产品专家三桥君通过三个典型案例:1)属性重复比较错误,应使用IN而非AND;2)WHERE子句中非法使用聚合函数的错误,应改用HAVING;3)正确的分组查询示例。三桥君还介绍了学生、课程和选课三个关系模式,并分析了SQL查询中的属性比较、聚合函数使用和分组查询等关键概念。最后通过实战练习帮助读者巩固知识,强调掌握这些技巧对提升数据库查询效率的重要性。
87 0
|
6月前
|
SQL 索引
【YashanDB知识库】字段加上索引后,SQL查询不到结果
【YashanDB知识库】字段加上索引后,SQL查询不到结果
|
2月前
|
SQL
SQL中如何删除指定查询出来的数据
SQL中如何删除指定查询出来的数据
|
4月前
|
SQL 关系型数据库 MySQL
凌晨2点报警群炸了:一条sql 执行200秒!搞定之后,我总结了一个慢SQL查询、定位分析解决的完整套路
凌晨2点报警群炸了:一条sql 执行200秒!搞定之后,我总结了一个慢SQL查询、定位分析解决的完整套路
凌晨2点报警群炸了:一条sql 执行200秒!搞定之后,我总结了一个慢SQL查询、定位分析解决的完整套路
|
4月前
|
SQL 存储 自然语言处理
SQL的解析和优化的原理:一条sql 执行过程是什么?
SQL的解析和优化的原理:一条sql 执行过程是什么?
SQL的解析和优化的原理:一条sql 执行过程是什么?
|
3月前
|
SQL 存储 弹性计算
OSS Select 加速查询:10GB CSV 文件秒级过滤的 SQL 语法优化技巧
OSS Select 可直接在对象存储上执行 SQL 过滤,跳过文件下载,仅返回所需数据,性能比传统 ECS 方案提升 10~100 倍。通过减少返回列、使用等值查询、避免复杂函数、分区剪枝及压缩优化等技巧,可大幅降低扫描与传输量,显著提升查询效率并降低成本。
|
6月前
|
SQL 关系型数据库 MySQL
如何优化SQL查询以提高数据库性能?
这篇文章以生动的比喻介绍了优化SQL查询的重要性及方法。它首先将未优化的SQL查询比作在自助餐厅贪多嚼不烂的行为,强调了只获取必要数据的必要性。接着,文章详细讲解了四种优化策略:**精简选择**(避免使用`SELECT *`)、**专业筛选**(利用`WHERE`缩小范围)、**高效联接**(索引和限制数据量)以及**使用索引**(加速搜索)。此外,还探讨了如何避免N+1查询问题、使用分页限制结果、理解执行计划以及定期维护数据库健康。通过这些技巧,可以显著提升数据库性能,让查询更高效流畅。
|
6月前
|
SQL 缓存 关系型数据库
SQL为什么不建议执行多表关联查询
本文探讨了SQL中不建议执行多表关联查询的原因,特别是MySQL与PG在多表关联上的区别。MySQL仅支持嵌套循环连接,而不支持排序-合并连接和散列连接,因此在多表(超过3张)关联查询时效率较低。文章还分析了多表关联查询与多次单表查询的效率对比,指出将关联操作放在Service层处理的优势,包括减少数据库计算资源消耗、提高缓存效率、降低锁竞争以及更易于分布式扩展等。最后,通过实例展示了如何分解关联查询以优化性能。
225 0
|
12月前
|
关系型数据库 MySQL 网络安全
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")