MYSQL索引优化

1. 索引的定义和作用

索引是对数据库表中一个或多个列进行特殊的数据结构处理,常见的如二叉树(BTREE)和哈希(HASH)。索引可以加速查询操作,但会增加存储开销,并影响DML(插入、更新、删除)操作的速度。最常用的索引类型是BTREE,因为它适用于范围查询、排序等操作。

  • BTREE:通过二叉树结构实现,支持范围查询(>、<、BETWEEN等),MySQL中大多数索引都是BTREE类型。
  • HASH:通过哈希算法实现,主要用于等值查询(=)。但是,HASH索引不能支持范围查询。
  • 其他类型:如全文索引(Fulltext)主要用于文本搜索,通常用于MyISAM引擎。

2. EXPLAIN优化查询

EXPLAIN语句是优化查询的强大工具,它能够展示MySQL如何执行一条查询,尤其是在涉及到索引时。EXPLAIN的输出字段非常关键,我们可以通过分析这些字段来优化查询。

示例查询
sql 复制代码
EXPLAIN SELECT `birthday` FROM `user` WHERE `birthday` < "1990/2/2";
输出字段解析:
  • id:查询的ID标识,可以用于区分查询中的不同子查询。一个简单的查询一般是1。
  • select_type:查询的类型。SIMPLE表示简单查询,PRIMARY表示最外层查询,UNION表示UNION中的查询等。
  • table:查询所涉及的表。
  • type :显示连接类型。range表示使用了索引来查找一个范围的数据,这通常比全表扫描(ALL)更高效。ALL表示全表扫描,这是最差的连接类型,尽量避免。
    • 从最好到最差的连接类型为:system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
  • possible_keys:MySQL认为在查询中可以使用的索引。
  • key:MySQL实际使用的索引。
  • key_len:索引的长度。较短的索引通常更高效。
  • ref:显示与索引一起使用的列或常数。
  • rows:MySQL估算需要扫描的行数。
  • Extra :一些额外的信息,Using where表示查询中有WHERE子句,Using index表示只使用了索引而未读取表数据,Using temporary表示使用了临时表,Using filesort表示MySQL需要额外的步骤进行排序。

3. 查询类型和连接类型

查询类型影响MySQL如何优化查询,以下是一些常见的查询类型及解释:

  • SIMPLE:简单查询,不涉及UNION或子查询。
  • PRIMARY:最外层的SELECT查询。
  • UNIONDEPENDENT UNIONSUBQUERY:分别表示UNION中的第二个或后面的查询,依赖于外层查询的查询等。

连接类型的优化很重要,尽量选择consteq_ref等高效的连接方式。

4. 索引类型的选择

根据查询的特点,选择合适的索引类型是优化查询的关键。

  • 唯一索引(UNIQUE INDEX):用于保证数据唯一性。可以在字段值有重复的情况下使用(但无法为NULL)。
  • 普通索引(INDEX):用于提高查询性能,但不限制数据唯一性。
  • 主键索引(PRIMARY KEY):主键是唯一且不可为NULL的,表中只能有一个主键。
  • 全文索引(FULLTEXT INDEX):适用于全文搜索,MyISAM引擎支持较好。

5. 索引的创建与删除

索引的创建、删除和查看都可以通过SQL语句进行。

  • 创建索引

    sql 复制代码
    CREATE INDEX index_name ON table_name (column_list);
  • 删除索引

    sql 复制代码
    DROP INDEX index_name ON table_name;
  • 查看索引

    sql 复制代码
    SHOW INDEX FROM table_name;

索引的删除应该小心,尤其是对于主键索引,删除时会影响表的结构。

6. 索引优化建议

根据查询模式和表的结构,优化索引可以显著提升性能。以下是一些常见的索引优化技巧:

高维度列:
  • 对于数据中有较多不同值的列(如年龄、性别),应该考虑创建索引。维度较低的列(如性别)不适合创建索引。
使用索引的列:
  • 对于WHEREONGROUP BYORDER BY等操作中常用的列,建议创建索引。
索引的大小:
  • 对于较小的数据列(如整数),可以使用索引。对于较长的字符串,可以考虑使用前缀索引,只索引字段的前部分。
不要过多创建索引:
  • 过多的索引会占用磁盘空间并降低写操作的性能(如INSERT、UPDATE、DELETE)。因此,要根据实际查询需求创建索引。
组合索引与前缀索引:
  • 组合索引 :当查询涉及多个列时,创建组合索引能减少多列索引的开销。

    sql 复制代码
    ALTER TABLE `myIndex` ADD INDEX `name_city_age` (vc_Name(10), vc_City, i_Age);
  • 前缀索引:对较长的字符串字段,创建前缀索引能够减少索引的大小,提高查询性能。

7. 索引创建实例分析

对于一个表中多个列的查询,单列索引和组合索引的效果对比:

单列索引
sql 复制代码
SELECT i_testID FROM myIndex WHERE vc_Name = 'erquan' AND vc_City = '郑州' AND i_Age = 25;

对于每一个条件,MySQL可能会分别扫描索引,效率较低。

组合索引
sql 复制代码
ALTER TABLE `myIndex` ADD INDEX `name_city_age` (vc_Name(10), vc_City, i_Age);

组合索引可以在一次查询中同时利用多个列,从而提高查询效率。

8. 其他优化建议

  • *避免使用SELECT 除非你确实需要所有列,否则应明确选择所需的列,减少数据量和索引扫描。
  • 查询缓存: 对于频繁执行的查询,可以使用查询缓存,但需要根据数据更新频率调整缓存策略。
  • 表设计优化: 设计良好的表结构也是提升查询性能的基础,确保数据表规范化,减少冗余数据。

总结

通过合理使用索引、EXPLAIN分析查询执行计划、优化查询语句,可以显著提升MySQL查询的性能。注意,在创建索引时要权衡读取性能与写入性能的平衡,避免过多创建索引,同时选择合适的索引类型和组合索引。

相关推荐
知初~4 小时前
出行项目案例
hive·hadoop·redis·sql·mysql·spark·database
子非衣5 小时前
MySQL修改JSON格式数据示例
android·mysql·json
钊兵6 小时前
数据库驱动免费下载(Oracle、Mysql、达梦、Postgresql)
数据库·mysql·postgresql·oracle·达梦·驱动
隔壁老王1568 小时前
mysql实时同步到es
数据库·mysql·elasticsearch
Hanson Huang11 小时前
【存储中间件API】MySQL、Redis、MongoDB、ES常见api操作及性能比较
redis·mysql·mongodb·es
LUCIAZZZ11 小时前
EasyExcel快速入门
java·数据库·后端·mysql·spring·spring cloud·easyexcel
yuanbenshidiaos11 小时前
【正则表达式】
数据库·mysql·正则表达式
雾里看山14 小时前
【MySQL】内置函数
android·数据库·mysql
geovindu14 小时前
python: SQLAlchemy (ORM) Simple example using mysql in Ubuntu 24.04
python·mysql·ubuntu