默认情况下,我的InnoDB存储引擎的主键是自动递增整数。为了隐藏数据库中的行数,应用程序代码为主键实现了一些随机生成器。
这是典型方案的示例:
CREATE TABLE `MUSIC_LINK` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`project_id` int(11) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=latin1;
我正在读一本书,才发现InnoDB使用按主键排序的聚簇索引。本质上,这意味着数据库文件中的记录由主键值索引和排序。只要下一条记录的主键始终大于插入的最后一条记录(这是默认情况下,由于自动增量约束),就很好。
当主键不再自动递增时会发生什么?为了使文件按主键排序,每次插入小于最大主键的主键时,都必须进行大量重写。
我是否误解了聚集索引如何在InnoDB中工作?因为这听起来像一个巨大的性能问题。
答案 0 :(得分:2)
InnoDB:
使用AUTO_INCREMENT
PRIMARY KEY
,“下一个”行将放置在保存表数据的BTree的“末尾”。这是有效的,并且“最后一个”块将被大量更新。
注意:块保留在buffer_pool中,最终要 写入磁盘。
对于具有“随机” PK(例如GUID,UUID,MD5,SHA1等)的情况,要插入的“下一个”行需要进入保存数据的BTree中的某个“随机”位置。如果buffer_pool足够大,则必要的块仍将位于其中。因此,效率与AI并没有太大差异。
另一方面,如果数据太大而无法容纳到buffer_pool中(或者其他活动不断使这些块溢出),那么插入将需要先获取该块,然后再对其进行修改。
例如,如果表的大小是buffer_pool中可以容纳的大小的20倍,则下一次随机写入将有20的缓存块中有1的机会。也就是说,INSERT
有95%的时间必须等待磁盘读取。
但是...您促成对INSERTs
的讨论。 SELECTs
呢?选择有什么模式(如果有)?如果仍然是“随机”,则PK的类型无关紧要。另一方面,如果选择倾向于到达“最近”项(例如新闻),则AI会赢得大型表,这是因为缓存了所需块的可能性增加了。
集群
评论表示对“集群/ ed / ing”有些困惑。一些定义(在MySQL / MariaDB上下文中):
所以,回到评论:
PRIMARY KEY
中跳来跳去(由于使用了我所谓的随机PK,或者只是由于未按某些相关顺序获取行)而在表中跳来跳去。