Jimmy那些事儿

SQL Server_性能优化

SQL Server 查询逻辑与性能优化

6.1 查询流

6.1.1 Select 语法

  1. Select语句的From部分将所有数据源组装进一个结果集,然后由Select语句的剩余部分对结果集执行操作。
  2. Where子句作用于From组装的记录集,根据条件筛选某些行。
  3. 聚合函数对数据集执行求和操作。
  4. Group by 子句根据在该子句中指定的列将大量数据集分组成较小的数据集。
  5. Having 对较小的数据组执行聚合函数。
  6. Order by 子句确定结果子的排列顺序。默认为升序;
1
2
3
4
5
6
7
8
Select [Distinct] [Top(n)] *, columns, or expressions
[From data source(s)]
[Join data source
ON condition] (may include multiple joins)
[Where conditions]
[Group by columns]
[Having conditions]
[Order by columns];

6.1.3 查询语句的逻辑流

数据源(From) —— 条件(Where) —— 列/表达式 (col/exp) —— Order by — 谓词

  1. From,查询首先组装初始数据集
  2. Where,筛选;筛选过程实际上是选择符合标准的行的where子句
  3. Group by,组合数据的子集 [若要分组,先对数据排序,然后根据排序后的数据进行聚合]
  4. 聚合,Aggregations,选择性地对数据进行聚合;如求平均值,按列中的值对数据分组以及筛选组;
  5. Having,筛选数据的子集
  6. 列表达式:处理Select列,并计算任何表达式 [ 这个时候才涉及到列 ]
  7. Order by,排序
  8. Over,窗口函数和排名函数通过与其他聚合函数一起提供结果的单独排序的视图
  9. Distinct,从结果集中删除任何重复的行
  10. Top,选定行后,执行计算,并按所需的顺序排序
  11. Insert,Update,Delete,最后一个逻辑步骤是将数据修改操作应用到查询结果。
  12. Output,选择插入和删除的虚拟表,并返回给客户端
  13. Union,堆叠或合并多个查询的结果

6.2 From子句

6.2.3 表名称

  • 方括号:表名或字段名如果引用了sql server中的关键字,数据库会不识别这到底是关键字还是表名(还是字段名)时就必须要加;
    • 查询语句的表中加上方括号[ ] , 目的是以声明其不是保留字
    • 如果表名不是关键字,不用加方括号

6.2.4 完全限定的名称

  • Server.Database.Scheme.Table;服务器.数据库.架构.表名称
    • 常使用后两部分来限定即可;

6.3 Where条件

  • 最佳实践:找到事物的最好办法就是查找,而不是先排除不是该事物的所有东西。即where条件,声明肯定的限制条件优于否定的限制条件;
1
where col >= 10 ; 优于 where col !< 9

惊叹号! ,不是ANSI标准的SQL;

6.3.1 Between And

1
2
3
4
5
6
7
8
9
10
11
# 使用带有日期时间值的 BETWEEN
WHERE RateChangeDate BETWEEN '2001-12-12' AND '2002-01-05';
----下面的示例检索所在的行【datetime值】可以介于'20011212'和'20020105'(含) 之间;因为在查询中的日期值和datetime值存储在RateChangeDate而无需在日期的时间部分中指定了列。
-- 下面是结果集:
BusinessEntityID RateChangeDate
----------- -----------------------
3 2001-12-12 00:00:00.000
4 2002-01-05 00:00:00.000
----未指定时间部分时,将默认使用 12:00 A.M。
--请注意,若某行的时间部分晚于 2002-01-05 12:00 A.M., 则由于它处于范围之外,因此此查询不返回该行。

6.3.2 与列比较

  1. 如果函数用于where子句中的测试列,那SQL Server 在筛选where子句前被迫对每一行计算该函数
1
2
3
--正确的写法; where col = 130 -30
--避免的情况; where col + 30 =130
  1. 对于NOT IN条件来说,如果列表中有NULL值,每行都别判定为FALSE; 证明否定命题是很难的,尤其是当NULL值也包括在内时;
1
2
3
Select 'IN' where 'A' Not In ('B', 'C'); 返回 IN
Select 'IN' where 'A' Not In ('B', 'NULL'); 返回空

6.3.3 使用Like搜索条件

运算符 含义 示例
% 任意长度的字符串 Email Like ‘%@%.com’
‘_’ 任意一个字符 AuthorName Like ‘张_’
[ ] 指定范围内的任意一个字符 A Like ‘A6C8[1-5]’
[^] 不在指定范围内的任意一个字符 A Like ‘A6C8[^1-6]’

查找含通配符的表达式:

  1. 把通配符放入方括号[ ] 内
  2. 在其之前放一个转义符

6.3.4 多个where条件

  • 布尔逻辑运算的优先次序: NOT > AND > OR
1
2
3
4
5
6
7
8
9
10
Where name Like 'Chain%' or ProductID Between 320 And 324
And name Like '%s%'
--1. 先执行And,即找出name中 带有 s 的名字;
--2. 再在其中寻找 name中有Chain 或者 ProduceID在[320,324]
------------------
Where (name Like 'Chain%' or ProductID Between 320 And 324 )
And name Like '%s%'
--1. 先执行括号,即先找出name中有Chain 或者 ProduceID在[320,324]
--2. 再在其中找出name中 带有 s 的名字;
  • what:
  • why :
  • how :


  • what:
  • why :
  • how :