据我所知,InnoDB主键索引在记录顺序时比在随机时更高效。
但是,我对几乎顺序的值的InnoDB主索引的性能感到好奇。假设我没有使用auto_increment
,而是使用存储为BINARY(16)的一些应用程序端顺序UUID方案,如this excellent article中所述。
如果记录差不多顺序,这对存储和查询性能意味着什么?
答案 0 :(得分:0)
您可以在Jeremy Cole这篇有趣的文章中找到关于InnoDB索引的详细而有用的信息
http://blog.jcole.us/2013/01/10/the-physical-structure-of-records-in-innodb/
Anyawy做的事实是索引基于B + Tree索引结构你所确认的
记录差不多 - 但不是很顺序
不要改变性能,因为顺序方面不是根据字段的含义(1,2,3而不是1,5,7)而是根据值的“分布”。在这种情况下,您显示的两个方案在值的分配方面是相同的。
答案 1 :(得分:0)
"计算磁盘命中数"。
案例1:所有数据和索引都适合innodb_buffer_pool_size
行和/或索引的排序并不重要。 (除非最终将所有内容保存到磁盘,否则没有磁盘命中。)
案例2:数据和/或索引太大,无法容纳在buffer_pool中。
案例2a:数据/索引是连续的,或几乎是连续的,或者具有有限数量的热点"。
将有一个或有限数量的'获得所有活动的块。这些(可能)很容易适合buffer_pool。所以,没有性能问题。
案例2b:数据/索引是随机的(例如,UUID或MD5) 现在,由于数据/索引太大而不适合,并且插入物随机跳转,因此将有大量I / O来完成工作。 I / O是性能杀手。 (由于包含' next' UUID的块不太可能缓存在buffer_pool中,因此需要将其读取,修改并最终写回磁盘。)
数据(在InnoDB中)按一个BTree中的PRIMARY KEY
排序。每个 ' index是自己的BTree。
现在让我们以不同的方式解决问题......
案例1.您只有PK,没有辅助钥匙 如果在加载之前通过PK对数据进行排序很容易,这会使加载运行得很快。 (填写一个块,写入磁盘;重复。不能减少磁盘命中。)
案例2.你有一个AUTO_INCREMENT
PK,还有一个二级密钥
在这种情况下,如果您使用辅助密钥进行预排序并让AUTO_INCREMENT
执行其操作,则会快速运行。
案例3:如果您有两个具有不同特征的密钥(PK和/或辅助密钥),例如时间戳和UUID,则 你被卡住了您可以尝试按一个预先排序来优化它,但是,另一个将是随机且缓慢的。 (在一个指数上效率低,另一个指数效率低。)
回到你的问题。 "差不多顺序"可能意味着你没有击中许多不同的块。例如,如果您有一年的数据,并且PK是时间戳,但每天的数据是混乱的,那么几乎排序"。在任何时候,你只需要一天的价值,而不是全年。