mysql索引的一点小知识

本文探讨了索引在查询中的应用,包括数据量对索引使用的影响、等值查询与非等值查询的索引选择差异,以及如何根据查询条件顺序优化复合索引。重点讲解了最左匹配原则和索引利用效率,以及在实际场景中的最佳索引构建策略。

是否走索引 和 数据量有关系

索引是(a,b)
查询是 select * from my_table where a=x; 可能数据量小的时候不走索引,等数据量增大了,就走索引了。

where 条件里面的字段顺序和是否走索引没有关系

上面说的主要是等值查询 例如 where field_a=1 and filed_b=2 和 where filed_b=2 and field_a=1 的索引情况是一样的
那如果是非等值索引呢?
where a=x and b>y and c=z 和 where a=x and c=z and b>y
上面两个sql 运行后的数据集肯定是一样的。那走的索引是不是一样的呢?或者换句话说 都是用and链接的条件,在包含非等值查询的时候,条件的顺序还有用么?
答案是条件的顺序无所谓。
上面那个case,最优的建立索引的顺序是 (a,c,b)

有索引(a,b,c,d)的时候

单独查询 a,(a,b) (a,b,c) (a,b,c,d) 都可以走索引;但是根据最左匹配,直接查询b,或者b,c and d,d都不能走索引。
索引查到不等值就会停下来。例如 where a=x and b>y and c=z 就只能使用ab索引

组合索引的选择率

选择率应该是最大的例如userid 之后的元素要保证 凡是等值查询的都放在前面 非等值查询的(大于小于 in)放到后面

索引是(a,b),查询条件也是 a=x and b=y 此时如果select * 就有可能不走索引。(因为回表)

在这里插入图片描述
例如上面

explain select * from employees where first_name >'a';
explain select first_name from employees where first_name >'a';

两个sql一个走索引一个不走索引,区别在哪?区别就在最终返回的结果一个只查first_name,一个需要回表查询所有字段
那有回表就一定不走索引么?
怎么可能!!
在这里插入图片描述


另外因为上面说了是否走索引 和 数据量有关系,所以大家以后测试的时候,就尽量找个大的数据集。恰好,mysql官方给我们整了一个雇员系统的db。 具体怎么用:https://zhuanlan.zhihu.com/p/293983110 记住导入mysql的时候,语法是
mysql -uxxx -pxxx < you_file_path/employees.sql

如果已经登录了,可以使用如下命令导入sql脚本

mysql> source  /path/to/file.sql; 
或
mysql>  \. /path/to/file.sql

参考资料

https://heapdump.cn/article/3965201

<think>嗯,用户想了解MySQL中的索引覆盖概念、使用场景以及优缺点。首先,我需要回忆一下索引覆盖的相关知识索引覆盖,也就是覆盖索引,是指一个查询的查询列条件列都包含在某个索引中,这样数据库可以直接通过索引来获取数据,而不需要回表查询数据行。 根据引用[1],覆盖索引特别适用于SELECT操作,尤其是涉及多个字段的查询。这意味着当查询需要的列都在索引中时,可以显著提高性能。而引用[3]提到,设计高效的索引很重要,宽索引可以覆盖更多查询,但需要在查询速度更新开销之间平衡。这可能涉及到覆盖索引的优缺点,比如减少磁盘I/O但可能增加维护成本。 引用[2][4]也提到索引的基本概念优化,比如索引下推普通索引与change buffer的配合使用。不过用户的问题主要集中在覆盖索引,所以需要聚焦这一点。优缺点方面,优点肯定是减少回表,提高查询速度,缺点可能包括索引维护的开销存储空间的增加。 用户的使用场景可能包括需要频繁查询的字段组合,或者查询中只需要索引中的列。比如常见的场景是SELECT语句中只包含索引列,这时候使用覆盖索引效果最好。例如,如果有一个索引包含(col1, col2),查询SELECT col1, col2 FROM table WHERE col1=...,这时候就能利用覆盖索引。 需要确认覆盖索引的定义是否正确,是否确实是当查询的列都在索引中时触发。引用[1]中提到的触发条件可能需要进一步解释,比如查询的所有字段都在索引中,包括SELECTWHERE中的列。例如,如果索引是(a,b,c),查询SELECT a,b FROM table WHERE c=...,这时候可能无法使用覆盖索引,因为c在索引中,但WHERE条件中的c如果索引结构不支持,可能需要回表。 另外,是否需要考虑联合索引顺序?比如,索引(a,b,c)是否能覆盖查询条件ac的情况?可能不行,因为索引的最左前缀原则,如果查询条件中的c没有a,可能无法有效利用索引,导致覆盖索引无法生效。这部分可能需要更详细的解释。 还有,覆盖索引的优缺点需要明确。优点是减少磁盘I/O,提升查询速度,可能减少CPU内存的使用(如引用[5]提到的SQL优化减少资源占用)。缺点则是索引占用更多存储空间,写操作(INSERT/UPDATE/DELETE)需要维护更多索引,可能影响性能。 需要结合引用中的内容,特别是引用[1]、[3]、[4]来支持这些点。例如,引用[4]提到普通索引change buffer的配合对于大数据量表的更新优化,这可能与覆盖索引的维护开销有关,但覆盖索引本身如果是普通索引,可能在这方面有影响。 最后,生成的相关问题应该围绕覆盖索引的应用、设计考虑、与其他索引类型的比较等。例如,如何设计覆盖索引,覆盖索引与复合索引关系,或者覆盖索引在特定场景下的优化案例。 总结回答的结构应该是:概念解释、使用场景、优缺点,每个部分引用对应的资料。注意使用正确的LaTeX格式,如变量用$...$,独立公式用$$...$$,但用户的问题可能不需要数学公式,所以可能用不到。不过如果有涉及性能分析的公式,比如时间复杂度,可能需要用,但根据用户的问题,可能不需要。</think>### MySQL索引覆盖详解 #### 一、索引覆盖概念 索引覆盖(Covering Index)指**查询所需的所有列均包含在索引中**,无需回表查询数据行即可完成查询。 例如: - 表结构:`user(id, name, age)`,索引为`idx_name_age(name, age)` - 查询语句:`SELECT name, age FROM user WHERE name = '张三'` 此时,索引`idx_name_age`已包含查询所需字段,直接通过索引即可返回结果[^1]。 #### 二、使用场景 1. **高频查询字段组合** 若某些字段频繁作为查询条件或返回结果(如`SELECT col1, col2`),可为其创建联合索引[^3]。 2. **聚合函数优化** 对索引字段使用`COUNT()`、`SUM()`等聚合函数时,可直接通过索引统计,无需访问数据行[^4]。 3. **排序与分组优化** 若`ORDER BY`或`GROUP BY`的字段在索引中,可避免临时表排序[^3]。 4. **减少随机I/O** 覆盖索引通过顺序读取索引树减少磁盘随机访问,提升查询效率[^2]。 #### 三、优缺点分析 | **优点** | **缺点** | |---------------------------------------|-------------------------------------| | 1. 减少回表操作,降低查询延迟 | 1. 索引占用更多存储空间 | | 2. 减少磁盘I/OCPU消耗(仅遍历索引结构)[^5] | 2. 写操作需维护更多索引,可能影响写入性能 | | 3. 可优化聚合、排序等复杂操作 | 3. 宽索引可能导致索引层级增加,影响查询效率 | #### 四、设计原则 1. **明确查询需求**:根据高频查询的字段组合设计索引,避免冗余。 2. **控制索引宽度**:优先选择区分度高且频繁查询的字段。 3. **权衡读写性能**:在查询优化与写入开销之间平衡,避免过度索引[^5]。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值