当前位置: 首页 > news >正文

Mysql索引-学习笔记

联合索引

在where子句中仅使用联合索引的第二个字段会导致性能问题

在使用联合索引时,如果where子句中仅仅使用联合索引的第二个字段作为过滤条件,将可能导致索引类型为ALL或者index
接下来,我们将做一个实验:

  • 首先创建一个包含两个联合索引的表index_table2
-- 创建表
CREATE TABLE index_table2 (ID INT AUTO_INCREMENT PRIMARY KEY,idx1_field1 VARCHAR(255) NOT NULL,idx1_field2 VARCHAR(255) NOT NULL,idx2_field3 VARCHAR(255) NOT NULL,idx2_field4 VARCHAR(255) NOT NULL
) ENGINE=InnoDB;-- 创建联合索引
CREATE INDEX idx_index1 ON index_table2 (idx1_field1, idx1_field2);
CREATE INDEX idx_index2 ON index_table2 (idx2_field3, idx2_field4);-- 插入 5000 条随机测试数据
DELIMITER $$
CREATE PROCEDURE insert_random_data()
BEGINDECLARE i INT DEFAULT 1;WHILE i <= 5000 DOINSERT INTO index_table2 (idx1_field1, idx1_field2, idx2_field3, idx2_field4)VALUES (CONCAT('idx1_field1', FLOOR(1 + RAND() * 10000)),CONCAT('idx1_field2', FLOOR(1 + RAND() * 10000)),CONCAT('idx2_field3', FLOOR(1 + RAND() * 10000)),CONCAT('idx2_field4', FLOOR(1 + RAND() * 10000)),CONCAT('no_idx_field5_', FLOOR(1 + RAND() * 10000)));SET i = i + 1;END WHILE;
END $$
DELIMITER ;CALL insert_random_data();
  • 接下来,我们将分析,where子句使用不同的字段对性能的影响。
-- 查询联合索引,如果 select 中的字段是联合索引的一部分,且 where 子句字段是联合索引的第一个字段,那么 type 为 ref
explain
select idx1_field1 from index_table2 it where idx1_field1 = 'idx1_field18151'
-- type refexplain
select idx1_field2 from index_table2 it where idx1_field1 = 'idx1_field18151'
-- type ref-- 查询联合索引,如果 select 中的字段补是联合索引的一部分,且 where 子句字段是联合索引的第一个字段,那么 type 为 ref
explain
select idx2_field3 from index_table2 it where idx1_field1 = 'idx1_field18151'
-- type refexplain
select idx2_field4 from index_table2 it where idx1_field1 = 'idx1_field18151'
-- type refexplain
select field5 from index_table2 it where idx1_field1 = 'idx1_field18151'
-- type ref

可以看到,如果where子句使用的是联合索引的第一个字段,那么无论查询哪个字段使用的都是ref索引。

-- 查询联合索引,如果 select 中的字段补是联合索引的一部分,且 where 子句字段不是联合索引的第一个字段,那么 type 为 ref
explain
select idx2_field3 from index_table2 it where idx1_field2 = 'idx1_field18151'
-- type ALLexplain
select idx2_field4 from index_table2 it where idx1_field2 = 'idx1_field18151'
-- type ALLexplain
select field5 from index_table2 it where idx1_field2 = 'idx1_field18151'
-- type ALL-- 查询联合索引,如果 select 中的字段是联合索引的一部分,且 where 子句字段不是联合索引的第一个字段,那么 type 为 index
explain
select idx1_field1 from index_table2 it where idx1_field2 = 'idx1_field18151'
-- type indexexplain
select idx1_field2 from index_table2 it where idx1_field2 = 'idx1_field18151'
-- type index

可以看到,如果where子句仅仅使用联合索引的第二个字段作为过滤条件,那么如果select中的字段不在联合索引中,就会使用全表查询,如果使用的字段在联合索引中,那么就会使用index索引。

如果希望使用联合索引的第二个字段作为过滤条件,此时应该在where子句中加上联合索引的第一个字段,这两个字段在where子句中的顺序,或者有其他where语句,并不影响使用ref索引。

explain
select field5 from index_table2 it where idx1_field2 = 'idx1_field29359' and idx2_field3 = 'idx2_field32298' and idx1_field1 = 'idx1_field11499';
-- ref

如果过滤条件不希望使用第一个字段,但又必须使用以免影响索引,这个时候给第一个字段一个范围值即可,建议:

  • 使用一个可以包括所有数据的范围

在这里插入图片描述

  • 查询联合索引第一个字段的全部的值,再执行sql(这里不建议使用子查询)
    在这里插入图片描述

不建议:
使用is not null 语句,会全表扫描
在这里插入图片描述

使用like语句,会全表扫描
在这里插入图片描述


http://www.mrgr.cn/news/66199.html

相关文章:

  • Matlab实现海马优化算法(SHO)求解路径规划问题
  • python画图|hist()函数画直方图初探
  • 第三十四章 Vue路由进阶之声明式导航(导航高亮)
  • (蓝桥杯C/C++)—— 编程基础
  • 分类算法——决策树 详解
  • 网络编程入门
  • 利用递归方法求5!
  • 机器学习与成像技术
  • jmeter结合ansible分布式压测--2jmter环境准备
  • Rust项目结构
  • 深入探讨移动Web开发:从基础到实践
  • 基于Springboot+Vue的在线教育系统 (含源码数据库)
  • 自由学习记录(19)
  • 日常使用巡检
  • 选择非标加工制造,让你的产品与众不同!
  • 数据库范式
  • 【IF-MMIN】利用模态不变性特征进行缺失模态的鲁棒多模态情感识别
  • 如何用3D技术打造高转化的跨境独立站?
  • 「Mac畅玩鸿蒙与硬件29」UI互动应用篇6 - 多选问卷小应用
  • 【专题】产业全球化视角下中国企业出海人才趋势洞察报告汇总PDF洞察(附原数据表)
  • UserControl 中为 Guna2TextBox 设置 ToolTip 效果的方法
  • ARGB和‌RGB的主要区别
  • CodeQL学习笔记(5)-CodeQL for Java(AST、元数据、调用图)
  • 不入耳开放式耳机哪个品牌好?开放式耳机排行榜 10 强推荐
  • 信创证书和软考有什么不同?看这!
  • 浅谈“绿色”医院的相关建设