为什么恢复表中索引的基数与原始表中的基数不同?

问题描述

我正在测试一个专有工具,该工具将 MysqL RDS 中的表转储为 parquet 格式,然后将其恢复到另一个 MysqL RDS。

两个表的行数相同:

MysqL> SELECT COUNT(*) FROM fox_owners;
+----------+
| COUNT(*) |
+----------+
|   118950 |
+----------+

表格本身在两种情况下的配置方式相同:

MysqL> SHOW CREATE TABLE fox_owners;
+------------+-------------------------------------------------------+
| Table      | Create Table                                          |
+------------+-------------------------------------------------------+
| fox_owners | CREATE TABLE `fox_owners` (
  `name` mediumtext,`owner_id` bigint NOT NULL,PRIMARY KEY (`owner_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
+------------+-------------------------------------------------------+

到目前为止一切顺利,对吧?

但是,桌子大小不同。 原文:

+----------+----------------------+------------+
| Database | Table                | Size in MB |
+----------+----------------------+------------+
| stam_db  | fox_owners           |    5582.52 |

恢复的那个:

+----------+----------------------+------------+
| Database | Table                | Size in MB |
+----------+----------------------+------------+
| stam_db  | fox_owners           |    5584.52 |

恢复后的大了 2MB! 然而,真正困扰我的是 2 个表之间索引基数的变化。 原文:

MysqL> SHOW INDEX FROM fox_owners;
+------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table      | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| fox_owners |          0 | PRIMARY  |            1 | owner_id    | A         |      118728 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
+------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+

恢复:

MysqL> SHOW INDEX FROM fox_owners;
+------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table      | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| fox_owners |          0 | PRIMARY  |            1 | owner_id    | A         |      117518 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
+------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+

为什么基数会从 118728 下降到 117518? 如果恢复后的表不如原始表唯一 - 这难道不是该表不同的明显标志吗?如何验证不同 RDS 数据库中的这 2 个表具有相同的内容

无论如何,基数不应该是 118950,因为对于具有单个主键列的表,基数必须等于表中的行数?

我在两个表上都运行了 ANALYZE TABLE,值没有改变。

解决方法

没问题。

“基数”是通过在表中进行少量“随机”探测来确定的。这导致估计。有时估计值相差两倍甚至更多。 118728 和 117518 异常接近。

加载/复制/更改表时,会重建 BTree。这导致 BTree 的块布局方式可能会发生变化。因此,看到表的大小(在磁盘上)发生变化是正常的。为此,很少有因子 2 的变化。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...