mysql出现锁表的原因(导致MySQL做全表扫描的几种情况)
mysql出现锁表的原因
导致MySQL做全表扫描的几种情况这两天看到了两种可能会导致全表扫描的sql,这里给大家看一下,希望可以避免踩坑:
情况1:
强制类型转换的情况下,不会使用索引,会走全表扫描。
举例如下:
首先我们创建一个表
|
create table `test` ( `id` int (11) not null auto_increment, `age` int (11) default null , `score` varchar (20) not null default '' , primary key (`id`), key `idx_score` (`score`) ) engine=innodb auto_increment=12 default charset=utf8 |
我们可以看到,这个表有三个字段,其中两个int类型,一个varchar类型。varchar类型的字段score是一个索引,而id是主键。
然后我们给这个表里面插入一些数据,插入数据之后的表如下:
|
mysql:yeyztest 21:43:12>> select * from test; + ----+------+-------+ | id | age | score | + ----+------+-------+ | 1 | 1 | 5 | | 2 | 2 | 10 | | 5 | 5 | 25 | | 8 | 8 | 40 | | 9 | 2 | 45 | | 10 | 5 | 50 | | 11 | 8 | 55 | + ----+------+-------+ 7 rows in set (0.00 sec) |
这个时候,我们使用explain语句来查看两条sql的执行情况,分别是:
|
explain select * from test where score = '10' ; explain select * from test where score =10; |
结果如下:
|
mysql:yeyztest 21:42:29>>explain select * from test where score = '10' ; + ----+-------------+-------+------------+------+---------------+-----------+---------+-------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | extra | + ----+-------------+-------+------------+------+---------------+-----------+---------+-------+------+----------+-------+ | 1 | simple | test | null | ref | idx_score | idx_score | 62 | const | 1 | 100.00 | null | + ----+-------------+-------+------------+------+---------------+-----------+---------+-------+------+----------+-------+ 1 row in set , 1 warning (0.00 sec) mysql:yeyztest 21:43:06>>explain select * from test where score =10; + ----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | extra | + ----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+ | 1 | simple | test | null | all | idx_score | null | null | null | 7 | 14.29 | using where | + ----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+ 1 row in set , 3 warnings (0.00 sec) |
可以看到,如果我们使用的是varchar类型的值,那么结果中扫描的行数rows就是1,而当我们使用的是整数值10的时候,扫描行数变为了7,证明,如果出现了强制类型转换,则会导致索引失效。
情况2:
反向查询不能使用索引,会导致全表扫描。
创建一个表test1,它的主键是score,然后插入6条数据:
|
create table `test1` ( `score` varchar (20) not null default '' , primary key (`score`) ) engine=innodb default charset=utf8 mysql:yeyztest 22:09:37>> select * from test1; + -------+ | score | + -------+ | 111 | | 222 | | 333 | | 444 | | 555 | | 666 | + -------+ 6 rows in set (0.00 sec) |
当我们使用反向查找的时候,不会使用到索引,来看下面两条sql:
|
explain select * from test1 where score= '111' ; explain select * from test1 where score!= '111' ; |
|
mysql:yeyztest 22:13:01>>explain select * from test1 where score= '111' ; + ----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | extra | + ----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+ | 1 | simple | test1 | null | const | primary | primary | 62 | const | 1 | 100.00 | using index | + ----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+ 1 row in set , 1 warning (0.00 sec) mysql:yeyztest 22:13:08>>explain select * from test1 where score!= '111' ; + ----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | extra | + ----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+ | 1 | simple | test1 | null | index | primary | primary | 62 | null | 6 | 100.00 | using where ; using index | + ----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+ 1 row in set , 1 warning (0.00 sec) |
可以看到,使用!=作为条件的时候,扫描的行数是表的总记录行数。因此如果想要使用索引,我们就不能使用反向匹配规则。
情况3:
某些or值条件可能导致全表扫描。
首先我们创建一个表,并插入几条数据:
|
create table `test4` ( `id` int (11) default null , ` name ` varchar (20) default null , key `idx_id` (`id`) ) engine=innodb default charset=utf8 1 row in set (0.00 sec) mysql --dba_admin@127.0.0.1:yeyztest 22:23:44>>select * from test4; + ------+------+ | id | name | + ------+------+ | 1 | aaa | | 2 | bbb | | 3 | ccc | | 4 | yeyz | | null | yeyz | + ------+------+ 5 rows in set (0.00 sec) |
其中表test4包含两个字段,id字段是一个索引,而name字段是varchar类型,我们来看下面三个语句的扫描行数:
|
explain select * from test4 where id=1; explain select * from test4 where id is null ; explain select * from test4 where id=1 or id is null ; |
|
mysql:yeyztest 22:24:12>>explain select * from test4 where id is null ; + ----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-----------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | extra | + ----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-----------------------+ | 1 | simple | test4 | null | ref | idx_id | idx_id | 5 | const | 1 | 100.00 | using index condition | + ----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-----------------------+ 1 row in set , 1 warning (0.00 sec) mysql:yeyztest 22:24:17>>explain select * from test4 where id=1; + ----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | extra | + ----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-------+ | 1 | simple | test4 | null | ref | idx_id | idx_id | 5 | const | 1 | 100.00 | null | + ----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-------+ 1 row in set , 1 warning (0.00 sec) mysql:yeyztest 22:24:28>>explain select * from test4 where id=1 or id is null ; + ----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | extra | + ----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+ | 1 | simple | test4 | null | all | idx_id | null | null | null | 5 | 40.00 | using where | + ----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+ 1 row in set , 1 warning (0.00 sec) |
可以看到单独使用id=1和id is null,都只会扫描一行记录,而使用or将二者连接起来就会导致扫描全表而不使用索引。
简单总结一下:
1.强制类型转换的情况下,不会使用索引,会走全表扫描
2.反向查询不能使用索引,会导致全表扫描。
3.某些or值条件可能导致全表扫描。
以上就是导致mysql做全表扫描的几种情况的详细内容,更多关于mysql 全表扫描的资料请关注开心学习网其它相关文章!
原文链接:https://mp.weixin.qq.com/s/5G1xGrxb6ii_gpcWE1hC6A
- MySQL 8.0.19安装详细教程(windows 64位)(MySQL 8.0.19安装详细教程windows 64位)
- mysql性能怎么看(是什么影响了 MySQL 的性能?)
- navicat15.0.28注册码(Navicat for MySQL 11注册码激活码汇总)
- mysql数据库死锁原理(MySQL数据库锁机制原理解析)
- mysql批量生成uuid(一种简单的ID生成策略: Mysql表生成全局唯一ID的实现)
- mysql常用的sql语句大全(mysql建表常用的sql语句汇总)
- centos7离线安装mysql5.7(CentOS7.5 安装MySql的教程)
- MySql 中IFNULL、ISNULL和NULLIF
- mysql提高分页效率(MySQL优化教程之超大分页查询)
- idea向数据库中插入中文报错(Idea连接MySQL数据库出现中文乱码的问题)
- python中怎么连接mysql(python远程连接MySQL数据库)
- phpstudy的mysql无法启动(Windows系统下解决PhPStudy MySQL启动失败问题)
- Mysql官方性能测试工具mysqlslap的使用简介(Mysql官方性能测试工具mysqlslap的使用简介)
- mysql权限收回(MySQL如何利用DCL管理用户和控制权限)
- mysql快速创建索引(MySQL创建高性能索引的全步骤)
- mysql添加数据很慢(mysql如何优化插入记录速度)
- 乡村爱情15 宋晓峰怀疑自己孩子,腾飞与姜奶奶亲子鉴定出结果(宋晓峰怀疑自己孩子)
- 《乡村爱情13》开播,新版刘能以假乱真,编剧思维进入瓶颈(新版刘能以假乱真)
- 当年的 白洋淀战神 练肌肉 嘎子哥也成为行走的荷尔蒙(当年的白洋淀战神)
- 肌肉小子陈康, 亚洲巨兽 黄哲勋,哪个才是你的菜(肌肉小子陈康亚洲巨兽)
- 新闻周刊 青岛网红 赵厂长 编段子一箩筐输出快乐,陪父亲十二载勇斗病魔(新闻周刊青岛网红)
- 44岁夏雨演谋女郎爸,大其24岁却看不出,互动不怕袁泉吃醋(44岁夏雨演谋女郎爸)
热门推荐
- docker是k8s 编排必备容器工具(Docker部署ELK7.3.0日志收集服务最佳实践)
- mysql的字符串截取函数(MySQL实现字符串的拼接,截取,替换,查找位置的操作)
- 启动sqlserver代理服务失败(SQL Server代理服务无法启动怎么办)
- js实现自动轮播(原生js封装无缝轮播功能)
- python字典键对应的值(Python 互换字典的键值对实例)
- dedecms添加代码(dedecms内容页调用栏目链接和栏目名称的方法)
- shell多台机器配置文件比对(如何使用shell在多服务器上批量操作)
- ideadocker调试(Idea部署远程Docker并配置文件)
- 如何使用自定义discuz代码(Apache,IIS下Discuz x1.5伪静态设置方法)
- python实现将txt转化为excel(python实现Excel文件转换为TXT文件)
排行榜
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9