Mysql如何优化查询速度

 更新时间:2023年08月30日 08:48:16   作者:哇~是小菜呀  
这篇文章主要介绍了Mysql如何优化查询速度问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

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

当查询结果需要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: = 1;
set @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:= 0;
select actor_id,@rownum:=@rownum+1 as rownum from actor limit 10;

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • MySQL 数据库的对库的操作及其数据类型

    MySQL 数据库的对库的操作及其数据类型

    这篇文章主要介绍了MySQL 数据库的对库的操作及其数据类型,下面文字围绕数据库的对库的操作及其数据类型的相关资料展开详细介绍,需要的小伙伴可以参考一下,希望对你有所帮助
    2021-12-12
  • mysql jdbc连接步骤及常见参数

    mysql jdbc连接步骤及常见参数

    这篇文章主要介绍了mysql jdbc连接步骤及常见参数,需要的朋友可以参考下
    2015-09-09
  • MySQL修改账号密码方法大全(小结)

    MySQL修改账号密码方法大全(小结)

    这篇文章主要介绍了MySQL修改账号密码方法大全(小结),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • mysql正则函数REGEXP使用及说明

    mysql正则函数REGEXP使用及说明

    本文介绍了MySQL中的正则表达式匹配操作符REGEXP及其在不同版本中的使用方法和差异,包括基本语法、支持的元字符与量词、版本差异及常用函数如REGEXP_LIKE、REGEXP_SUBSTR、REGEXP_REPLACE等
    2026-05-05
  • MYSQL必知必会读书笔记第三章之显示数据库

    MYSQL必知必会读书笔记第三章之显示数据库

    MySQL是一种开放源代码的关系型数据库管理系统(RDBMS),MySQL数据库系统使用最常用的数据库管理语言--结构化查询语言(SQL)进行数据库管理。接下来通过本文给大家介绍MYSQL必知必会读书笔记第三章之显示数据库,感兴趣的朋友参考下吧
    2016-05-05
  • MySQL指令进行分页显示的使用示例

    MySQL指令进行分页显示的使用示例

    本文主要介绍了MySQL指令进行分页显示的使用示例,主要使用LIMIT命令来实现,具有一定的参考价值,感兴趣的可以了解一下
    2023-11-11
  • MySQL8.0新特性之不可见主键的使用

    MySQL8.0新特性之不可见主键的使用

    MySQL8.0.30版本引入不可见主键,它可以自动为没有显式指定主键的 InnoDB 表创建一个不可见的主键,本文主要介绍了MySQL8.0新特性之不可见主键的使用,具有一定的参考价值,感兴趣的可以了解一下
    2024-04-04
  • mysql之explain使用详解(分析索引)

    mysql之explain使用详解(分析索引)

    在这里对explain的各个字段进行详细的分析,来帮助大家分析自己所写的sql是否最佳的使用了索引,需要的朋友可以参考下
    2018-01-01
  • mysql binlog(二进制日志)查看方法

    mysql binlog(二进制日志)查看方法

    在本篇文章里小编给大家分享了关于mysql binlog(二进制日志)查看方法,有需要的朋友们学习下。
    2019-01-01
  • 聊聊MySQL的COUNT(*)的性能

    聊聊MySQL的COUNT(*)的性能

    这篇文章主要介绍了聊聊MySQL的COUNT(*)的性能,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11

最新评论