当前位置:网站首页>Mysql优化查询速度

Mysql优化查询速度

2022-06-24 19:19:00 哇~是小菜呀

对于需要排序的字段使用索引

当查询结果需要order by的时候,可以在order by 的字段加上索引,因为索引已经排列好顺序了,所以可以更快的完成排序,而不需要每次对查询结果进行排序,耗费大量内存和时间。

尽量使用union all 而不是union

除非确实需要服务器消除重复的行,否则一定要使用union all,因此没有all关键字,mysql会在查询的时候给临时表加上distinct的关键字,这个操作的代价很高。

exists 和 join如何选择

join
需要多张表进行连接,并且需要查询的字段不是来自一张表的,比如a.name,b.dept 这种情况需要使用join

exists
要查询的字段都在a表,但是有一个很复杂的条件,可以使用exists子句来描述后面复杂的查询条件

现实情况中,exists用的比较少,大家都想不起来用哈哈哈哈

and优先级高于or

比如一个查询,需要筛选名字为AAA,并且年龄为20或者21的数据,sql语句如下,

select * from tab_a where name = 'AAA' and age = 20 or age = 21;

查询结果会变为
name = ‘AAA’ and age = 20的数据和
age=21的数据,查询结果错误。需要改造sql语句如下:

select * from tab_a where name = 'AAA' and (age=20 or age=21)

尽量不要join超过三张表

单表索引控制在5个以内

索引越多,b+树越大,会影响插入、删除效率

组合索引的字段不能超过5个

key(a,b,c,d,e)不宜过多,由于最左匹配原则,如果查询的列在右边,那个查询的时候需要补充前几列的条件
并且,索引的长度过长会使b+树偏大,消耗存储空间

limit优化

limit语法如下:

从第一行开始返回,返回前n条数据

select * from tab_a order by a limit n

从第m行数据开始返回,返回后面的n条数据

select * from tab_a order by a limit m,n;

例如,如果要查询tab_a表的第3页,每页10条数据,可以如下进行:

select * from tab_a order by a limit 20,10;

limit相当于是一个指针,在遍历完前面的数据之后,找到需要的数据,再返回给用户,如果数据量非常大时,例如limit(25000,20),会扫描全表,limit效率会变得非常低,这种情况的调优方式如下:
使用索引列子查询进行调优

调优前:

select film_id,description from film order by title limit 50,5

调优后:

explain select film.film_id,film.description from film inner join (select film_id from film order by title limit 1500,5) as lim using(film_id);

调优后,避免了limit指针扫描全表获取数据,而是先使用主键id进行查询,id在查询时,只会使用b+树去访问到数据,不需要对整张表进行io,速度更快,并且不需要回表,再将查询结果和主表做join,返回数据。

避免向数据库查询不必要的数据

数据库服务层会查询所有的结果,形成结果集,获取前面n条数据后关闭结果集,为了避免形成不必要的结果集,可以使用limit提升速率
例如:

select * from tab_a where id = 'sdasafdf676d8' limit 1;

避免使用select *

如果需要不断的重复查询,使用redis进行缓存

尽量使用关联代替子查询

因为子查询在执行的过程中会将子查询结果放到临时表,增加了io,对内存的开销较大,而join可以利用join buffer进行快速匹配,运行速度较快。

group by, distinct, order by 时推荐使用索引列

使用自定义变量

什么是自定义变量?

set @one= 1set @current_actor: = select actor_id from actor order by last_update desc limit 1 ;
set @last_week :=current_date-interval 1 week;
-- 使用如下
select count(1) from actor where last_update < @last_week;
select * from message where actor_id = @current_actor;

自定义变量使用场景:

  • 优化排序
set @rownum= 0select actor_id,@rownum:=@rownum+1 as rownum from actor limit 10;
原网站

版权声明
本文为[哇~是小菜呀]所创,转载请带上原文链接,感谢
https://blog.csdn.net/weixin_44712778/article/details/125316092