群集与非群集主键

时间:2010-01-26 09:35:28

标签: performance sqlite clustered-index

begin transaction;
create table person_id(person_id integer primary key);
insert into person_id values(1);
... snip ...
insert into person_id values(50000);
commit;

此代码在我的计算机上大约需要0.9秒,并创建一个占用392K的db文件。如果我将第二行更改为

,这些数字将变为1.4秒和864K
create table person_id(person_id integer nonclustered primary key);

为什么会这样?

4 个答案:

答案 0 :(得分:4)

在DBA StackExchange上可以找到这个问题的一个很好的答案:https://dba.stackexchange.com/questions/7741/when-should-a-primary-key-be-declared-non-clustered/7744#7744

答案 1 :(得分:2)

对主键进行聚类将其与行存储在一起;这意味着它占用更少的空间(因为没有单独的索引块)。但是,它的主要优点通常是范围扫描通常可以访问位于同一块中的行,从而减少IO操作,当您拥有大量数据集(不是50k整数)时,这将变得非常重要。

我认为50k整数是一个相当人为的基准,而不是你在现实世界中关心的。

答案 2 :(得分:0)

[仅作为一个想法]

也许当您明确指定将整数列作为聚簇键时,它就是这样做的。但是当你告诉它不要使用你的整数列时,它仍会在幕后创建一个索引,但是选择一个不同的数据类型来做这个,假设是两倍大。然后,每个条目都必须引用表格中的记录,在这里,大小正在爆炸。

答案 3 :(得分:0)

我随机化了insert语句,并使用一到五十万的值重新执行查询。有趣的是,聚簇和非聚簇数据库文件现在占用了确切的空间量(直到字节)。但是,群集数据库上的插入仍然更快。

对我来说,这是违反直觉的。当我告诉数据库集群这些值时 - 我告诉数据库......当我回来获取它们时,这些值最好按此顺序排列。当我没有规范时,我实际上是在对数据库说 - 看看这些值并按照你喜欢的方式安排它们 - 无论什么让你的生活更轻松。

理论上,这种额外的自由永远不会减慢查询速度。也许不会一直加速它们,但永远不要放慢速度。想法?