事务处理对长期统计信息自动收集的影响

打印 上一主题 下一主题

主题 2301|帖子 2301|积分 6903

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
事务处理对长期统计信息自动收集的影响

1. 长期化统计信息

长期统计信息将统计信息存储到磁盘,使它们在服务器重启后保持不变,优化器更有大概在查询时做出一致的选择,从而进步执行计划的稳固性。
在innodb_stats_persistent=ON(默认值)或表定义利用 stats_persistent=1时,优化器统计信息会长期化保存。
长期统计信息存储在 mysql.innodb_table_stats 和 mysql.innodb_index_stats 表中,last_update 列可以看到前次更新统计信息的时间。
系统变量innodb_stats_auto_recalc(默认ON)控制表行更改凌驾10%时,是否自动计算统计信息。也可以通过创建或更改表时指定stats_auto_recalc子句为单个表配置自动统计重新计算。
由于自动统计信息收集是一个后台线程,其处理过程与DML操作是异步的,在DML操作凌驾 10% 的表后,大概不会立即重新计算统计信息。在某些环境下,统计数据重新计算大概会延迟几秒钟。如果立即需要最新的统计信息,执行 ANALYZE TABLE 以启动统计信息的同步计算。
事务的 commit 和 rollback 会影响统计信息的自动收集么?通过下面测试,可以回答这问题。
2. 测试commit和rollback对长期统计信息收集的影响

测试环境的系统变量值:
  1. greatsql> SHOW GLOBAL VARIABLES LIKE 'innodb_stats%';
  2. +--------------------------------------+-------------+
  3. | Variable_name                        | Value       |
  4. +--------------------------------------+-------------+
  5. | innodb_stats_auto_recalc             | ON          |
  6. | innodb_stats_include_delete_marked   | OFF         |
  7. | innodb_stats_method                  | nulls_equal |
  8. | innodb_stats_on_metadata             | OFF         |
  9. | innodb_stats_persistent              | ON          |
  10. | innodb_stats_persistent_sample_pages | 20          |
  11. | innodb_stats_transient_sample_pages  | 8           |
  12. +--------------------------------------+-------------+
复制代码
2.1 INSERT 操作
  1. greatsql> TRUNCATE TABLE test1;
  2. Query OK, 0 rows affected (0.05 sec)
  3. -- 开启事务,在空表test1中插入10万行数据
  4. greatsql> BEGIN;
  5. Query OK, 0 rows affected (0.00 sec)
  6. greatsql> SELECT now();INSERT INTO test1 SELECT * FROM LIMIT 100000;SELECT now();
  7. +---------------------+
  8. | now()               |
  9. +---------------------+
  10. | 2025-01-07 09:59:19 |
  11. +---------------------+
  12. 1 row in set (0.00 sec)
  13. Query OK, 100000 rows affected (2.73 sec)
  14. Records: 100000  Duplicates: 0  Warnings: 0
  15. +---------------------+
  16. | now()               |
  17. +---------------------+
  18. | 2025-01-07 09:59:21 |
  19. +---------------------+
  20. 1 row in set (0.00 sec)
  21. -- 事务没有提交,但统计信息已收集
  22. greatsql> SELECT * FROM mysql.innodb_index_stats WHERE database_name='testdb1' AND table_name='test1';
  23. +---------------+------------+------------+---------------------+--------------+------------+-------------+-----------------------------------+
  24. | database_name | table_name | index_name | last_update         | stat_name    | stat_value | sample_size | stat_description                  |
  25. +---------------+------------+------------+---------------------+--------------+------------+-------------+-----------------------------------+
  26. | testdb1       | test1      | PRIMARY    | 2025-01-07 09:59:19 | n_diff_pfx01 |         11 |           1 | id                                |
  27. | testdb1       | test1      | PRIMARY    | 2025-01-07 09:59:19 | n_leaf_pages |          1 |        NULL | Number of leaf pages in the index |
  28. | testdb1       | test1      | PRIMARY    | 2025-01-07 09:59:19 | size         |          1 |        NULL | Number of pages in the index      |
  29. | testdb1       | test1      | k_1        | 2025-01-07 09:59:19 | n_diff_pfx01 |         11 |           1 | k                                 |
  30. | testdb1       | test1      | k_1        | 2025-01-07 09:59:19 | n_diff_pfx02 |         11 |           1 | k,id                              |
  31. | testdb1       | test1      | k_1        | 2025-01-07 09:59:19 | n_leaf_pages |          1 |        NULL | Number of leaf pages in the index |
  32. | testdb1       | test1      | k_1        | 2025-01-07 09:59:19 | size         |          1 |        NULL | Number of pages in the index      |
  33. +---------------+------------+------------+---------------------+--------------+------------+-------------+-----------------------------------+
  34. 7 rows in set (0.00 sec)
  35. greatsql> SELECT * FROM mysql.innodb_index_stats WHERE database_name='testdb1' AND table_name='test1';
  36. +---------------+------------+------------+---------------------+--------------+------------+-------------+-----------------------------------+
  37. | database_name | table_name | index_name | last_update         | stat_name    | stat_value | sample_size | stat_description                  |
  38. +---------------+------------+------------+---------------------+--------------+------------+-------------+-----------------------------------+
  39. | testdb1       | test1      | PRIMARY    | 2025-01-07 09:59:29 | n_diff_pfx01 |      98712 |          20 | id                                |
  40. | testdb1       | test1      | PRIMARY    | 2025-01-07 09:59:29 | n_leaf_pages |       1371 |        NULL | Number of leaf pages in the index |
  41. | testdb1       | test1      | PRIMARY    | 2025-01-07 09:59:29 | size         |       1379 |        NULL | Number of pages in the index      |
  42. | testdb1       | test1      | k_1        | 2025-01-07 09:59:29 | n_diff_pfx01 |      30169 |          20 | k                                 |
  43. | testdb1       | test1      | k_1        | 2025-01-07 09:59:29 | n_diff_pfx02 |     100268 |          20 | k,id                              |
  44. | testdb1       | test1      | k_1        | 2025-01-07 09:59:29 | n_leaf_pages |        128 |        NULL | Number of leaf pages in the index |
  45. | testdb1       | test1      | k_1        | 2025-01-07 09:59:29 | size         |        161 |        NULL | Number of pages in the index      |
  46. +---------------+------------+------------+---------------------+--------------+------------+-------------+-----------------------------------+
  47. 7 rows in set (0.00 sec)
  48. -- 回滚事务
  49. greatsql> ROLLBACK;
  50. Query OK, 0 rows affected (2.64 sec)
  51. -- 没有重新收集统计信息,统计信息与表数据不匹配
  52. greatsql> SELECT * FROM mysql.innodb_index_stats WHERE database_name='testdb1' AND table_name='test1';
  53. +---------------+------------+------------+---------------------+--------------+------------+-------------+-----------------------------------+
  54. | database_name | table_name | index_name | last_update         | stat_name    | stat_value | sample_size | stat_description                  |
  55. +---------------+------------+------------+---------------------+--------------+------------+-------------+-----------------------------------+
  56. | testdb1       | test1      | PRIMARY    | 2025-01-07 09:59:29 | n_diff_pfx01 |      98712 |          20 | id                                |
  57. | testdb1       | test1      | PRIMARY    | 2025-01-07 09:59:29 | n_leaf_pages |       1371 |        NULL | Number of leaf pages in the index |
  58. | testdb1       | test1      | PRIMARY    | 2025-01-07 09:59:29 | size         |       1379 |        NULL | Number of pages in the index      |
  59. | testdb1       | test1      | k_1        | 2025-01-07 09:59:29 | n_diff_pfx01 |      30169 |          20 | k                                 |
  60. | testdb1       | test1      | k_1        | 2025-01-07 09:59:29 | n_diff_pfx02 |     100268 |          20 | k,id                              |
  61. | testdb1       | test1      | k_1        | 2025-01-07 09:59:29 | n_leaf_pages |        128 |        NULL | Number of leaf pages in the index |
  62. | testdb1       | test1      | k_1        | 2025-01-07 09:59:29 | size         |        161 |        NULL | Number of pages in the index      |
  63. +---------------+------------+------------+---------------------+--------------+------------+-------------+-----------------------------------+
  64. 7 rows in set (0.00 sec)
  65. greatsql> SELECT COUNT(*) FROM test1;
  66. +----------+
  67. | count(*) |
  68. +----------+
  69. |        0 |
  70. +----------+
  71. 1 row in set (0.00 sec)
  72. -- analyze重新收集统计信息,统计信息才和表数据一致
  73. greatsql> ANALYZE TABLE test1;
  74. +---------------+---------+----------+----------+
  75. | Table         | Op      | Msg_type | Msg_text |
  76. +---------------+---------+----------+----------+
  77. | testdb1.test1 | analyze | status   | OK       |
  78. +---------------+---------+----------+----------+
  79. 1 row in set (0.06 sec)
  80. greatsql> SELECT * FROM mysql.innodb_index_stats WHERE database_name='testdb1' AND table_name='test1';
  81. +---------------+------------+------------+---------------------+--------------+------------+-------------+-----------------------------------+
  82. | database_name | table_name | index_name | last_update         | stat_name    | stat_value | sample_size | stat_description                  |
  83. +---------------+------------+------------+---------------------+--------------+------------+-------------+-----------------------------------+
  84. | testdb1       | test1      | PRIMARY    | 2025-01-07 10:01:58 | n_diff_pfx01 |          0 |           1 | id                                |
  85. | testdb1       | test1      | PRIMARY    | 2025-01-07 10:01:58 | n_leaf_pages |          1 |        NULL | Number of leaf pages in the index |
  86. | testdb1       | test1      | PRIMARY    | 2025-01-07 10:01:58 | size         |          1 |        NULL | Number of pages in the index      |
  87. | testdb1       | test1      | k_1        | 2025-01-07 10:01:58 | n_diff_pfx01 |          0 |           1 | k                                 |
  88. | testdb1       | test1      | k_1        | 2025-01-07 10:01:58 | n_diff_pfx02 |          0 |           1 | k,id                              |
  89. | testdb1       | test1      | k_1        | 2025-01-07 10:01:58 | n_leaf_pages |          1 |        NULL | Number of leaf pages in the index |
  90. | testdb1       | test1      | k_1        | 2025-01-07 10:01:58 | size         |          1 |        NULL | Number of pages in the index      |
  91. +---------------+------------+------------+---------------------+--------------+------------+-------------+-----------------------------------+
  92. 7 rows in set (0.00 sec)
复制代码
2.2 DELETE 操作
  1. greatsql> SELECT COUNT(*) FROM test1;
  2. +----------+
  3. | count(*) |
  4. +----------+
  5. |   100000 |
  6. +----------+
  7. 1 row in set (0.15 sec)
  8. -- 开启事务,执行delete操作
  9. greatsql> BEGIN;
  10. Query OK, 0 rows affected (0.00 sec)
  11. greatsql> SELECT now();DELETE FROM test1;SELECT now();
  12. +---------------------+
  13. | now()               |
  14. +---------------------+
  15. | 2025-01-07 09:41:36 |
  16. +---------------------+
  17. 1 row in set (0.00 sec)
  18. Query OK, 100000 rows affected (1.87 sec)
  19. +---------------------+
  20. | now()               |
  21. +---------------------+
  22. | 2025-01-07 09:41:38 |
  23. +---------------------+
  24. 1 row in set (0.00 sec)
  25. -- 在delete开始时,进行了一次统计信息收集
  26. greatsql> SELECT * FROM mysql.innodb_index_stats WHERE database_name='testdb1' AND table_name='test1';
  27. +---------------+------------+------------+---------------------+--------------+------------+-------------+-----------------------------------+
  28. | database_name | table_name | index_name | last_update         | stat_name    | stat_value | sample_size | stat_description                  |
  29. +---------------+------------+------------+---------------------+--------------+------------+-------------+-----------------------------------+
  30. | testdb1       | test1      | PRIMARY    | 2025-01-07 09:41:36 | n_diff_pfx01 |      98712 |          20 | id                                |
  31. | testdb1       | test1      | PRIMARY    | 2025-01-07 09:41:36 | n_leaf_pages |       1371 |        NULL | Number of leaf pages in the index |
  32. | testdb1       | test1      | PRIMARY    | 2025-01-07 09:41:36 | size         |       1379 |        NULL | Number of pages in the index      |
  33. | testdb1       | test1      | k_1        | 2025-01-07 09:41:36 | n_diff_pfx01 |      32313 |          20 | k                                 |
  34. | testdb1       | test1      | k_1        | 2025-01-07 09:41:36 | n_diff_pfx02 |      99244 |          20 | k,id                              |
  35. | testdb1       | test1      | k_1        | 2025-01-07 09:41:36 | n_leaf_pages |        128 |        NULL | Number of leaf pages in the index |
  36. | testdb1       | test1      | k_1        | 2025-01-07 09:41:36 | size         |        161 |        NULL | Number of pages in the index      |
  37. +---------------+------------+------------+---------------------+--------------+------------+-------------+-----------------------------------+
  38. 7 rows in set (0.00 sec)
  39. -- delete完成一段时间后(约10秒)进行了第二次统计信息收集
  40. greatsql> SELECT * FROM mysql.innodb_index_stats WHERE database_name='testdb1' AND table_name='test1';
  41. +---------------+------------+------------+---------------------+--------------+------------+-------------+-----------------------------------+
  42. | database_name | table_name | index_name | last_update         | stat_name    | stat_value | sample_size | stat_description                  |
  43. +---------------+------------+------------+---------------------+--------------+------------+-------------+-----------------------------------+
  44. | testdb1       | test1      | PRIMARY    | 2025-01-07 09:41:46 | n_diff_pfx01 |          0 |          20 | id                                |
  45. | testdb1       | test1      | PRIMARY    | 2025-01-07 09:41:46 | n_leaf_pages |       1371 |        NULL | Number of leaf pages in the index |
  46. | testdb1       | test1      | PRIMARY    | 2025-01-07 09:41:46 | size         |       1379 |        NULL | Number of pages in the index      |
  47. | testdb1       | test1      | k_1        | 2025-01-07 09:41:46 | n_diff_pfx01 |          0 |          20 | k                                 |
  48. | testdb1       | test1      | k_1        | 2025-01-07 09:41:46 | n_diff_pfx02 |          0 |          20 | k,id                              |
  49. | testdb1       | test1      | k_1        | 2025-01-07 09:41:46 | n_leaf_pages |        128 |        NULL | Number of leaf pages in the index |
  50. | testdb1       | test1      | k_1        | 2025-01-07 09:41:46 | size         |        161 |        NULL | Number of pages in the index      |
  51. +---------------+------------+------------+---------------------+--------------+------------+-------------+-----------------------------------+
  52. 7 rows in set (0.00 sec)
  53. -- 回滚事务
  54. greatsql> ROLLBACK;
  55. Query OK, 0 rows affected (1.95 sec)
  56. -- 事务回滚后,统计信息与表数据不匹配
  57. greatsql> SELECT * FROM mysql.innodb_index_stats WHERE database_name='testdb1' AND table_name='test1';
  58. +---------------+------------+------------+---------------------+--------------+------------+-------------+-----------------------------------+
  59. | database_name | table_name | index_name | last_update         | stat_name    | stat_value | sample_size | stat_description                  |
  60. +---------------+------------+------------+---------------------+--------------+------------+-------------+-----------------------------------+
  61. | testdb1       | test1      | PRIMARY    | 2025-01-07 09:41:46 | n_diff_pfx01 |          0 |          20 | id                                |
  62. | testdb1       | test1      | PRIMARY    | 2025-01-07 09:41:46 | n_leaf_pages |       1371 |        NULL | Number of leaf pages in the index |
  63. | testdb1       | test1      | PRIMARY    | 2025-01-07 09:41:46 | size         |       1379 |        NULL | Number of pages in the index      |
  64. | testdb1       | test1      | k_1        | 2025-01-07 09:41:46 | n_diff_pfx01 |          0 |          20 | k                                 |
  65. | testdb1       | test1      | k_1        | 2025-01-07 09:41:46 | n_diff_pfx02 |          0 |          20 | k,id                              |
  66. | testdb1       | test1      | k_1        | 2025-01-07 09:41:46 | n_leaf_pages |        128 |        NULL | Number of leaf pages in the index |
  67. | testdb1       | test1      | k_1        | 2025-01-07 09:41:46 | size         |        161 |        NULL | Number of pages in the index      |
  68. +---------------+------------+------------+---------------------+--------------+------------+-------------+-----------------------------------+
  69. 7 rows in set (0.00 sec)
  70. greatsql> SELECT COUNT(*) FROM test1;
  71. +----------+
  72. | count(*) |
  73. +----------+
  74. |   100000 |
  75. +----------+
  76. 1 row in set (0.15 sec)
  77. -- analyze重新收集统计信息,统计信息才和表数据一致
  78. greatsql> ANALYZE TABLE test1;
  79. +---------------+---------+----------+----------+
  80. | Table         | Op      | Msg_type | Msg_text |
  81. +---------------+---------+----------+----------+
  82. | testdb1.test1 | analyze | status   | OK       |
  83. +---------------+---------+----------+----------+
  84. 1 row in set (0.08 sec)
  85. greatsql> SELECT * FROM mysql.innodb_index_stats WHERE database_name='testdb1' AND table_name='test1';
  86. +---------------+------------+------------+---------------------+--------------+------------+-------------+-----------------------------------+
  87. | database_name | table_name | index_name | last_update         | stat_name    | stat_value | sample_size | stat_description                  |
  88. +---------------+------------+------------+---------------------+--------------+------------+-------------+-----------------------------------+
  89. | testdb1       | test1      | PRIMARY    | 2025-01-07 09:47:29 | n_diff_pfx01 |      98712 |          20 | id                                |
  90. | testdb1       | test1      | PRIMARY    | 2025-01-07 09:47:29 | n_leaf_pages |       1371 |        NULL | Number of leaf pages in the index |
  91. | testdb1       | test1      | PRIMARY    | 2025-01-07 09:47:29 | size         |       1379 |        NULL | Number of pages in the index      |
  92. | testdb1       | test1      | k_1        | 2025-01-07 09:47:29 | n_diff_pfx01 |      32332 |          20 | k                                 |
  93. | testdb1       | test1      | k_1        | 2025-01-07 09:47:29 | n_diff_pfx02 |     100051 |          20 | k,id                              |
  94. | testdb1       | test1      | k_1        | 2025-01-07 09:47:29 | n_leaf_pages |        128 |        NULL | Number of leaf pages in the index |
  95. | testdb1       | test1      | k_1        | 2025-01-07 09:47:29 | size         |        161 |        NULL | Number of pages in the index      |
  96. +---------------+------------+------------+---------------------+--------------+------------+-------------+-----------------------------------+
  97. 7 rows in set (0.01 sec)
复制代码
3. 总结


  • 数据量变化大(凌驾10%)的DML操作会导致2次统计信息收集,一次是DML开始时,一次是DML完成约10秒后。
  • DML操作是否COMMIT提交,不影响统计信息收集。
  • DML操作的rollback回滚,大概造成统计信息与表数据不一致。当大数据DML操作回滚后,可以执行ANALYZE TABLE重新收集表的统计信息。

Enjoy GreatSQL
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

立聪堂德州十三局店

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表