索引的缺点
额外存储开销
索引需要占用额外的磁盘空间。对于大型表,索引可能比数据本身占用更多空间,尤其是组合索引或全文索引。维护成本高
写入性能下降:每次插入、更新、删除数据时,数据库需要同步更新相关索引,导致写操作变慢。
重建成本:频繁修改数据可能导致索引碎片化,需要定期重建索引以优化性能。
可能误导查询优化器
过多的索引可能导致优化器选择低效的执行计划(如错误选择索引扫描而非全表扫描)。
统计信息不准确时,优化器可能无法有效利用索引。
不适用于所有查询
对低选择性字段(如性别、状态)建立索引效果差。
索引无法覆盖所有查询场景(如某些复杂条件或函数操作)。
设计复杂度高
需要根据具体查询模式合理设计索引,否则可能导致资源浪费或性能瓶颈。
常见的索引类型
1. B-Tree 索引
结构:平衡多路搜索树(如B+树,数据库常用变种)。
特点:
支持范围查询(
>
、<
、BETWEEN
)和排序(ORDER BY
)。适合高基数(唯一值多)的字段。
限制:
对前缀模糊查询(
LIKE '%abc'
)无效。函数或表达式可能导致索引失效。
常见子类:
唯一索引:强制字段值唯一(如主键)。
组合索引:多列联合索引,遵循最左匹配原则。
2. 哈希索引
结构:基于哈希表,存储键值的哈希码和行指针。
特点:
仅支持等值查询(
=
、IN
),查询速度极快(O(1))。
限制:
不支持范围查询或排序。
哈希冲突可能影响性能。
适用场景:内存表(如MySQL的Memory引擎)。
3. 全文索引
结构:倒排索引(存储关键词到文档的映射)。
特点:
支持文本关键词搜索(如
MATCH ... AGAINST
)。支持自然语言处理和分词(依赖语言规则)。
限制:
对短文本效果有限。
需要定期优化以合并分词碎片。
示例:Elasticsearch的核心索引类型。
4. 位图索引
结构:用位图(bitmap)表示每个键值对应的行是否存在。
特点:
适合低基数字段(如性别、布尔值)。
多条件组合查询效率高(通过位运算)。
限制:
高并发写入时锁竞争激烈。
不适合频繁更新的OLTP场景。
适用场景:数据仓库(OLAP)。
5. 空间索引(R-Tree)
结构:R树或其变种,用于多维数据(如地理坐标)。
特点:
支持空间查询(如
ST_Contains
、ST_Distance
)。
示例:PostGIS中的地理数据索引。
6. 其他类型
覆盖索引:索引包含查询所需的所有字段,避免回表。
聚簇索引(如InnoDB主键索引):数据行按索引顺序物理存储。
列存储索引(如ClickHouse):按列压缩存储,适合OLAP聚合查询。
总结
索引类型 | 适用场景 | 核心缺点 |
---|---|---|
B-Tree | 范围查询、高基数字段 | 前缀模糊查询无效,维护成本高 |
哈希 | 等值查询、内存表 | 不支持范围查询,哈希冲突风险 |
全文 | 文本搜索 | 分词复杂度高,存储占用大 |
位图 | 低基数字段、OLAP | 高并发写入性能差 |
空间索引 | 地理数据 | 仅支持特定空间操作 |
建议:
优先为高频查询条件建立索引,避免过度索引。
定期监控索引使用率,删除冗余索引。
组合索引需遵循最左匹配原则,合理安排字段顺序。