SQL 优化总结(三) SQL子句

SQL子句

  尽可能编写优化器可以优化的语句。

1、 SELECT子句

(1) 在查询Select语句中用Where字句限制返回的行数,避免表扫描,如果返回不必要的数据,浪费了服务器的I/O资源,加重了网络的负担降低性能。如果表很大,在表扫描的期间将表锁住,禁止其他的联接访问表,后果严重。用select top 100 / 10 Percent 来限制用户返回的行数或者SET ROWCOUNT来限制操作的行。

(2) 查询时不要返回不需要的列。字段提取要按照“需多少、提多少”的原则,避免“select *”,尽量使用“select 字段1,字段2,字段3........”。实践证明:每少提取一个字段,数据的提取速度就会有相应的提升。提升的速度还要看您舍弃的字段的大小来判断。

(3) 避免返回大结果集的查询

(4) 检索紧跟在 INSERT SQL 之后且位于同一连接上的 IDENTITY值

SELECT @@IDENTITY

例如:

SET NOCOUNT ON;// 表示返回的记录集有一行和一列,其中包含了这个新的 IDENTITY 值。

INSERT INTO Products (ProductName)  VALUES ('Chalk')

SELECT @@IDENTITY

2、 WHERE子句

(1)   函数名和列名分开

任何对列的操作都将导致表扫描,它包括数据库函数、计算表达式等等,查询时要尽可能将操作移至等号右边。

语句

时间

select * from record   where substring(card_no,1,4) ='5378'

(13秒)

select * from record   where card_no like  '5378%'

(< 1秒)

where子句中对列的任何操作结果都是在SQL运行时逐列计算得到的,因此它不得不进行表搜索,而没有使用该列上面的索引;如果这些结果在查询编译时就能得到,那么就可以被SQL优化器优化,使用索引,避免表搜索。

(2) 表达式等号右边的字段值应尽量与等号左边的字段数据类型完全一致

分析select emp_name form employee where salary > 3000 在此语句中若salary是Float类型的,则优化器对其进行优化为Convert(float,3000) ,因为3000是个整数,我们应在编程时使用3000.0而不要等运行时让DBMS进行转化。同样字符和整型数据的转换。

(3) 在 WHERE 子句中减少需要分组的行数而避免在HAVING子句中进行

假设您将按区域对所有销售人员进行分组并将他们的销售额进行小计,但是您只想要那些数据库中标记为处于活动状态的销售人员。您可以按区域对销售人员分组,并使用 HAVING 子句消除那些未处于活动状态的销售人员,也可以在 WHERE 子句中执行此操作。在 WHERE 子句中执行此操作会减少需要分组的行数,所以比在HAVING 子句中执行此操作效率更高。HAVING 子句中基于行的条件的筛选会强制查询对那些在WHERE子句中会被去除的数据进行分组。

(4) WHERE子句中的连接顺序

sql解析器采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前,那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾

SELECT … FROM emp e WHERE sal>50000 AND job=‘MANAGER’AND 25<(SELECT COUNT(*)  FROM emp WHERE mgr=e.empno) ;

效率低于

SELECT… FROM emp e WHERE 25<(SELECT COUNT(*)  FROM emp WHERE mgr=e.empno)  AND sal>50000 AND job=‘MANAGER’;

WHERE子句后面的条件顺序对大数据量表的查询会产生直接的影响,如

 

Select * from zl_yhjbqk where dy_dj = '1K以下' and xh_bz=1

Select * from zl_yhjbqk where xh_bz=1 and dy_dj = '1K以下'

以上两个SQL中dy_dj及xh_bz两个字段都没进行索引,所以执行的时候都是全表扫描,第一条SQL的dy_dj = '1KV以下'条件在记录集内比率为99%,而xh_bz=1的比率只为0.5%,在进行第一条SQL的时候99%条记录都进行dy_dj及xh_bz的比较,而在进行第二条SQL的时候0.5%条记录都进行dy_dj及xh_bz的比较,以此可以得出第二条SQL的CPU占用率明显比第一条低。

(5) where语句条件顺序

有索引的列优先,都有索引的看查询出来的数据量,少的优先。

(6) 条件中最好不要使用OR或IN。

原文地址:https://www.cnblogs.com/liushen/p/3335948.html