MySQL 三星索引

本文围绕数据库表TEST的索引idx_a_b_c展开,介绍了索引三星优化原理。第一颗星要保证最窄的索引片;第二颗星需避免排序;第三颗星要避免回表且同时满足一星和二星。还提到宽索引情况,总结指出若一和二无法同时实现,一更重要,结果集大时要考虑避免排序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

表:TEST
列:A,B,C,D,E,F
索引:idx_a_b_c(A,B,C)
A列:过滤因子1% 
B列:过滤因子10%

第一颗星,保证最窄的索引片
SELECT A,B,C,D,E,F FROM TEST WHERE A=A1 AND B=B1 AND C = C1
索引idx_a_b_C 满足了所有的谓词
WHERE A=A1 AND B=B1 AND C=C1  
idx_a_b_c 为一星索引,但D,E,F 需要回表查找,所以无法满足三星

第二颗星,避免排序
SELECT A,B,C,D,E,F FROM TEST WHERE A=A1 AND B=B1 ORDER BY C DESC
  OR
SELECT A,B,C,D,E,F FROM TEST ORDER BY A DESC
索引idx_a_b_c 可以用于排序,索引符合二星,但需要回表,无法满足三星

第三颗星,避免回表,同时满足一星,二星
SELECT A,B,C FROM TEST WHERE A=A1 AND B>B1 
idx_a_b_c 可以直接从索引值获取A,B,C的值,不需要回表,同时 满足第一颗星

宽索引:避免了回表,的可能不满足第一颗星
SELECT A,B,C FROM TEST WHERE A>1 AND B=B1 AND C=C1
A 是范围查找,B,C索引不在匹配,但是,所有的值可以通过 idx_a_b_c 获取,而不需要回表查找

总结
一般而言,如果一和二无法同时实现, 一比二更重要。
更窄的索引片,能减少随机访问,而且小数据,在CPU排序,速度是非常快的。
假设每一行处理速度是10us左右  5W行排序 只需要0.5s(当然对于CPU而言,时间太长)
所以对于结果集很大,但只需要产生一屏数据,排序消耗的时间太长,要考虑避免排序

<think>好的,我现在需要答用户关于MySQL索引的问题。首先,用户之前询问了深度学习的内容,现在转向数据库的索引,可能是在学习技术栈的不同部分。我需要确保答的结构清晰,覆盖主要知识点,并且符合用户提到的格式要求。 首先,我应该忆一下MySQL索引的基本概念,然后分门别类地整理知识点。常见的索引类型有B+树索引、哈希索引、全文索引等。接下来是索引的数据结构,比如B+树的结构特点,为什么MySQL使用B+树而不是B树或者其他结构。然后要考虑索引的类型,比如主键索引、唯一索引、普通索引、联合索引等,每种索引的区别和应用场景。 另外,需要包括索引的创建和管理,比如创建索引的语法,如何选择索引的列,索引优化策略,比如最左前缀原则,覆盖索引索引下推这些概念。还有索引的优缺点,比如提高查询速度但会增加写入开销,占用存储空间等。 还要考虑索引的使用注意事项,比如什么时候应该创建索引,什么时候不应该,如何通过EXPLAIN来分析索引的使用情况,索引的失效场景,比如使用函数、类型转换、OR条件等导致索引失效的情况。 可能还需要提到聚簇索引和非聚簇索引的区别,InnoDB和MyISAM在索引实现上的不同。此外,索引的存储引擎支持情况,比如MEMORY引擎支持哈希索引,InnoDB的自适应哈希索引等。 有没有遗漏的部分?比如索引的维护,比如重建索引索引的统计信息,Cardinality的概念,以及索引的选择性和查询效率的关系。此外,还有全文索引的特殊处理,比如自然语言模式和布尔模式,以及5.6版本后InnoDB对全文索引的支持。 还有,需要确保使用正确的LaTeX格式,比如数学达式和公式用$或$$包裹,结构分点明确。需要检查是否有错误的技术细节,比如B+树的高度计算,或者联合索引的最左匹配原则的具体例子。 可能还需要举例说明,比如创建索引的SQL语句,如何查看索引信息,使用EXPLAIN的结果解读。但用户可能只需要知识点的罗列,不需要具体例子,但适当举例有助于理解。 最后,总结部分可以提到索引的最佳实践,比如避免过多索引,定期分析索引使用情况,根据查询模式设计索引等。同时,确保内容准确,比如InnoDB的聚簇索引结构,行数据存储的位置,以及二级索引的访问需要两次查找等。 现在需要将这些内容组织成一个结构化的答,分点说明,使用适当的子标题,确保每个部分清晰,并且符合用户之前设定的格式要求,比如使用中文,正确的LaTeX语法,独立公式用$$包裹,行内公式用$包裹,避免使用Markdown格式。</think>以下是MySQL索引的核心知识点整理: ### 1. 索引基础原理 - **B+树结构**:主流索引类型,满足$O(\log n)$查询复杂度 $$ \text{节点容量}=16KB/(主键大小+指针大小) $$ 例:8B主键+6B指针 → 约1170子节点/层 - **页分裂机制**:当插入数据导致页使用率超过$\frac{15}{16}$时触发 - **聚簇索引**:InnoDB主键索引,数据与索引存储在一起(非主键时自动创建隐藏RowID) ### 2. 索引类型体系 | 类型 | 数据结构 | 支持引擎 | 特点 | |------|----------|----------|------| | 主键索引 | B+Tree | InnoDB | 唯一且非空,叶节点含完整数据 | | 唯一索引 | B+Tree | 所有引擎 | 强制列值唯一性 | | 普通索引 | B+Tree | 主要引擎 | 允许重复值,叶节点存主键 | | 全文索引 | 倒排索引 | InnoDB(5.6+) | 支持`MATCH AGAINST`查询 | | 空间索引 | R-Tree | MyISAM | 处理GIS数据,支持`MBRContains`等函数 | ### 3. 复合索引规则 - **最左前缀原则**: 索引`(a,b,c)`有效查询: ```sql WHERE a=1 AND b>2 WHERE c=3 AND b=5 AND a=2 -- 优化器自动调整顺序 ``` 无效场景: ```sql WHERE b=1 -- 跳过首列 WHERE a=1 AND c=3 -- 中间断层 ``` - **索引跳跃扫描**:MySQL 8.0新特性,即使未指定首列也可使用索引(需低基数首列) ### 4. 性能优化要点 - **覆盖索引**:查询字段全部包含索引中,避免 ```sql -- 使用索引(a,b) SELECT b FROM table WHERE a=5 ``` - **索引下推(ICP)**:5.6+版本,WHERE条件在存储引擎层过滤 ```sql /* 索引(a,b), 查询条件a=1 AND b LIKE 'test%' */ 旧方案:后过滤b条件 ICP:在索引层直接过滤b条件 ``` - **索引选择率**:最优索引应满足 $$ \frac{\text{distinct值数量}}{\text{总行数}} \geq 10\% $$ ### 5. 索引失效场景 1. **隐式类型转换**: ```sql WHERE varchar_col = 123 -- 转换为字符串比较 ``` 2. **函数操作**: ```sql WHERE YEAR(create_time)=2023 -- 改为范围查询 ``` 3. **前导通配符**: ```sql WHERE name LIKE '%abc' -- 无法使用索引 ``` 4. **OR条件**: ```sql WHERE a=1 OR b=2 -- 除非a,b都有独立索引 ``` ### 6. 索引管理命令 ```sql -- 查看索引信息 SHOW INDEX FROM tbl; -- Cardinality统计 ANALYZE TABLE tbl; -- 强制使用索引 SELECT * FROM tbl USE INDEX(idx_name); -- 索引重建(消除碎片) ALTER TABLE tbl ENGINE=InnoDB; ``` ### 7. 设计实践准则 - **三星索引原则**: 1. WHERE条件列形成索引左前缀(★) 2. ORDER BY列包含索引中(★) 3. 覆盖所有SELECT字段(★) - **空间占用计算**: 每GB数据约需额外100-300MB索引空间 - **写入代价**:每个索引增加约10%-20%的INSERT/UPDATE耗时 最新版本改进(MySQL 8.0): - 新增`INVISIBLE INDEX`功能,可暂时禁用索引测试影响 - 支持降序索引`(a DESC, b ASC)`,优化ORDER BY ... DESC查询 - 引入函数索引`INDEX((DATE(create_time)))`,突破字段操作限制
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值