- 数据类型无需进行类型转换
-- 好(salary是flaot类型)select emp_name from employee where salary>3000.0-- 坏select emp_name from employee where salary>3000
分析select emp_name form employee where salary > 3000 在此语句中若salary是Float类
型的,则优化器对其进行优化为Convert(float,3000),因为3000是个整数,我们应在编程时
使用3000.0而不要等运行时让DBMS进行转化。同样字符和整型数据的转换
2. 不要使用select *
-- 好select emp_name tel from employee-- 坏select * from employee
使用select *的话会增加解析的时间,另外会把不需要的数据也给查询出来,数据传输也是
耗费时间的,
比如text类型的字段通常用来保存一些内容比较繁杂的东西,如果使用select *则会把该字段
也查询出来。
3.谨慎使用模糊查询
-- 好select emp_name tel from employee where emp_name like 'paral%'-- 坏select * from employee where emp_name like '%paral%'
当模糊匹配以%开头时,该列索引将失效,若不以%开头,该列索引有效。
3. 应尽量避免在where子句中对字段进行函数操作
-- 好select id from t where name like 'abc%'select id from t where createdate>='2022-01-01' and createdate<='2022-05-01'-- 坏select id from t where substring(name,1,3)='abc'select id from t where datediff(day,createdate,'2022-05-01')=0
这将导致引擎放弃使用索引而进行全表扫描
4. 优先使用UNION ALL,避免使用UNION
-- 好select name from studentunion allselect name from teacher-- 坏select name from studentunionselect name from teacher
UNION 因为会将各查询子集的记录做比较,故比起UNION ALL ,通常速度都会慢上许多。
一般来说,如果使用UNION ALL能满足要求的话,务必使用UNION ALL。还有一种情况,
如果业务上能够确保不会出现重复记录。
6.应尽量避免在 where 子句中对字段进行表达式操作
-- 好select id from t where num=100*2-- 坏select id from where num/2=100
这将导致引擎放弃使用索引而进行全表扫描
7. 应尽量避免在 where 子句中对字段进行 null 值判断
-- 好select id from t where num=0-- 坏select id from t where num is null
对字段进行 null 值判断,将导致引擎放弃使用索引而进行全表扫描。可以在建表时添加Not
Null 约束。
8.应尽量避免在 where 子句中使用 or 来连接条件
-- 好select id from t where num=10union allselect id from t where num=20-- 坏select id from t where num=10 or num=20
使用 or 来连接条件,将导致引擎放弃使用索引而进行全表扫描
9.很多时候用 exists 代替 in 是一个好的选择
-- 好select num from a where exists(select 1 from b where num=a.num)-- 坏select num from a where num in (select num from b)-- 好select * from orders where customer_name not exists(select customer_namefrom customer)-- 坏select * from orders where customer_name not in(select customer_namefrom customer)
10.如果在 where 子句中使用参数,也会导致全表扫描
-- 好select id from t with(index(索引名)) where num=@num-- 坏select id from t where num=@num
因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行
时;它必须在编译时进行选择。然 而,如果在编译时建立访问计划,变量的值还是未知的,
因而无法作为索引选择的输入项