数据库调优(二)Inner Join Merge Join Hash Match
T-SQL 的编码习惯以及规范,影响的是查询优化器对执行计划的选择
健壮的SQL语句,更稳定、更高效
SELECT 几个部分:
- 查询的数据来自什么表
- 需要查询表中哪些字段 (尽量不使用类似于 **SELECT *** )
- 查询出符合哪些特定条件的数据
- 对数据进行排序、分组、汇总等操作 (限定结果集 => SELECT TOP 防止大量IO)
ORDER BY 子句性能取决于参与排序操作的数据量大小,避免大数据量的排序操作(考虑添加非聚集索引)
GROUP BY (DISTINCT 相当于全字段的GROUP BY)
冲突 => 所有的分组和排序需要用到索引,索引不能建立太多
DELETE 检索数据的性能
排他锁,影响到索引;如果频繁删除数据的表,建立索引时,谨慎查询和更新的频率;
WHERE 子句优化
针对筛选条件的语句进行的,其实就是一个合理索引的选择及高效应用
where条件是否合理的判断因素:
- 是否有合适的索引可供使用
-
字段是否有函数计算
- 返回结果集是否过大
- 是否仅查询出需要的字段
关联查询
=> 嵌套循环 (Inner Join) => 适用于小数据量和大数据量之间的连接操作,是性能最好的连接方式
内部表(数据量多的表)存在索引时,嵌套循环发挥最佳性能,执行计划进行索引查找 Index Seek
外部表存 (数据量小的表)在索引,执行计划进行 索引扫描 Index Scan
=> 合并连接 (Merge Join)
关联表数据相当且存在唯一索引,如果都不存在索引则会进行哈希连接
=> 哈希连接 (Hash Match)
关联表不存在索引,也未进行排序 (考虑在表中的字段增加索引进行 Inner Join 或者 Merge Join)
子查询
-
子查询尽量集中在where子句中,方便阅读
-
在一个语句中,子查询的数量不超过3个,整个查询语句涉及的表不超过5个
子查询中的语句会被执行计划分解、简化、特殊的转换,转化成常用的连接操作
-
避免在子查询中对大量的数据进行汇总或者排序操作
-
尽量缩小子查询中可能返回的结果集,设计的数据量尽可能小
-
尽量使用确定的判断符(=/IN/EXISTS)避免使用any、all