IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> 实验:验证mysql索引失效场景 -> 正文阅读

[大数据]实验:验证mysql索引失效场景

本文主要是为了验证何种情况下索引会失效,建表使用了innoDB存储引擎
以下是一些索引失效传言,和本人验证结果,基于5.6的版本

  1. “索引列不能出现null值”,不准确,可能会全表扫描,可能会走索引,看优化器怎么衡量查询的代价
  2. “模糊查询,只有左匹配才能走索引”,对
  3. “用了or的查询,必须or两边的条件都满足最左匹配才能走索引”,对
  4. “隐式转换会引起索引失效”,对
  5. “!= 不走索引”,不知道,我在主键和非主键索引上验证了都是不走的

另外字段列值允许为null的情况下,查询时有些坑要注意:

  1. count(*)与count(具体列名)的区别:前者会将null值统计在内,后者不会,取舍要取决于null的业务含义
  2. sum(具体字段)=null的情况:当查询的结果集为空时,sum的结果为null
  3. count(1) 和 count(具体列) 是等效的,结果一致

总的来说,查询是否走索引,最终看的是mysql优化器的判断,网上很多“索引失效规律”都是有前提的

建表细节:
在这里插入图片描述

-- 建表语句
CREATE TABLE `t_innodb` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '是否为空对命中索引有啥影响',
  `age` int(11) DEFAULT NULL,
  `sex` tinyint(1) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`) USING BTREE,
  KEY `idx_age_sex` (`age`,`sex`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;


-- 练习与验证
-- 查询mysql的安装路径
show variables like '%basedir%'

-- 查询版本号
SELECT VERSION()

-- 无法看到innoDB和myisam表的文件在磁盘上的区别

-- 测试模糊查询

-- 单个索引字段查询
EXPLAIN select * from t_innodb where age = 11
-- 范围查询也可索引
EXPLAIN select age from t_innodb where age > 11 and age <44

-- != 会导致索引失效
EXPLAIN select * from t_innodb where age != 22





-- null 是特殊的,要用is null
select * from t_innodb where age = null

-- 索引字段为null并不一定会索引失效
EXPLAIN select * from t_innodb where age is null

-- varchar字段 存了数字的话,字符转换问题会影响索引
EXPLAIN select * from t_innodb where name = '22' -- 查询结果一致,因为mysql做了隐士转换
EXPLAIN select * from t_innodb where name = 22


-- 不是的:!= 不走索引

-- select * 偶尔会影响走索引,可能是因为全表扫描的效率更高
EXPLAIN select name from t_innodb where name != '22'
EXPLAIN select * from t_innodb where name != '22'
-- 走索引
EXPLAIN select * from t_innodb where name like '22'
-- 走索引
EXPLAIN select * from t_innodb where name like '22%'
-- 右边匹配不走索引
EXPLAIN select * from t_innodb where name like '%22'

-- 查询null值不影响走索引
EXPLAIN select * from t_innodb where name is null

-- 
EXPLAIN select name from t_innodb where name is not null



-- 联合索引

EXPLAIN select * from t_innodb where age = 1 or age = 22 -- 晚点测试in 和 not in

-- 用了or的联合索引,无论如何一定要各自遵循最左匹配:就当做or的左右都是有隐形的括号包起来的
EXPLAIN select * from t_innodb where age = 1 or (age = 2 and sex = 22)

EXPLAIN select * from t_innodb where age = 1 and sex != 22

EXPLAIN select * from t_innodb where age = 11 and sex != 22



-- 怎么从解析计划中看到查询是否有回表操作,看extra字段


-- 关于null的一些坑
SELECT count(name) from t_innodb
SELECT count(*) from t_innodb  -- 共10条

-- 含null列,查询结果不含null,
-- 所以如果对于业务而言null是有意义的话,这种写法容易查漏数据
SELECT * from t_innodb where name != 'zk'
-- 含null列,如果需要查到null
SELECT * from t_innodb where name != 'zk' or ISNULL(name)


-- sum() 对可能为null的字段使用sum

-- 没有结果集的时候返回null
SELECT sum(age) from t_innodb where id = 10

-- 直接统计的话,为null的值不参与统计

SELECT sum(age) from t_innodb

-- 结果为null
select 1 + null


 select SQL_NO_CACHE  * from t_innodb where name != 'zk' or ISNULL(name)


举个栗子说明为啥是否走索引

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-08-19 19:12:48  更:2022-08-19 19:13:35 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/20 1:35:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码