MySQL索引

MySQL索引

  • MySQL架构
  • 索引优化分析
    • 索引的概念
    • 索引的优势
    • 索引的劣势
    • 索引的基本语法
    • 索引分类
      • 单值索引
      • 唯一索引
      • 复合索引
    • MySQL索引结构(主讲:BTree索引)
      • BTree索引
    • MySQL性能分析
      • MySQL Query Optimizer(MySQL查询优化器)
      • MySQL的常见瓶颈
      • Explain
    • MySQL索引优化
      • 索引分析(案例)
      • 索引失效(应该如何避免)
      • 索引面试题分析
      • 一般性建议
  • 查询截取分析
    • 查询优化
    • 慢查询日志
    • show profile
    • 全局查询日志(测试环境用)

MySQL架构

MySQL索引_第1张图片

连接器:用于处理MySQL客户端连接和权限验证。
分析器:SQL词法、语法分析。
优化器:MySQL会根据规则将输入的SQL命令,会开启自我优化分析,自动优化到最佳效果。
存储引擎:存储引擎有多种,查看存储引擎指令为:show engines;。常用如下两种存储引擎。查看默认存储引擎和当前存储引擎show variables like '%storage_engine%';
1、MyISAM
2、InnoDB
二者区别如下

对比项 MyISAM InnoDB
主外键 不支持 支持
事务 不支持 支持
行表锁 表锁,即使操作一条记录也会锁住整个表,不适合高并发的操作 行锁,操作只锁住某一行,不对其他行有影响。适合高并发的操作
缓存 只缓存索引,不缓存真实数据 不仅缓存索引还要缓存真实数据,对内存要求高,而且内存大小对性能有决定性的影响
表空间
关注点 性能 事务
默认安装 Y Y

索引优化分析

索引的概念

MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构。可以得到索引的本质:索引数据结构。可以理解为"排好序的快速查找的数据结构"
一般来说索引本身也很大,不可能全部存储在内存中,因此索引往往以文件的形式存储在磁盘上。我们平常说的索引,如果没有特别指明,都是值B树(多路搜索树,并不一定是二叉的)结构组织的索引。其中,聚集索引、次要索引、复合索引、前缀索引、唯一索引默认都是B+树索引,统称索引。当然,除了B+树这种索引之外,还有哈希索引(hash index)等。

索引的优势

1、提高数据检索的效率,降低数据库的IO成本
2、通过索引对数据进行排序,减低数据排序的成本,降低CPU的消耗
即:索引具有提高检索数据的效率和对数据排序的优点。

索引的劣势

实际上索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录,所以索引列也是要占用空间的。虽然索引大大提高了查询的速度,同时也会降低了更新表(对表进行insert、update、delete)的速度,因为在更新表时,MySQL不仅要保存数据,还要保存一下索引文件每次更新添加了索引列的字段,都会调整因为更新所带来的键值变化后的索引信息。索引只是提高效率的一个因素,如果MySQL有大数据量的表,就需要花时间研究建立最优秀的索引,或优化查询

索引的基本语法

# 逻辑分区
# 普通索引
create index <索引名> on <表名>(字段名);
# 唯一索引
create unique index <索引名> on <表名>(字段名);
# 主键索引
-- 主键索引就是专门为主键字段创建的索引,也是索引的恶意中,主键索引是一种特殊的索引。
-- 不允值重复或者值为空,创建主键索引通常使用primary key关键字,不能使用create index
-- 语句创建索引
# 空间索引
create spatial index <索引名> on <表名>(字段名);
# 全文索引
create fulltext index <索引名> on <表名>(字段名);

# 实际使用区分
# 单列索引
create index <索引名> on <表名>(<字段名>);
# 组合索引
create index <索引名> on <表名>(<字段名1>[,<字段名2> ...]);

# MySQL创建索引
# MySQL提供三种创建索引的方法:
# 1、使用create index语句,语法格式如下:
create index <索引名> on <表名>(<列名>[<长度>][ASC|DESC]); 
# 2、建表的时候指定索引字段
# 3、修改表的时候添加索引
alter table <表名> add <索引类型> 索引名(<column_list>);

MySQL查看索引
show index from <表名|数据库名>\G;

MySQL删除索引
drop index <索引名> on <表名>;

索引分类

建议表中的索引不要超过 5 个。

单值索引

即一个索引只包含单个列,一个表可以有多个单值索引。

唯一索引

索引列的值必须唯一,但允许有空值。

复合索引

即一个索引包含多个列。

MySQL索引结构(主讲:BTree索引)

1、BTree索引
2、Hash索引
3、full-text全文索引
4、R-Tree索引

BTree索引

1、检索原理
MySQL索引_第2张图片
2、哪些情况需要创建索引

1、主键自动创建唯一索引
2、频繁作为查询的字段应该创建索引
3、查询中与其他表关联的字段,外键关系建立索引
4、单值/组合索引的选择问题,到底选择谁?(在高并发下倾向创建组合索引)
5、查询中排序的字段,排序字段若通过索引去访问将大大提高排序速度
6、查询中统计或分组的字段

3、哪些情况不要创建索引

1、表记录太少
2、经常增删改的表
频繁更新的字段不适合创建索引,因为每次更新不单单是更新了记录还会更新索引树。虽然提高了查询速度,同时汇缴地更新表的速度,如对标进行insert、update、delete,因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。
3、数据重复且平均的表字段,因此应该职位最经常查询和最经常排序的数据建立索引。注意,如果某个数据列包含许多重复的内容,为他建立索引就没有太大的实际效果。
4、where条件里用不到的字段不创建索引

MySQL性能分析

MySQL Query Optimizer(MySQL查询优化器)

1、MySQL中有专门的负责优化 select 语句的优化器模块,主要功能:通过计算分析系统中收集到的统计信息,为客户端请求的 Query 提供他认为最优秀的执行计划(他认为最优的检索方式,但不见的是DBA认为是最优的)
2、当客户端向MySQL请求一条Query,命令解释器模块完成请求分类,区别出是select并转发给MySQL Query Optimizer时,MySQL Query Optimizer 首先会对整条Query进行优化,处理掉一些常量表达式的预算,直接换算成常量值,并对Query中的查询条件进行简化和转换,如去掉一些无用或显而易见的条件,结构调整等。然后Query中的Hint(提示)信息(如果有),看显示Hint信息是否可以完全确定该Query的执行计划。如果没有Hint或Hint信息还不足以完全确定执行计划,则会读取所涉及对象的统计信息,根据Query进行写相应的计算分析,然后在得出最后的执行计划。

MySQL的常见瓶颈

CPU:CPU在饱和的时候,一般发生在数据装入内存或从磁盘中读取数据时候
IO:磁盘 I/O 瓶颈发生在装入数据远大于内存容量的时候
服务器硬件性能瓶颈:top,tree,iostat 和 vmstat 来查看系统的性能状态

Explain

1、查看执行计划

使用explain关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理你的SQL语句的。分析你的查询语句或是表结构的性能瓶颈。

2、Explain能干什么?

能查看
1、表的读取顺序
2、数据读取操作的操作类型
3、那些索引可以使用
4、那些索引被实际使用
5、表之间的引用
6、每张表有多少行被优化器查询

3、Explain如何使用?

1、explain + SQL查询语句
2、执行计划包含的信息
在这里插入图片描述

4、执行计划表头信息字段解析:

id:select查询的序列号,包含一组数字,表示查询中select字句或操作表的读取顺序

三种情况:
(1)id相同,加载表的执行顺序从上至下。
(2)id不同,如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行
(3)id相同有不同:同时存在。id如果相同,可以认为是一组,从上往下顺序执行;在所有的组中id值越大,优先级越高,越先执行。
derived:派生、衍生。

select_type:查询的类型。

1、select_type的值:
MySQL索引_第3张图片
2、查询的类型:主要用于区别 普通查询、联合查询、子查询等复杂查询
(1)SIMPLE:简单的select查询,查询中不包含子查询或者UNION。
(2)PRIMARY:查询中若包含任何复杂的子部分,最外层查询则被标记为PRIMARY。
(3)SUBQUERY:在 selec t或 where 列表中包含了子查询。
(4)DERIVED:在 from 列表中包含的子查询被标记为DERVICED(衍生),MySQL会递归执行这些子查询,把结果放在临时表里。
(5)UNION:若在第二个select出现在UNION之后,则被标记为UNION;若UNION包含在from字句的子查询中,外层select将被标记为:DERVED
(6)UNION RESULT:从UNION表获取结果的select

table:数据表名

type:访问类型,显示查询使用了何种类型。

1、访问类型的值:
在这里插入图片描述
2、访问类型排序
结果从最好到最坏依次是
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > range > index > ALL
需要记住的访问类型排序(工作中常用):
system > const > eq_ref > ref > range > index > ALL
一般来说,得保证查询至少达到range级别,最好能达到ref。

system:表中只有一行记录(等于系统表),这是const类型的特例。
const:表示通过索引一次就找到了,const用于表示primary key或者unique索引。因为职匹配一行数据,所以很快。如将逐渐至于where列表中,MySQL就能将该查询转换为一个常量。
eq_ref:唯一索引扫描,对于每个索引键,表中只有一条记录与之匹配。常见于主键或唯一索引扫描
ref:非唯一性索引扫描,返回匹配某个单独值的所有行,本质上也是一种索引访问,他返回所有匹配某个单独指的所有行。然而他可能会找到多个符合条件的行,所以他应该属于查找和扫描的混合体。
range:只检索给定范围的行,使用一个索引来选择行。key列显使用了哪个索引,一般就是在你的where语句中出现了between、<、>、in 等的查询,这种范围扫描索引比全表扫描要好,只因为他需要开始于索引的某一点,而结束于另一点,不用全表扫描。
index:Full index Scan(全索引扫描),index与ALL区别为index类型只遍历索引树。通常比ALL快,以为索引文件通常比数据小。(也就是说虽然ALL和index都是读全表,但是index是从索引中读取的,而ALL是从硬盘中读的)。
ALL:Full Table Scan(全表扫描),将遍历全表以找到匹配的行。
备注:一般来说,得保证查询至少达到 range 级别,最好能到到 ref 。

possible_key:显示可能应用在这张表中的索引,一个或多个。查询涉及到的字段若存在索引,则该索引被列出来,但不一定被查询实际使用。

key:实际使用的索引。如果为null,则没有使用索引;查询中若使用了覆盖索引,则该索引仅出现在key列表中,possible_key为null。覆盖索引指的是select查询的字段列表和复合索引的字段与顺序一一对应

key_len:表示索引中使用的字节数,可通过该列计算查询中使用的索引长度。在不损失精确性的情况下,长度越短越好。key_len显示的值为索引字段的最大长度,并非实际使用长度,即:key_len是根据定义计算而得,不是通过表内检索出的。

# 总结key_len的长度计算公式
varchar10)变长且允许null10*character set:utf8=3,gbk=2,latin1=1+1null+2(变长字段)
varchar10)变长字段且不允许null10*character set:utf8=3,gbk=2,latin1=1+2(变长字段)
char10)固定字段且允许null10*character set:utf8=3,gbk=2,latin1=1+1nullchar10)固定长度且不允许为null10*character set:utf8=3,gbk=2,latin1=1

ref:显示索引的哪一列被使用,如果可能的话,是一个常数。哪些列或常量被用于查找索引列上的值。

rows:根据表统计信息及索引选用情况,大致估算出找到所需的记录所需要读取的行数。

Extra:包含不是和在其他列中显示但十分重要的额外信息。

1、Using filesort(文件类排序):说明MySQL会对数据使用一个外部索引排序,而不是按照表内的索引顺序进行读取。MySQL中无法利用索引完成排序操作成为 “文件排序”。
2、Using temporary(临时表):使用了临时表保存中间结果,MySQL在对查询结果排序使用临时表,常用于排序 order by 和分组查询 group by
3、Using index:表示相应的select操作使用了覆盖索引(Covering Index),避免访问了表的数据行,效率不错!如果同时出现using where,表明索引覆盖被用来执行索引键值的查找;如果没有同时出现using where,表明索引引用来读取数据而非执行查找动作。

覆盖索引

所谓索引覆盖。就是select的数据列只用从索引中就能获得,不必读取数据行,MySQL可以利用索引返回select列表中的字段,而不必根据索引再次读取数据文件,换句话说:查询列要被所见的索引覆盖。
注意:如果要使用索引覆盖,一定要注意select列表中只许出现索引列,不可使用select *。因为如果将所有的字段一起做索引回到值索引文件过大,查询性能降低。

MySQL索引优化

索引分析(案例)

1、单表

EXPLAIN SELECT id,author_id FROM article WHERE category_id = 1 AND comments > 1 ORDER BY views DESC LIMIT1;
EXPLAIN SELECT id,author_id FROM article WHERE category_id = 1 AND comments = 3 ORDER BY views DESC LIMIT1;
#结论:
#type变成了range,这是可以忍受的。但是extra里使用Using filesort仍是无法接受的。
#但是我们已经建立了索引,为啥没用呢?
#这是因为按照BTree 索引的工作原理,
#先排序category_id,
#如果遇到相同的category_id则再排序comments,如果遇到相同的comments则再排序views。
#当comments字段在联合索引里处于中间位置时,
#因comments >1条件是一个范围值(所谓range),
#MySQL无法利用索引再对后面的views部分进行检索,即range类型查询字段后面的索引无效。

#原因浅析:
# '>' 或 '<'符号表示范围,当索引字段用到表示范围,该索引字段之后的字段全部失效。

#解决的方式:
#创建除作为范围的条件字段的符合索引。

2、两表

#在驱动表的条件字段添加索引;驱动表:左外连接,右表为驱动表。右外连接,左表为驱动表。
#左外连接 left join ,在右表条件字段添加索引,如下:
explain select * from t1 left join t2 on t1.card = t2.card;
# 为 t2 表的 card 字段添加索引
alter table t2 add index ix_t2_card(card);

#右外连接 right join ,在右表条件字段添加索引,如下:
explain select * from t3 right join t4 on t3.card = t4.card;
# 为 t1 表的 card 字段添加索引
alter table t3 add index ix_t3_card(card);

3、三表

1、在驱动表的条件字段添加索引;驱动表:左外连接,右表为驱动表。右外连接,左表为驱动表。
2、join语句的优化:小表驱动大表。索引需要建立在经常查询的字段当中。
(1)尽可能减少 join 中的 NestedLoop 循环总次数:" 永远用小结果接驱动大的结果集 "。
(2)优先优化 NestedLoop 的内层循环。
(3)保证 join 语句中被驱动表上 join 条件字段已经被索引。
(4)当无法保证驱动表的 join 条件字段被索引且内存资源充足前提下,不要吝啬 JoinBuffer 的设置。

索引失效(应该如何避免)

索引失效的前提:首先应该有创建了有效的索引。

1、全值匹配:查询条件包含全部索引字段。
2、最佳左前缀法则:如果索引了多列,要遵守最佳左前缀法则。指的是查询从索引的最左前列开始并且不能跳过索引中的列。(类比火车头与车厢)
3、不在索引列上做任何操作(包括计算、函数、(自动或手动)类型转换等等),会导致索引失效而转向全表扫描
4、存储引擎不能使用索引中范围条件右边的列
5、尽量使用索引覆盖(只访问索引的查询(索引列和查询列一致)),减少select *
6、MySQL在使用不等于(!= 或 <>)的时候无法使用索引会导致全表扫描
7、is null 、is not null 也无法使用索引
8、like 以通配符开头(’%abc…’),MySQL索引失效会标称全表扫描的操作

如何解决 '%abc...%' 导致的索引失效?
使用覆盖索引来解决,避免全表扫描

9、字符串不加单引号会索引失效

select * from users where name = '2000';

# 此处进行了隐式的类型转换,int类型转换成字符串类型。见第 3 点。
# 条件索引列进行了操作,导致索引失效
select * from users where name = 2000; 

10、少用or,用它来连接时会索引失效

总结:(练习)

where语句 索引是否被使用
where a= 3 Y,使用到a
where a=3 and b=5 Y,使用到a,b
where a=3 and b=5 and c=4 Y,使用到了a,b,c
where b=3或者where b=3 and c=4或者where c=4 N
where a=3 and c=5 Y,使用到a,但c不能用,b中间断了
where a=3 and b>4 and c=5 Y,使用到a,b,但c不能用在范围之后,b断了
where a=3 and b like ‘kk%’ and c=4 Y,使用到a,b,c
where a=3 and b like ‘%kk’ and c=4 Y,只使用到a
where a=3 and b like ‘%kk%’ and c=4 Y,只使用到a
where a=3 and b like ‘k%kk%’ and c=4 Y,使用到a,b,c

索引面试题分析

1、索引列与创建的的索引字段顺序 index_name(ix1,ix2,ix3,…)无关,只要用到,MySQL的优化器会自动将其最优化处理,类比(1+2+3 = 3+2+1)结果一样。
2、定值、范围还是排序,一般 order by 是给个范围
3、group by 基本上都需要进行排序,会有临时表产生

一般性建议

1、对于单值索引,尽量选择针对当前query过滤性更好的索引。
2、在选择组合索引的时候,当前query中过滤性最好的字段在索引字段顺序中,位置越靠前越好。
3、在选择组合索引的时候,尽量选择可以能够包含当前query中的where字句中更多字段的索引。
4、尽可能通过分析统计信息和调整query的写法来达到选择合适索引的目的。

查询截取分析

查询截取分析的工作?

1、观察,至少跑一天,看看生产环境的慢SQL情况
2、开启慢查询日志,设置阀值,比如超过 2 秒的就是慢SQL,并将它抓取出来。
3、explain + 慢SQL分析
4、show profile
5、运维经理、DBA,进行SQL数据库服务器的参数调优。
总结

1、慢查询的开启并捕获
2、explain +慢SQL分析
3、show profile 查询SQL在MySQL服务器里面的执行细节和生命周期情况
4、进行SQL数据库服务器的参数调优。

查询优化

1、永远小表驱动大表*(原理RBO,基于规则优化),类似嵌套循环Nested Loop

# 当B表的数据集必须小于A表的数据集时,用 in 优于 exists:
select * from A where id in(select id from B)
等价于
for select id from B
for select * from A where A.id = B.id

# 当A表的数据集必须小于B表的数据集时,用 exists 优于 in:
select * from  A where exists (select 1 from B where B.id = A.id)
等价于
for select * from A
for select * from B where B.id = A.id

# 注意:A表与B表的 id 字段应建立索引。

# exists 
# 语法:select ... from table where exists (subQuery)
# 可以理解为:将主查询的数据,放到子查询中做条件验证,根据验证结果(true 或 false)
# 来决定主查询的数据结果是否得以保留

2、order by 关键字优化

(1)order by 字句,尽量使用 Index 方式排序,避免使用 FileSort 方式排序。

1、MySQL支持两种方式的排序,FileSort和Index,Index效率高。它指MySQL扫描索引本身完成排序。FileSort方式效率低。
2、order by 满足两种情况,会使用Index方式排序:
(a)order by 语句使用最左前列
(b)使用 where 字句与order by字句条件组合满足索引最左前列

(2)尽可能在索引列上完成排序操作,遵守索引建的最佳左前缀规则。
(3)如果不在索引列上,FileSort的两种算法:MySQL就要启动双路排序和单路排序。
(4)优化策略。

1、增大sort_buffer_size参数设置
2、增大max_length_for_sort_data参数设置

提高Order By的速度

1.Order byselect是一个大忌只Query需要的字段,这点非常重要。在这里的影响是:
1.1当Query的字段夹小总和小于max_length_for_sort_data而且排序字段不是TEXT|IBLOB类型时,
会用改进后的算法一—单路排序,否则用老算法——多路排序。
1.2两种算法的数据都有可能超出sort_buffer的容量,超出之后,会创建tmp文件进行合并排序,
导致多次I/O,但是用单路排序算法的风险会更大一些,所以要提高sort_buffer_size。

2.尝试提高sort_buffer_size
不管用哪种算法,提高这个参数都会提高效率,当然,要根据系统的能力去提高,因为这个参数是针对每个进程的

3.尝试提高max_length_for_sort_data
提高这个参数,会增加用改进算法的概率。但是如果设的太高,数据总容量超出sort_buffer_size的概率就增大,
明显症状是高的磁盘I/O活动和低的处理器使用率.

MySQL索引_第4张图片
3、group by 关键字优化

1、group by 实质是指先排序后进行分组,遵照索引见得最佳左前缀
2、当无法使用索引列,增大max_length_for_sort_data参数的设置+增大sort_buffer_size参数设置
3、where 高于having,能卸载where限定的条件就不要去having限定了。

慢查询日志

慢查询日志的概念?

MySQL的慢查询日志是MySQL提供的一种日志记录,他用来记录在MySQL中响应时间超过阀值query语句,具体指用来记录运行时间超过long_query_time值的SQL语句。该SQL会被记录到慢查询日志中。
long_query_time:SQL语句执行时间,默认值为:10s(秒)。
默认情况下,MySQL数据库没有开启慢查询日志,需要手动设置参数。当然,没有调优需要,一般不启动该参数,开启慢查询日志也会或多或少对性能带来一定影响。慢查询日志支持将日志记录写入文件。

慢查询日志参数配置和使用?

1、查看是否开启及如何开启慢查询日志

# 查看:(默认设置不开启慢查询日志)
show variables like '%slow_query_log%';
# 开启,关闭设置为0。使用此命令只对当前MySQL数据库生效,如果重启会失效。:
set global slow_query_log = 1; 

2、设置慢查询的阀值,记录慢SQL:

# 查看慢查询设置的运行阀值时间:
show variables like '%long_query_time%';
# 这是慢查询日志阀值时间:(设置好后新开一个会话是使用上面命令查看)
# 或使用 show global variables like '%long_query_time%';进行查看
set global long_query_time = 2;

3、测试
(1)先查询

#使用如下命令查询测试:
select sleep(5); #类比java中的线程睡眠时间
#查看慢查询日志文件路径:
show variables like '%slow_query_log%';

(2)查看日志

# linux系统下
cat <慢查询日志文件路径>

慢查询日志分析工具(mysqldumpslow)
MySQL索引_第5张图片
工作常用参考(案例)

# 得到返回记录集最多的10个SQL
mysqldumpslow -s r -t 10 /var/lib/mysql-slow.log

# 得到访问次数最多的10个SQL
mysqldumpslow -s c -t 10 /var/lib/mysql-slow.log

# 得到按照时间排序的前10条里面含有左连接的查询语句
mysqldumpslow -s t -t 10 -g "left join" /var/lib/mysql/mysql-slow.log

# 另外建议在使用这些命令时结合│和more 使用,否则有可能出现爆屏情况
mysqldumpslow -s r -t 10 /var/lib/mysql/mysql-slow.log | more

show profile

1、show profile是什么?
是MySQL提供可以用来分析当前会话中语句执行的资源消耗情况。可以用于SQL优化的测量。
2、状态
默认情况下,参数处于关闭状态,并保存最近15次的运行结果。
3、分析步骤
(1)是否支持,看看当前的MySQL版本是否支持:show variables like 'profiling' 或 'profiling%';
(2)开启功能,默认是关闭,使用前需要开启:set profiling = on;
(3)运行SQL
(4)查看结果,show profiles;
(5)诊断SQL,show profile cpu,block io for query < Query_ID > 上一步前面的问题SQL数字号码( Query_ID);诊断参数如下:

参数 含义
ALL 显示所有的开销信息
BLOCK IO 显示块lO相关开销
CONTEXT SWITCHES 上下文切换相关开销
CPU 显示CPU相关开销信息
IPC 显示发送和接收相关开销信息
MEMORY 显示内存相关开销信息
PAGE FAULTS 显示页面错误相关开销信
SOURCE 显示和Source_function,Source_file,Source_line相关的开销信息
SWAPS 显示交换次数相关开销的信息

(6)日常开发需要注意的结论

1、converting HEAP to MyISAM 查询结果集太大,内存都不够用了往磁盘上搬了。
2、Creating tmp table 创建临时表:
(1)拷贝数据到临时表
(2)用完再删除
3、Copying to tmp table on disk 把内存中临时表复制到磁盘,危险!!
4、locked

全局查询日志(测试环境用)

1、配置启用

#在mysql的my.cnf中,设置如下:
#开启
general_log=1
#记录日志文件的路径
general_log_file=/path/logfile#输出格式
log_output=FILE

2、编码启用

set global general_log = 1;
set global log_output = 'TABLE';
# 此后,你所编写的 sql 语句,将会记录到 mysql 数据库里的general_log表,可以用下面的命令查看。
select * from mysql.general_log;

注意:永远不要在生产环境开启此功能。

你可能感兴趣的:(MySQL,MySQL索引优化,mysql)