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 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> Impossible WHERE noticed after reading const tables -> 正文阅读

[大数据]Impossible WHERE noticed after reading const tables

  • 创建一表并指定了一个唯一索引
CREATE TABLE `student_info` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `student_id` int(11) NOT NULL,
  `name` varchar(20) DEFAULT NULL,
  `course_id` int(11) NOT NULL,
  `class_id` int(11) DEFAULT NULL,
  `create_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `idx_name` (`name`),
  KEY `idx_classid` (`class_id`)
) ENGINE=InnoDB AUTO_INCREMENT=963277 DEFAULT CHARSET=utf8mb4

此时指定了2个索引,一个是name字段的唯一索引,一个是class_id字段的普通索引。

在使用explain查看以下sql的执行计划时,出现一下的补充提示

explain select * from student_info
where name = 'vznavzwoulu1c6jc' and class_id = 575

在这里插入图片描述
而且这条sql也没有用到任何索引。但是明明name和class_id字段都是有索引的。

查阅相关资料后得出结论,当sql的where条件满足以下4个条件时。MySQL在 EXPLAIN 之前会优先根据这一条件查找出对应的记录,并用记录的实际值替换查询中所有使用到的该表属性。

  1. 当查询条件中包含了某个表的主键或者非空的唯一索引列
  2. 该列的判定条件为等值条件
  3. 目标值的类型与该列的类型一致
  4. 目标值为一个确定的常量

name使用了唯一索引,满足第一条,且是等值条件,满足第二条,参数值是字符串类型,不存在隐式转换,满足第三条,且是一个确定的常亮,不存在使用函数或者子查询之类的,第四条满足,此时mysql就会查出一条唯一的值,然后拿这条记录的class_id与条件的class_id字段比较,发现不符合,于是提示了

Impossible WHERE noticed after reading const tables

  • 尝试删除name的索引后再查询
drop index idx_name on student_info;
  • 再继续查询
explain select * from student_info
where name = 'vznavzwoulu1c6jc' and class_id = 58184

在这里插入图片描述
此时优化器就用上了class这个索引。

  • 测试添加联合索引
create index mul_class_id_name_create_time on student_info(class_id,name,create_time);

explain select sql_no_cache * from student_info
where  name = 'zsd' and class_id = 781 and create_time > '2022-04-06'

虽然此时的查询条件顺序是name classid create_time,但优化器优化了顺序,使得能够使用上联合索引。

在这里插入图片描述

explain select sql_no_cache * from student_info
where  name = '781' and create_time > '2022-04-06'

在这里插入图片描述

上述sql如果没有使用classid字段,则就会进行全表扫描,虽然name和createtime字段是有联合索引的。但是前提是当classid相同,才会给name排序,当name相同才会给createtime排序。也就是说不看classid,那么name和createtime根本就是乱序的,既然是乱序的只能进行全表扫描了。

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-04-27 11:23:07  更:2022-04-27 11:25:09 
 
开发: 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年11日历 -2024/11/24 2:38:20-

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