Debian MariaDB索引优化技巧
为经常用于WHERE子句、JOIN条件或ORDER BY子句的列创建索引,优先选择过滤性高的列(如状态字段、时间字段)。避免为不常查询或重复值多的列(如性别)创建索引——过度索引会增加写操作(INSERT、UPDATE、DELETE)的开销,并占用额外存储空间。
对于多列组合查询,创建复合索引(如CREATE INDEX idx_name_age ON users(name, age))。复合索引的列顺序需遵循“最佳左前缀”原则:查询条件必须从左到右连续使用索引列,否则索引会失效。例如,索引idx_name_age可用于WHERE name='John'、WHERE name='John' AND age=30,但不能用于WHERE age=30(除非name列是常量)。
复合索引的列顺序应根据查询频率和范围查询调整:过滤性高的列(如状态字段)放在前面,范围查询的列(如时间、年龄)放在后面。例如,若查询常以status=1且create_time>='2025-01-01'筛选,索引顺序应为(status, create_time)——范围查询后的列无法被索引继续利用,但前面的列仍能发挥作用。
OPTIMIZE TABLE table_name;命令重建索引,恢复索引效率;SHOW INDEX FROM table_name;查看索引的Cardinality(基数,唯一值数量)和Rows_read(读取行数),删除长期未使用的索引(可通过performance_schema进一步分析)。WHERE UPPER(name)='JOHN'会导致索引失效,应改为WHERE name='John';WHERE age=10 OR classid=100(若classid无索引),需为classid添加索引;%开头(如LIKE '%John'),会导致索引失效,若需模糊搜索,可使用全文索引或搜索引擎(如Elasticsearch)。覆盖索引是指索引包含查询所需的所有列,数据库无需访问表数据即可返回结果。例如,查询SELECT name, age FROM users WHERE name='John',若已有复合索引(name, age),则可直接从索引中获取数据,大幅减少磁盘IO。
通过EXPLAIN SELECT ...命令查看查询执行计划,重点关注以下字段:
const、eq_ref、range为高效类型,ALL表示全表扫描);NULL,则表示未使用索引);Using index表示使用了覆盖索引,Using filesort表示需要排序)。