【mysql】mysql优化策略

案例来自《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(*) 怎么优化

  1. count(辅助索引) 快于 count(*)
  2. count(distinct)效果更好

    扫描二维码关注公众号,回复: 161163 查看本文章
    • 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查询

能用关联用关联查询

用where子句替换having子句

猜你喜欢

转载自blog.csdn.net/ColdFireMan/article/details/80210966