案例来自《MySQL管理之道》
not in 子查询优化
not in 后跟子查询
select
SQL_NO_CACHE count(*)
from
test1
where
id not in(
select
id
from
test2
)
用left join 关联查询
select
SQL_NO_CACHE
from
test1
left join
test2
on
test1.id=test2.id
where test2.id is null
用关联查询的方式优于子查询
匹配模式 like ‘%xxx%’ 优化
‘xxx%’ 可以用到索引,’%xxx%’ 不能用到索引,所以尽量用 ‘xxx%’
如果一定要用索引还有模糊查询,可以如下举例:
select
count(*)
from
artist a
join (
select
artist_id
from
artist
where
name like '%xxx%'
) b
on
a.artist_id=b.artist_id
其中,artist_id是artist表的索引
limit分页优化
原始查询
select
SQL_NO_CACHE *
from
test1
order by
id
limit 99999, 10
上面的sql虽然用到了索引,但是第一行开始就定位到了99999行,再扫描后10行,相当于进行了一个全表扫描。
优化如下:
select
SQL_NO_CACHE *
from
test1
where
id >= 100000
order by id
limit 10
这样效率有明显的提升
还有一种通过表内连接方式来优化
select
SQL_NO_CACHE *
from
test1 a
join (
select
SQL_NO_CACHE *
from
test1 b
order by id
limit 99999,1
)b
on
a.id >= b.id
limit 10
先取出99999条后的一条,再取出后面的10条,也可以提高效率
count(*) 怎么优化
- count(辅助索引) 快于 count(*)
count(distinct)效果更好
- or 条件优化
普通使用 or 是不会用到索引的,如:
- or 条件优化
select
*
from
test1
where
name='a'
or
age > 17
可以使用 union all 优化:
select
*
from
test1
where
name='a'
union all
select
*
from
test1
where
age > 17
这样的查询就可以利用索引加快查询
ON DUPLICATE KEY UPDATE 用法
这是mysql中非常高效的主键冲突处理判断,冲突执行update,不冲突则执行insert,如:
insert into
gg
values
(
3,
'd'
)
ON DUPLICATE KEY UPDATE
id = id+1
这句sql的意思是插入数据时如果主键id的值 3 已经存在冲突了,那么数据库中的3会更新成4
不必要的排序
子查询中没有必要排序就不要排序
不必要的嵌套select查询
能用关联用关联查询