一、索引语法
- 创建索引
sql
CREATE [UNIQUE|FULLTEXT] INDEX index_name ON table_name (index_col_name,...);
- UNIQUE:唯一索引
- FULLTEXT:全文索引
- 不加修饰词为普通索引
- 查看索引
sql
SHOW INDEX FROM table_name;
- 删除索引
sql
DROP INDEX index_name ON table_name;
二、SQL 执行频率统计
sql
SHOW [SESSION|GLOBAL] STATUS LIKE 'Com_______';
可查看:
- Com_select:查询次数
- Com_insert:插入次数
- Com_update:更新次数
- Com_delete:删除次数
三、慢查询日志
- 记录执行时间超过
long_query_time(默认 10 秒)的 SQL - 开启配置(my.cnf):
ini
slow_query_log=1
long_query_time=2
- 日志默认路径:
/var/lib/mysql/localhost-slow.log
四、Profile 性能分析
sql
-- 查看所有SQL耗时
show profiles;
-- 查看某条SQL详细耗时
show profile for query query_id;
-- 查看CPU消耗
show profile cpu for query query_id;
五、EXPLAIN 执行计划
sql
EXPLAIN SELECT ...;
关键字段含义
- id:查询序号,id 越大越先执行
- select_type:查询类型(SIMPLE、PRIMARY、UNION...)
- type :性能从好到坏
NULL > system > const > eq_ref > ref > range > index > ALL - possible_key:可能用到的索引
- key:实际用到的索引
- key_len:索引使用字节长度
- rows:预估扫描行数
- filtered:返回行数占比,越高越好
Extra 关键字段
using index condition:用到索引,但需要回表using where; using index:覆盖索引,无需回表
六、索引使用规则
1. 验证索引效率
对比创建索引前后同一条 SQL 的执行耗时。
2. 最左前缀法则
联合索引必须从最左列开始,不能跳过中间列,否则后面索引失效。
3. 范围查询
联合索引中出现 > < 范围查询,范围右侧列索引失效。
4. 索引失效场景
- 字符串不加引号
- 模糊查询以
%开头(like '%xxx') - OR 连接的条件中有一列无索引
- 对索引列做函数、运算操作
- MySQL 判断全表扫描比索引更快时,不使用索引
七、单列索引 & 联合索引
- 单列索引:单个字段
- 联合索引:多个字段,优先使用,更容易实现覆盖索引
八、前缀索引
适用于长字符串字段,减少索引空间占用。
sql
CREATE INDEX idx_xxx ON table(column(n));
通过计算选择性(不重复值 / 总数)确定前缀长度。
九、覆盖索引
查询的字段全部在索引里,不需要回表查询。尽量避免 select *,只查需要的字段。
十、SQL 提示(手动指定索引)
sql
-- 建议使用
USE INDEX(索引名)
-- 忽略索引
IGNORE INDEX(索引名)
-- 强制使用
FORCE INDEX(索引名)
十一、索引设计原则
- 数据量大、查询频繁才建索引
- 常用于 where /order by /group by 的字段建索引
- 选择区分度高的列
- 长字符串用前缀索引
- 优先建联合索引,少建单列索引
- 控制索引数量,避免影响增删改
- 索引字段尽量 NOT NULL