information_schema系列十
1:INNODB_FT_CONFIG
这张表存的是全文索引的信息,查询前可以先通过以下语句查询一下开启全文索引的表:
show variables like 'innodb_ft_aux_table';
只有两个列还是相当的简单的:
name | Description |
KEY | The name designating an item of metadata for an InnoDB table containing a FULLTEXT index. |
VALUE | The value associated with the corresponding KEY column, reflecting some limit or current value for an aspect of a FULLTEXT index for an InnoDBtable. |
2:INNODB_FT_BEING_DELETED 和INNODB_FT_DELETED
INNODB_FT_BEING_DELETED 这张表是INNODB_FT_DELETED的一个快照。而且只在OPTIMIZE TABLE 的时候才会使用。OPTIMIZE TABLE 下面会好好讲一下。
每次开始执行OPTIMIZE TABLE的时候,INNODB_FT_BEING_DELETED都会被清空,这个表的生命周期是很短的。只有指定innodb_ft_aux_table的时候才会有值,一般情况下都是空的(INNODB_FT_DELETED也是)。
INNODB_FT_DELETED这个表就比较屌了,能够记录有全文索引的INNODB表被删除的行记录。这个表主要是为了避免DML语句执行的时候昂亏的索引充足才会记录被删除的行记录信息。 删除的记录不会被立即清除,而是存储在了INNODB_FT_DELETED中,只有当OPTIMIZE TABLE发生的时候才会被清除掉。这个表只有一个DOC__ID列,是指向innodb_ft_index_table 这张表。
3:INNODB_FT_INDEX_TABLE
这个表存储的是关于INNODB表有全文索引的索引使用信息的,同样这个表也是要设置innodb_ft_aux_table以后才能够使用的,一般情况下是空的。SET GLOBAL
innodb_optimize_fulltext_only=ON;
mysql> use test; mysql> CREATE TABLE articles ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, title VARCHAR(200), body TEXT, FULLTEXT (title,body) ) ENGINE=InnoDB;
mysql> INSERT INTO articles (title,body) VALUES ('MySQL Tutorial','DBMS stands for DataBase ...'), ('How To Use MySQL Well','After you went through a ...'), ('Optimizing MySQL','In this tutorial we will show ...'), ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), ('MySQL vs. YourSQL','In the following database comparison ...'), ('MySQL Security','When configured properly, MySQL ...');
mysql> SET GLOBAL innodb_optimize_fulltext_only=ON; Query OK, 0 rows affected (0.00 sec)
mysql> OPTIMIZE TABLE articles; +---------------+----------+----------+----------+ | Table | Op | Msg_type | Msg_text | +---------------+----------+----------+----------+ | test.articles | optimize | status | OK | +---------------+----------+----------+----------+ 1 row in set (0.00 sec) mysql> SET GLOBAL innodb_ft_aux_table = 'test/articles'; Query OK, 0 rows affected (0.00 sec) mysql> USE INFORMATION_SCHEMA;
mysql> SELECT word, doc_count, doc_id, position FROM INNODB_FT_INDEX_TABLE LIMIT 5; +------------+-----------+--------+----------+ | word | doc_count | doc_id | position | +------------+-----------+--------+----------+ | 1001 | 1 | 4 | 0 | | after | 1 | 2 | 22 | | comparison | 1 | 5 | 44 | | configured | 1 | 6 | 20 | | database | 2 | 1 | 31 | +------------+-----------+--------+----------+
INNODB_FT_DEFAULT_STOPWORD这个表存放的是stopword 的信息,怎么定义stopword 的信息可以以后补充一下:
5:INNODB_FT_INDEX_CACHE
这张表存放的是插入前的记录信息,也是为了避免DML时候昂贵的索引重组。我们可以通过设置以下两个变量来设置大小:
innodb_ft_cache_size 和 innodb_ft_total_cache_size.
下面详细看一下OPTIMEZE TABLE
首先看一下语法:
OPTIMIZE [NO_WRITE_TO_BINLOG | LOCAL] TABLE tbl_name [, tbl_name] ...
我们知道mysql存储引擎里面的数据和索引数据都是物理存储的,所以说为了减少空间使用和访问表的时候能有更好的IO表现,所以说当表执行OPTIMIZE TABLE的时候,是会发生切实的变化的.
一般以下集中情况下,我们会使用OPTIMIZE TABLE来进行优化:
1:在大量的插入,更新,或者删除INNODB表以后,我们再执行是很有必要的.此时如果执行OPTIMIZE TABLE的话,整表和表上所有的索引都会重组,而且不使用的表空间会被回收给操作系统.
2:在大量的插入,更新,或者删除有全文索引的INNODB表的字段以后,不过要首先设置innodb_optimize_fulltext_only=1,也可以通过指定innodb_ft_num_word_optimize 的值来指定能在索引里面更新多少记录.记录数满的时候就要通过OPTIMIZE TABLE来优化表.
3:在 MyISAM和 ARCHIVE 表做大量的删除的时候就需要执行OPTIMIZE TABLE,或者是 MyISAM和 ARCHIVE 表做了字段长度的更改,如果此时表中有大字段的话,就更需要执行OPTIMIZE TABLE 来优化表了.因为被删除的记录的位置还是会保存,并不会进行回收,等待新纪录插入,或者OPTIMIZE TABLE 进行重组才回回收.而且最重要的一点是OPTIMIZE TABLE以后性能会得到很大的提升,特别是表做过较大的变更以后在执行,性能提升会非常的明显.
OPTIMEZE TABLE 需要的权限:
对表insert 和 select权限.
而且OPTIMIZE TABLE 对分区表也是支持的,具体的语法是
ALTER TABLE t1 OPTIMIZE PARTITION p0, p1;
从上面就可以看出来OPTIMEZE TABLE对于INNODB,MyISAM和 ARCHIVE 的表都是适用的,对于其他引擎的数据表都是不适用的,如果想要使用OPTIMIZE TABLE 优化表,就要在启动mysqld的时候使用--skip-new参数启动.
OPTIMIZE TABLE 可以在线DDL,通过指定(ALGORITHM=INPLACE) ,不过这个只支持INNODB表,普通表和分区表都是支持的.表重建的方式有两种,OPTIMIZE TABLE 和 ALTER TABLE ... FORCE两种方式都可以触发表重建.
OPTIMIZE TABLE 也有适用于 ALGORITHM=COPY的一些条件:
1:当old_alter_table参数设置为ON的时候,OPTIMIZE并不会重建,而是使用一个临时表先把记录插进去来做处理.这个时候就要使用ALGORITHM=COPY来处理了.
2:当mysqld以--skip-new 为方式启动的时候
3:当INNODB表含有全文索引的时候 ,就只能够使用ALGORITHM=COPY来进行优化了
INNODB的数据存储是按照page-allocation的方式存储的,这和MYASIM引擎是不相同的,所以当我们考虑要OPTIMEZE一张表的时候,一定要先考虑以下的几个问题:
1:INNODB表的索引碎片是有所保留的,一般情况下是最多只能够占用93%的,剩余的一些是要保留起来用于update更新时候的页分裂来分配空间
2:删除操作会留下一部分的空间,只有当OPTIMIZE TABLE的时候才会重新的回收.
3:update的记录等于是对原有的数据页进行重新的写入,这和数据类型和行格式是有很大关系的.这个是有前提条件的,就是原有的页有足够的空间能够书写新数据.
4:高并发的情况下,会造成索引的间隙,这个产生的主要原因就是因为MySQL的事物是基于MVCC来实现的.
OPTIMIZE TABLE 对于MYASIM表的支持:
1:如果表有删除或者行拆分的话,就要repair table
2:如果索引页没有划分,就会重新划分索引页
3:统计信息如果不准确的话,就会重新更新统计信息
OPTIMIZE TABLE 返回信息尅看一下:
Column | Value |
Table | The table name |
Op | Always optimize |
Msg_type | status, error, info, note, or warning |
Msg_text | An informational message |
但是还要记住一点就是5.7.4以前的版本OPTIMIZE TABLE的时候会锁定全表,之后版本的INNODB表就就可以在线OPTIMIZE 了.而且更重要的是OPTIMIZE TABLE 会记录二进制日志,所以说对于复制的机器是会传送到slave上的.而且他对R-TREE结构的索引是不起作用的.
快速分析mysql的表信息,MYASIM引擎:
myisamchk --quick --check-only-changed --sort-index --analyze
重新组织表:
ALTER TABLE [tbl_name] TYPE=innodb
修改表行格式:
alter table your_table row_format=compressed
热衷于学习讨论MySQL和SQL Server,NoSQL等数据库技术,欢迎加入SQL优化群:659336691