问题描述
我正在测试一个专有工具,该工具将 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 的变化。