0

我有一个表定义:

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的 's 而不是主键。

旁注,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真正为我买了什么,可以安全地删除它吗?

4

2 回答 2

1

索引更大,因为当您没有可以视为唯一索引的唯一列时,InnoDB 表将分配一个 6 字节的主键。表中的所有其他索引也包含主键...参见14.2.3.12.2。手册中的聚集索引和二级索引

于 2013-03-06T16:55:18.047 回答
0

首先,是的,这是很正常的行为,正如 innvo 所写。

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

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

于 2013-03-07T13:05:06.907 回答