我有一个表定义:
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;
基本上,我有很多id
和data1
个键值对,每隔几个小时我就会添加以前未见过的新键值对,或者值之前的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
为我真正购买了什么,是否可以安全删除?
答案 0 :(得分:1)
索引更大,因为当没有唯一列可以将其视为唯一索引时,InnoDB表将分配一个6字节的主键。表中的所有其他索引也包含主键...请参阅手册中的14.2.3.12.2. Clustered and Secondary Indexes
答案 1 :(得分:0)
首先,是的,这是非常正常的行为,因为innvo写道。
其次,您可以使用OPTIMIZE TABLE优化表及其索引。由于您的主键很可能是“碎片化” - 即假设插入的行在物理上靠近前一行是不安全的 - 那里可能会有一些收益。
最后,您可能不会需要表上的主键,但如果您要查询数百万行,则几乎肯定需要索引...