MySQL重建表统计信息

发布时间 2024-01-01 15:27:41作者: 济南小老虎

MySQL重建表统计信息


背景

最近一段时间遇到了一些性能问题
发现很多其实都是由于 数据库的索引/统计信息不准确导致的问题. 
Oracle和SQLServer都遇到了很多类似的问题.

我这边联想到 MySQL也经常会出现卡顿的问题, 
所以想验证一下 MySQL如果重建表索引后不知道会不会好一些. 

重建的方法

MySQL官方资料里面最简单的重建方法是:
alter table tablename engine=innodb ; 

网上有很多来源:
https://geek-docs.com/mysql/mysql-ask-answer/356_mysql_how_can_i_rebuild_indexes_and_update_stats_in_mysql_innodb.html
https://dev.mysql.com/doc/refman/8.0/en/rebuilding-tables.html

感觉如果写SQL的话太麻烦了. 不如一个命令直接执行. 

mysql -uroot -pTestxxxx -D myapp2206mysql0721 <<EOS
SELECT CONCAT('ALTER TABLE ', table_name , ' ENGINE=INNODB ;')  FROM information_schema.tables  WHERE table_schema="myapp2206mysql0721" INTO OUTFILE '/tmp/mysqlrebuild.sql' ;
source /tmp/mysqlrebuild.sql
EOS

可以通过这个命令直接执行数据库的表重建动作. 

需要注意 ,需要先修改一下 my.conf 增加上可以进行 into outfile的处理参数
secure_file_priv = /tmp/

修改完成后需要重启数据库. 

关于数据库表的区别

PG数据库所有的表都是 堆组织表, 又称之为 HOT PG仅支持堆表
Oracle和SQLServer 其实大部分都是 堆组织表, 但是他们也支持堆组织表和局促表等存储模式
MySQL数据库的innodb存储引擎不支持堆表, 仅支持索引组织表 也就是IOT

这两种表的存储模式各有优缺点
堆表(heap table)和索引组织表(Index Oragnization Table,简称IOT)是两种数据表的存储结构。
pg中的表是堆表。mysql Innodb引擎中的表是索引组织表。oracle中既支持堆表,也支持索引组织表。

在具体介绍堆表和索引组织表之前,我们先看下pg中index scan和index only scan。
Index Scan: 也即普通索引扫描,对于给定的查询,我们先扫描一遍索引,从索引中找到符合要求的记录的位置(指针),
    再定位到表中具体的Page去取。等于是两次I/O,先走索引,再取表记录。
Index only scan: 建立index时,所包含的字段集合,囊括了我们需要查询的字段,
    这样就只需在索引中取数据,就不必访问表了。

索引组织表有些明显的好处: 
一是节约了磁盘空间,
二是降低了IO,提高了查询的性能。
    尤其是当我们的数据几乎总是通过主键来进行搜索时,查询效率的提升将会很显著。

缺点: 当索引组织表上有二级索引,并且频繁使用二级索引进行访问时,它的缺点也很明显了,
    那就是二级索引需要回表,它的效率要比堆表直接使用行指针访问数据的效率要低的。

总结一下:

堆表:数据存储在表中,索引存储在索引里,两者分开的。数据在堆中是无序的,
    索引让键值有序,但数据还是无序的。堆表中主键索引和普通索引一样的,都是存放指向堆表中数据的指针。

索引组织表:数据存储在聚簇索引中,或者说,数据按照主键的顺序来组织数据,两者合二为一。
    主键索引,叶子节点存放整行数据。其他索引称为辅助索引(二级索引),叶子节点存放键值和主键值。

来源: https://www.modb.pro/db/107906