以前在网上看了一些资料,有些人说话不严谨,导致一直被误导,最近在实际开发中发现一些结论有问题,因此特地整理了一下,防止下次继续犯错。

以下前提是有对这个字段建立索引(简直废话,没建的肯定不会使用索引啊)

首先建立一张表:

CREATE DATABASE `test_lkc` CHARATER SET utf8 COLLATE utf8_general_ci;

CREATE TABLE `students` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`stuno` varchar(9) NOT NULL DEFAULT '' COMMENT '学号',
`name` varchar(64) NOT NULL DEFAULT '' COMMENT '姓名',
`major` varchar(255) NOT NULL DEFAULT '' COMMENT '专业',
`class` int(10) unsigned NOT NULL DEFAULT '' COMMENT '班级',
`id_card` varchar(18) NOT NULL DEFAULT '' COMMENT '身份证号码',
`memo` varchar(255) NOT NULL DEFAULT '' COMMENT '备注',
PRIMARY KEY (`id`),
UNIQUE KEY `stuno` (`stuno`) USING BTREE,
UNIQUE KEY `id_card` (`id_card`) USING BTREE,
KEY `major_class` (`major`,`class`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;

数据我是用php批量生成的

<?php
$pdo = new PDO("mysql:host=127.0.0.1;dbname=test_lkc","root","root");
//数据
$addList = [];
$majorList = ['CN','EN','JP','KO','RU','SV','CU','DE','FR','RO'];
$prefixList = ['A','B','C','D','E','F','G','H','I','J'];
for ($i=0;$i<1000;$i++){
$row = [];
$id = sprintf('%03d',$i);
$row['stuno'] = $prefixList[$i/100] . '2017' . sprintf('%04d',$i + 1);
$row['name'] = $prefixList[$id[0]] . $prefixList[$id[1]] . $prefixList[$id[2]];
$row['major'] = $majorList[$id[0]];
$row['class'] = $i%3 + 1;
$row['id_card'] = '320106194910290' . $id; $addList[] = $row;
} $res = addAll($pdo,$addList);
var_dump($res); function addAll($pdo,$addList){
//字段
$sql = "INSERT INTO `students` (`" . implode("`,`",array_keys($addList[0])) . "`) VALUES ";
//拼接SQL语句
foreach ($addList as $value){
$sql .= "('";
$sql .= implode("','", $value);
$sql .= "'),";
}
$sql = rtrim($sql,','); $res = $pdo->exec($sql);
return $res ? $res : $pdo->errorInfo();
}

1.IN到底会不会使用索引?

答:会!

explain select * from students where id_card IN ('','');

如果没有走索引,那么可能是你的使用姿势不对,比如

(1)字符串类型没有加单引号,

explain select * from students where id_card IN (320106194910290999,320106194910290998);

(2)或者mysql认为使用全表扫描要比使用索引快(我自己遇到的是数据太少或者查询出来的结果很多的时候会出现,比如图中预估的行数是952),则不使用索引

explain select * from students where major IN ('RO','CN');

2.OR到底会不会使用索引?

答:会!

explain select * from students where id = 1 or stuno = 'A20170002';

如果没有走索引,那么肯定又是你的使用姿势不对,比如说

(1)两个条件里面其中一个字段没有建立索引;

explain select * from students where id = 1 or name = 'AAB';

(2)字符串类型的没有加单引号;

explain select * from students where id = 1 or id_card = 320106194910290999;

(3)mysql认为使用全表扫描要比使用索引快,则不使用索引

explain select * from students where id = 1 or major = 'CN';

3.LIKE会不会使用索引

答:LIKE 'xxx%'会;

(1)LIKE'%xxx'或者LIKE'%xxx%'不会

explain select * from students where stuno like 'A2017%';

explain select * from students where stuno like '%20170001';

(2)mysql认为使用全表扫描要比使用索引快,则不使用索引

explain select * from students where major like 'C%';

说来惭愧,我自己被错误的结论误导了那么久,希望大家引以为戒,网络上的答案也不一定就是对的,还是要自己多试试。实践才是检验真理的唯一标准

在查询语句前面加explain ,根据type和key来分析查询到底有没有使用索引

type排行:
连接类型
system 表只有一行
const 表最多只有一行匹配,通用用于主键或者唯一索引比较时
eq_ref 每次与之前的表合并行都只在该表读取一行,这是除了system,const之外最好的一种,
特点是使用=,而且索引的所有部分都参与join且索引是主键或非空唯一键的索引
ref 如果每次只匹配少数行,那就是比较好的一种,使用=或<=>,可以是左覆盖索引或非主键或非唯一键
fulltext 全文搜索
ref_or_null 与ref类似,但包括NULL
index_merge 表示出现了索引合并优化(包括交集,并集以及交集之间的并集),但不包括跨表和全文索引。
这个比较复杂,目前的理解是合并单表的范围索引扫描(如果成本估算比普通的range要更优的话)
unique_subquery 在in子查询中,就是value in (select...)把形如“select unique_key_column”的子查询替换。
PS:所以不一定in子句中使用子查询就是低效的!
index_subquery 同上,但把形如”select non_unique_key_column“的子查询替换
range 常数值的范围
index a.当查询是索引覆盖的,即所有数据均可从索引树获取的时候(Extra中有Using Index);
b.以索引顺序从索引中查找数据行的全表扫描(无 Using Index);
c.如果Extra中Using Index与Using Where同时出现的话,则是利用索引查找键值的意思;
d.如单独出现,则是用读索引来代替读行,但不用于查找
all 全表扫描

关于MySQL IN LIKE OR使用索引的问题的更多相关文章

  1. MySQL基础(四)——索引

    MySQL基础(四)--索引

  2. MySQL优化技巧之三(索引操作和查询优化)

    对于任何DBMS,索引都是进行优化的最主要的因素.对于少量的数据,没有合适的索引影响不是很大,但是,当随着数据量的增加,性能会急剧下降.如果对多列进行索引(组合索引),列的顺序非常重要,MySQL仅能 ...

  3. MySQL 数据库性能优化之索引优化

    接着上一篇 MySQL 数据库性能优化之表结构,这是 MySQL数据库性能优化专题 系列的第三篇文章:MySQL 数据库性能优化之索引优化 大家都知道索引对于数据访问的性能有非常关键的作用,都知道索引 ...

  4. Mysql优化之创建高性能索引(一)

    1.索引基础 索引对于良好的性能非常关键.尤其是当表中的数据量越来越大时,索引对性能的影响愈发重要.但是不恰当的索引随着数据量的增加,也会使整个数据库的性能下降. 举个例子: ; 如果在id上建立索引 ...

  5. MySQL系列(三)---索引

    MySQL系列(三)---索引 前言:如果有疏忽或理解不当的地方,请指正. 目录 MySQL系列(一):基础知识大总结 MySQL系列(二):MySQL事务 MySQL系列(三):索引 什么是索引 如 ...

  6. mysql进阶(二十七)数据库索引原理

    mysql进阶(二十七)数据库索引原理 前言   本文主要是阐述MySQL索引机制,主要是说明存储引擎Innodb.   第一部分主要从数据结构及算法理论层面讨论MySQL数据库索引的数理基础.    ...

  7. (转)Mysql哪些字段适合建立索引

    工作中处理数据时,发现某个表的数据达近亿条,所以要为表建索引提高查询性能,以下两篇文章总结的很好,记录一下,以备后用. 数据库建立索引常用的规则如下: 1.表的主键.外键必须有索引: 2.数据量超过3 ...

  8. Mysql哪些字段适合建立索引

    数据库建立索引常用的规则如下: 1.表的主键.外键必须有索引: 2.数据量超过300的表应该有索引: 3.经常与其他表进行连接的表,在连接字段上应该建立索引: 4.经常出现在Where子句中的字段,特 ...

  9. 关于MySql数据库主键及索引的区别

    一.什么是索引?索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存.如果没有索引,执行查询时MySQL必须从第一个记录开始扫描整个表的所有记录,直至找到符合要求的记录.表里 ...

  10. MySQL 第五篇:索引原理与慢查询优化

    一 介绍 为何要有索引? 一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,在生产环境中,我们遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,因此对查询语句 ...

随机推荐

  1. css3@media实现原理

    window.matchMedia() 基本用法 window.matchMedia方法用来检查CSS的mediaQuery语句.各种浏览器的最新版本(包括IE 10+)都支持该方法,对于不支持该方法 ...

  2. 深入浅出写一个多级异步回调从基础到Promise实现的Demo

    今天一时兴起,写了一个渐进升级的异步调用demo,记录一下. 1. 最基础的同步调用 //需求:f2在f1之后执行,且依赖f1的返回值.如下: function f1(){ var s="1 ...

  3. 第三篇:异步请求遇上for循环怎么做

    场景:读取Excel数据(地名),发送请求到百度地图,从返回的json格式数据取出坐标数据(逗号隔开的两个float型数值),拼接成了分号隔开的一个字符串data,接下来需要利用“百度坐标转换API” ...

  4. Java 12 正式发布,8大新特性!

    自 2 月 7 日开始,Java/JDK 12 就进入了 RC 阶段.按照发布周期,美国当地时间 3 月 19 日,也就是北京时间 20 号 Java 12 正式发布了! △ JDK 12 GA 发布 ...

  5. Identifying a Blocking Query After the Issuing Session Becomes Idle

    Identifying a Blocking Query After the Issuing Session Becomes Idle #查看阻塞信息 select * from sys.innodb ...

  6. 工作记录--WPF自定义控件,实现一个可设置编辑模式的TextBox

    原文:工作记录--WPF自定义控件,实现一个可设置编辑模式的TextBox 1. 背景 因为最近在使用wpf开发桌面端应用,在查看页面需要把TextBox和Combox等控件设置为只读的.原本是个很简 ...

  7. C# 获取今天是星期几

    //获取今天是星期几 string[] Day = new string[] { "星期日", "星期一", "星期二", "星期 ...

  8. U-BOOT 对 Nand Flash 命令的支持

    U-BOOT 对 Nand Flash 命令的支持 在 U­BOOT 下对 Nand Flash 的支持主要是在命令行下实现对 nand flash 的操作.对 nand flash 实现的命令 为: ...

  9. Python全栈开发:选课系统实例

    程序目录: bin文件夹下为可执行文件:administrator,students config文件夹下为设置文件,涉及系统参数配置:setting db文件夹为数据类文件,涉及系统的输入输出数据: ...

  10. 180608发现的一个有趣的Douyin-Bot项目

    今日发现的github 项目 Douyin-Bot 抖音机器人发现漂亮小姐姐 :sweat_smile: 在开发者模式下,找到指针位置,开启之后,当点击屏幕时,可以获取点击屏幕处的xy坐标了 我使用的 ...