MySQL减少存储空间

时间:2013-03-06 16:39:35

标签: mysql innodb

我有一个表定义:

CREATE TABLE `k_timestamps` (
  `id` bigint(20) NOT NULL,
  `k_timestamp` datetime NULL DEFAULT NULL,
  `data1` smallint(6) NOT NULL,
  KEY `k_timestamp_key` (`k_timestamp`,`id`) USING BTREE,
  CONSTRAINT `k_time_fk` FOREIGN KEY (`id`) REFERENCES `data` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

基本上,我有很多iddata1个键值对,每隔几个小时我就会添加以前未见过的新键值对,或者值之前的ID已更改。我希望及时跟踪每个id的所有值。因此,id列可以包含重复的id,并且不是主键。

旁注,k_time_fk指向另一个更小的表,该表具有特定id的公共信息,无论当前时间或目前的值是什么。

(id, k_timestamp)应该被认为是表的(复合)主键。

例如,

id          k_timestamp            data1
1597071247  2012-11-15 12:25:47     4
1597355222  2012-11-15 12:25:47     4
1597201376  2012-11-15 12:25:47     4
1597071243  2012-11-15 13:25:47     4
1597071247  2012-11-15 13:25:47     3
1597071249  2012-11-15 13:25:47     3

无论如何,我运行了这个查询:

SELECT concat(table_schema,'.',table_name), 
concat(round(table_rows/1000000,2),'M') rows, 
concat(round(data_length/(1024*1024*1024),2),'G') DATA, 
concat(round(index_length/(1024*1024*1024),2),'G') idx, 
concat(round((data_length+index_length)/(1024*1024*1024),2),'G') total_size, 
round(index_length/data_length,2) idxfrac 
FROM information_schema.TABLES ORDER BY data_length+index_length DESC LIMIT 20; 

要在我的桌子上提取空间信息:

rows      Data     idx       total_size  idxfrac
11.25M    0.50G    0.87G     1.36G       1.76

我不太确定我理解这一点,索引怎么能占用这么多空间?有什么明显我在这里做错了,还是这是正常的?如果可能的话,我希望尽量减少这个表的占地面积。我甚至不确定k_timestamp_key为我真正购买了什么,是否可以安全删除?

2 个答案:

答案 0 :(得分:1)

索引更大,因为当没有唯一列可以将其视为唯一索引时,InnoDB表将分配一个6字节的主键。表中的所有其他索引也包含主键...请参阅手册中的14.2.3.12.2. Clustered and Secondary Indexes

答案 1 :(得分:0)

首先,是的,这是非常正常的行为,因为innvo写道。

其次,您可以使用OPTIMIZE TABLE优化表及其索引。由于您的主键很可能是“碎片化” - 即假设插入的行在物理上靠近前一行是不安全的 - 那里可能会有一些收益。

最后,您可能不会需要表上的主键,但如果您要查询数百万行,则几乎肯定需要索引...