原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11429037.html

1. 无索引、索引失效导致慢查询

如果在一张几千万数据的表中以一个没有索引的列作为查询条件,大部分情况下查询会非常耗时,这种查询毫无疑问是一个慢SQL查询。所以对于大数据量的查询,需要建立适合的索引来优化查询。

虽然很多时候建立了索引,但在一些特定的场景下,索引还有可能会失效,所以索引失效也是导致慢查询的主要原因之一。

2. 锁等待

常用的存储引擎有 InnoDB 和 MyISAM,前者支持行锁和表锁,后者只支持表锁

如果数据库操作是基于表锁实现的,试想下,如果一张订单表在更新时,需要锁住整张表,那么其它大量数据库操作(包括查询)都将处于等待状态,这将严重影响到系统的并发性能。

这时,InnoDB 存储引擎支持的行锁更适合高并发场景。但在使用 InnoDB 存储引擎时,要特别注意行锁升级为表锁的可能。在批量更新操作时,行锁就很可能会升级为表锁。

MySQL认为如果对一张表使用大量行锁,会导致事务执行效率下降,从而可能造成其它事务长时间锁等待和更多的锁冲突问题发生,致使性能严重下降,所以MySQL会将行锁升级为表锁。还有,行锁是基于索引加的锁,如果在更新操作时,条件索引失效,那么行锁也会升级为表锁。

因此,基于表锁的数据库操作,会导致SQL阻塞等待,从而影响执行速度。在一些更新操作(insert\update\delete)大于或等于读操作的情况下,MySQL不建议使用MyISAM存储引擎。

除了锁升级之外,行锁相对表锁来说,虽然粒度更细,并发能力提升了,但也带来了新的问题,那就是死锁。因此,在使用行锁时,要注意避免死锁。

3. 不恰当的SQL语句

使用不恰当的SQL语句也是慢SQL最常见的诱因之一。例如,习惯使用<SELECT *>,<SELECT COUNT(*)> SQL语句,在大数据表中使用<LIMIT M,N>分页查询,以及对非索引字段进行排序等等。

Note:

慢查询问题,很可能是没有利用好索引导致的,MySQL 内置的 explain 命令,可以帮助确认查询语句是否利用了索引。

Column name Description
id Sequence number that shows in which order tables are joined.
select_type What kind of SELECT the table comes from.
table Alias name of table. Materialized temporary tables for sub queries are named <subquery#>
type How rows are found from the table (join type).
possible_keys keys in table that could be used to find rows in the table
key The name of the key that is used to retrieve rows. NULL is no key was used.
key_len How many bytes of the key that was used (shows if we are using only parts of the multi-column key).
ref The reference that is used to as the key value.
rows An estimate of how many rows we will find in the table for each key lookup.
Extra Extra information about this join.

其中 type 表示 表中找到所需行的方式

Value Description
ALL A full table scan is done for the table (all rows are read). This is bad if the table is large and the table is joined against a previous table! This happens when the optimizer could not find any usable index to access rows.
const There is only one possibly matching row in the table. The row is read before the optimization phase and all columns in the table are treated as constants.
eq_ref A unique index is used to find the rows. This is the best possible plan to find the row.
fulltext A fulltext index is used to access the rows.
index_merge A 'range' access is done for for several index and the found rows are merged. The key column shows which keys are used.
index_subquery This is similar as ref, but used for sub queries that are transformed to key lookups.
index A full scan over the used index. Better than ALL but still bad if index is large and the table is joined against a previous table.
range The table will be accessed with a key over one or more value ranges.
ref_or_null Like 'ref' but in addition another search for the 'null' value is done if the first value was not found. This happens usually with sub queries.
ref A non unique index or prefix of an unique index is used to find the rows. Good if the prefix doesn't match many rows.
system The table has 0 or 1 rows.
unique_subquery This is similar as eq_ref, but used for sub queries that are transformed to key lookups

常用的类型有: ALL, index, range, ref, eq_ref, const, system, NULL(从左到右,性能从差到好)

  • ALL:Full Table Scan, MySQL将遍历全表以找到匹配的行

  • index: Full Index Scan,index与ALL区别为index类型只遍历索引树

  • range: 只检索给定范围的行,使用一个索引来选择行

  • ref: 表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值

  • eq_ref: 类似ref,区别就在使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配,简单来说,就是多表连接中使用primary key或者 unique key作为关联条件

  • const、system: 当MySQL对查询某部分进行优化,并转换为一个常量时,使用这些类型访问。如将主键置于where列表中,MySQL就能将该查询转换为一个常量,system是const类型的特例,当查询的表只有一行的情况下,使用system

  • NULL: MySQL在优化过程中分解语句,执行时甚至不用访问表或索引,例如从一个索引列里选取最小值可以通过单独索引查找完成。

SQL性能优化目标

Reference

https://time.geekbang.org/column/article/113440

https://mariadb.com/kb/en/library/show-processlist/

https://mariadb.com/kb/en/library/thread-command-values/

https://mariadb.com/kb/en/library/explain/

MySQL慢SQL语句常见诱因的更多相关文章

  1. MySQL中SQL语句常见优化策略

    1.避免全表扫描 对查询进行优化,应尽量避免全表扫描,首先应考虑在where 及order by 涉及的列上建立索引. 2.避免判断null 值 应尽量避免在where 子句中对字段进行null 值判 ...

  2. mysql优化sql语句

    mysql优化sql语句   常见误区   www.2cto.com   误区1:   count(1)和count(primary_key) 优于 count(*)   很多人为了统计记录条数,就使 ...

  3. MySQL数据库SQL语句基本操作

    一.用户管理: 创建用户: create user '用户名'@'IP地址' identified by '密码'; 删除用户: drop user '用户名'@'IP地址'; 修改用户: renam ...

  4. php面试专题---MySQL常用SQL语句优化

    php面试专题---MySQL常用SQL语句优化 一.总结 一句话总结: 原理,万变不离其宗:其实SQL语句优化的过程中,无非就是对mysql的执行计划理解,以及B+树索引的理解,其实只要我们理解执行 ...

  5. Mysql常用sql语句(20)- 子查询重点知识

    测试必备的Mysql常用sql语句系列 https://www.cnblogs.com/poloyy/category/1683347.html 子查询语句可以嵌套在 sql 语句中任何表达式出现的位 ...

  6. Mysql常用sql语句(22)- insert 插入数据

    测试必备的Mysql常用sql语句系列 https://www.cnblogs.com/poloyy/category/1683347.html 前言 终于讲完基础的查询语句了...这篇讲的就是插入数 ...

  7. Mysql常用sql语句(3)- select 查询语句基础使用

    测试必备的Mysql常用sql语句系列 https://www.cnblogs.com/poloyy/category/1683347.html 前言 针对数据表里面的每条记录,select查询语句叫 ...

  8. Mysql常用sql语句(4)- distinct 去重数据

    测试必备的Mysql常用sql语句系列 https://www.cnblogs.com/poloyy/category/1683347.html 前言 我们使用select进行数据查询时是会返回所有匹 ...

  9. Mysql 常用 SQL 语句集锦

    Mysql 常用 SQL 语句集锦 基础篇 //查询时间,友好提示 $sql = "select date_format(create_time, '%Y-%m-%d') as day fr ...

随机推荐

  1. Spring----组合注解与元注解

    1.概述 1.1.Spring提供了大量的注解, 尤其是相同的注解用到各个类中,会相当的啰嗦: 1.2.元注解: 可以注解到别的注解上的注解: 组合注解: 被注解注解的注解称为 组合注解: 组合注解  ...

  2. 英语单词Repository

    Repository 来源——查看仓库的名称内容 [root@centos7 ~]# yum repolist Loaded plugins: fastestmirror Repository bas ...

  3. Java Web学习总结(9)学习总结-JSTL

    一,JSTL概述 JSTL(JSP Standard Tag Library),JSP标准标签库,可以嵌入在jsp页面中使用标签的形式完成业务逻辑等功能.jstl出现的目的同el一样也是要代替jsp页 ...

  4. kafka-server.properties

    # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreement ...

  5. ADSL(Asymmetric Digital Subscriber Loop)技术

    上行带宽,下行带宽 宽带上行下行是指一般ADSL上网方式上行与下行速率,上行就是从电脑上传的速度,下行就是从网络上的主机下载速度,一般下行速率比较高! ADSL(Asymmetric Digital ...

  6. 二次封装arcgis的timeslider

    arcgis的timeslider是对dojo slider二次封装,项目需要,所有Map用统一样式的slider,所以写了一个common的dojo class,统一调用生成slider,作为对ti ...

  7. html常用代码

    <marquee width="70%" scrollamount="2">大家好</marquee>    // 大家好 字符从左到右 ...

  8. git 多个远程仓库

    有时候一个git项目需要使用多个远程库,如:测试环境+生产环境,国内加国外等 项目根目录下修改 .git/config 文件 vim .git/config 新增远程一个远程仓库   并为其命名 :如 ...

  9. C++内存修改器开源代码

    我们玩单机游戏时,游戏难度可能过大, 或者游戏已经比较熟练,想要增加游戏的玩法,这时候可以使用修改器. 内存式游戏修改器主要对游戏内存修改 修改时有两种方式,一是定时对内存数值进行修改.实现类似锁定的 ...

  10. urllib爬取实例

    #汉字转码.多个参数拼接 from urllib import request base_url = "http://www.baidu.com/s?" content = inp ...