一、索引的基本原理
1. 数据结构支撑
数据库索引通常基于B树或B+树结构实现。
B树:每个节点存储键值和数据指针,支持快速二分查找,适用于平衡查询和修改的场景。
B+树:非叶子节点仅存键值,数据全存于叶子节点,并通过链表连接,适合范围查询和磁盘存储优化。例如,InnoDB引擎默认使用B+树。
2. 索引的影响机制
索引通过预排序将数据块的随机访问转换为顺序访问,减少磁盘I/O次数。例如,无索引时查询需扫描全表(复杂度O(n)),而索引可将复杂度降至O(log n)。
聚集索引(如主键索引)直接决定数据物理存储顺序,叶子节点存储完整数据行;非聚集索引叶子节点存储主键值,需二次查找(回表)获取数据。
3. 索引的核心代价
空间代价:索引需额外存储排序后的键值和指针。例如,500万条记录的索引可能占用数十万数据块。
维护代价:增删改操作需调整索引结构,可能触发页分裂或合并,影响写入性能。
二、索引的常见用法
1. 索引类型及适用场景
| 类型 | 特点 | 适用场景 |
| 主键索引 | 唯一且非空,默认聚集索引 | 高频访问的主键字段 |
| 唯一索引 | 字段值唯一,允许NULL | 唯一性约束字段(如身份证号) |
| 复合索引 | 多字段联合排序,遵循最左匹配规则 | 多条件查询(如WHERE+ORDER BY) |
| 覆盖索引 | 索引包含查询所需字段,避免回表 | 高频查询的字段组合 |
2. 创建与优化策略
创建语法示例:
sql
单列索引
CREATE INDEX idx_name ON table(column);
复合索引
CREATE INDEX idx_name ON table(col1, col2);
唯一索引
CREATE UNIQUE INDEX idx_unique ON table(column);
优化规则:
高区分度字段优先:例如性别字段区分度低(仅2种值),不适合单独建索引。
避免冗余索引:如已有(col1, col2),单独对col1建索引冗余。
警惕索引失效:避免对索引字段使用函数、运算或类型转换(如`WHERE YEAR(date_col)=2023`)。
3. 索引的失效场景
使用`LIKE ‘%value%`导致无法利用索引前缀。
联合索引未遵循最左匹配规则(如索引为(col1, col2),但查询仅用col2)。
数据量过小时(如全表扫描更快),优化器可能放弃索引。
三、索引的进阶应用
1. 索引选择与基数性
基数性(Cardinality):字段唯一值的比例。高基数性(如用户ID)适合建索引,低基数性(如情形码)可能需结合其他字段建复合索引。
索引下推(ICP):在存储引擎层过滤数据,减少回表次数(如MySQL 5.6+支持)。
2. 聚簇索引的设计影响
主键应选择有序且不更新的字段(如自增ID),避免频繁页分裂。若使用UUID等无序值,插入性能可能骤降。
3. 全文索引与独特场景
全文索引:基于倒排索引实现,适用于文本搜索(如`MATCH(col) AGAINST(‘keyword’)`)。
空间索引:如R树用于地理数据,Z-order曲线优化多维查询。
四、具体要怎么做
核心规则:索引是“空间换时刻”的典型应用,需平衡查询性能与维护成本。
操作技巧:
优先为WHERE、JOIN、ORDER BY涉及的字段建索引。
监控慢查询日志,定期优化冗余索引(如使用`EXPLAIN`分析执行规划)。
大数据表中,考虑分区表或分库分表以减轻索引压力。
通过合理设计索引,可显著提升数据库性能,但需结合业务场景动态调整,避免过度索引导致的资源浪费。