1.使用连接(JOIN)来代替子查询(Sub-Queries)
2.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描
3.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描
如:select id from t where num is null
可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:
select id from t where num=0
4.应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描
如:select id from t where num=10 or num=20
可以这样查询:select id from t where num=10
union all
select id from t where num=20
5.尽量避免两端模糊匹配like%***%
6.in 和 not in 也要慎用,否则会导致全表扫描,如:
select id from t where num in(1,2,3)
对于连续的数值,能用 between 就不要用 in 了:
select id from t where num between 1 and 3
7.应尽量避免在 where 子句中对字段进行表达式或函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:
select id from t where num/2=100 应改为:select id from t where num=100*2
如:select id from t where substring(name,1,3)='abc'--name以abc开头的id
select id from t where datediff(day,createdate,'2005-11-30')=0--'2005-11-30'生成的id
应改为:select id from t where name like 'abc%'
select id from t where createdate>='2005-11-30' and createdate<'2005-12-1'
8.尽量避免在where子句中使用in,notin或者having,使用exists,notexists代替:
select num from a where num in(select num from b)
替换:select num from a where exists(select 1 from b where num=a.num)
9.使用selectcount(*) 统计行数
10.尽量少运算
11.尽量早过滤
12.能用inner join连接尽量使用inner join连接
13.使用JOIN时候,应该用小的结果驱动打的结果(left join 左边表结果尽量小,如果有条件应该放到左边先处理,right join同理反向),同事尽量把牵涉到多表联合的查询拆分多个query(多个表查询效率低,容易锁表和阻塞)。如:
Select * from A left join B ona.id=B.ref_id where B.ref_id>10;
可以优化为:select * from (select * from A wehre id >10) T1 left join B onT1.id=B.ref_id;
14.尽量用union all 代替union