索引语法
-
创建索引
CREATE [UNIQUE | FULLTEXT] INDEX index_name ON table_name (index_col_name, ...);
UNIQUE
:创建唯一索引,保证索引列中的值唯一。FULLTEXT
:创建全文索引,用于高效文本搜索。- 单列索引:对单个字段创建索引,例如
CREATE INDEX idx_name ON table_name(column_name);
。 - 联合索引:对多个字段组合创建索引,例如
CREATE INDEX idx_name ON table_name(column1, column2);
,可以提高多条件查询效率。
-
查看索引
SHOW INDEX FROM table_name;
- 显示指定表的所有索引信息,包括索引名称、字段等。
-
删除索引
DROP INDEX index_name ON table_name;
- 删除指定表上的索引,释放空间。
SQL执行频率
- 查询数据库操作频率:使用以下命令可以查看数据库中不同操作的执行频率,例如
INSERT
、UPDATE
、DELETE
、SELECT
等操作的统计信息。SHOW GLOBAL STATUS LIKE 'Com______';
session
:显示当前会话的状态信息。global
:显示全局状态信息。
慢查询日志
-
慢查询日志记录了所有执行时间超出指定参数(
long_query_time
,单位:秒,默认为10秒)的SQL语句的日志。- 查看慢查询日志是否开启:
SHOW VARIABLES LIKE 'slow_query_log';
-
配置文件(通常为
/etc/my.cnf
)中可开启慢查询日志并设定时间阈值:# 开启MySQL慢日志查询开关 slow_query_log=1 # 设置慢日志的时间为2秒,SQL语句执行时间超过2秒,就会视为慢查询,记录慢查询日志 long_query_time=2
- 查看慢查询日志是否开启:
Profile详情
- Profile:
SHOW PROFILES
命令在SQL优化时能够帮助我们了解每个查询的时间消耗情况。- 查询是否支持profiling功能:
SELECT @@have_profiling;
- 设置profiling的级别:
- Session级别:仅对当前会话生效,断开连接后失效。
SET profiling = 1;
- Global级别:对所有新建会话生效,已存在的会话不受影响。
SET GLOBAL profiling = 1;
- Session级别:仅对当前会话生效,断开连接后失效。
- 查看profiling状态:
- 当前会话的profiling状态:
SHOW VARIABLES LIKE 'profiling';
- 全局profiling状态:
SHOW GLOBAL VARIABLES LIKE 'profiling';
- 当前会话的profiling状态:
- 查看每条SQL的耗时基本情况:
SHOW PROFILES;
- 查看指定query_id的SQL语句各个阶段的耗时情况:
SHOW PROFILE FOR QUERY query_id;
- 查看指定query_id的SQL语句CPU的使用情况:
SHOW PROFILE CPU FOR QUERY query_id;
- 查询是否支持profiling功能:
EXPLAIN执行计划
EXPLAIN
或DESC
命令用于获取MySQL如何执行SELECT
语句的信息,包括执行过程中表的连接顺序和方式。- 语法:
EXPLAIN SELECT 字段列表 FROM 表名 WHERE 条件;
- 各字段含义:
- id:
SELECT
查询的序列号,表示查询中执行顺序,id
值越大越先执行。 - select_type:表示
SELECT
的类型,常见取值包括SIMPLE
(简单查询)、PRIMARY
(主查询)、UNION
(联合查询)、SUBQUERY
(子查询)等。 - type:表示连接类型,性能优劣由好到差为
NULL
、system
、const
、eq_ref
、ref
、range
、index
、all
。 - possible_keys:显示可能应用在这张表上的索引,一个或多个。
- key:实际使用的索引,如果为
NULL
,则没有使用索引。 - key_len:表示索引中使用的字节数,该值表示字段最大可能长度,并非实际使用长度,在不损失精确性的前提下,长度越短越好。
- rows:MySQL认为必须要执行并读取的行数,这个值是一个估计值,可能不总是准确的。
- filtered:表示返回结果的行数占需读取行数的百分比,
filtered
值越大越好。
- id:
- 语法:
SQL提示
SQL提示是优化数据库的一个重要手段,简而言之,是在SQL语句中人为地加入提示来达到优化的目的。
- use index:提示MySQL使用指定索引。
EXPLAIN SELECT * FROM tb_user USE INDEX(idx_user_pro) WHERE profession = '软件工程';
- ignore index:提示MySQL忽略指定索引。
EXPLAIN SELECT * FROM tb_user IGNORE INDEX(idx_user_pro) WHERE profession = '软件工程';
- force index:提示MySQL强制使用指定索引。
EXPLAIN SELECT * FROM tb_user FORCE INDEX(idx_user_pro) WHERE profession = '软件工程';
前缀索引
- 当字段类型为字符串(如
VARCHAR
、TEXT
等)时,如果索引需要的字符串很长,索引会变得很大,影响查询效率。此时可以只将字符串的前部分作为前缀建立索引,以节约空间并提高效率。- 语法示例:
CREATE INDEX idx_xxxx ON table_name(column(n));
- 其中
n
表示前缀长度,可以根据实际需求设定适当的值。
- 语法示例:
覆盖索引与回表
- 覆盖索引:查询中所有需要的字段都包含在索引中,不需要回表即可获取所有数据,从而提高查询效率。此时
EXPLAIN
输出的Extra
字段中会显示Using index
。 - 回表:当查询的字段不完全包含在索引中时,MySQL需要通过索引定位到数据行,然后返回表中读取其他字段的数据。这种操作称为回表,增加了查询的开销。
最左前缀法则
- 最左前缀法则指的是在多列联合索引中,查询时要遵循索引从左到右的顺序,否则索引可能失效。例如,对于
(a, b, c)
的联合索引:WHERE a = 1
、WHERE a = 1 AND b = 2
、WHERE a = 1 AND b = 2 AND c = 3
可以使用索引。- 但
WHERE b = 2
、WHERE c = 3
无法使用索引。
索引失效的情况
- 不满足最左前缀法则:如在联合索引中没有从最左侧开始使用。
- 对索引字段使用函数:如
WHERE LEFT(name, 3) = 'abc'
。 - 对索引字段进行计算:如
WHERE age + 1 = 21
。 - 使用
!=
或<>
:如WHERE age != 10
。 - 使用
IS NULL
或IS NOT NULL
:有时会导致索引失效。 - 使用
LIKE
时以通配符%
开头:如WHERE name LIKE '%abc'
。 - 数据类型隐式转换:如
WHERE varchar_field = 123
(数字被隐式转换为字符串)。 - 范围条件后再使用索引列:如
WHERE a = 1 AND b > 2 AND c = 3
,c
列无法使用索引。