如何在mysql中作为索引在b-tree排序的uid ?

  • 本文关键字:排序 b-tree uid 索引 mysql mysql
  • 更新时间 :
  • 英文 :


我知道索引本身在B-tree中存储时是排序的。

当我选择uid作为表的主键时,结果是不同的,当它有'order by'子句或没有。我假设没有'order by'的结果应该与'order by asc'相同,但事实并非如此。因为它们会从索引树中被选中

谁能解释一下为什么这种事发生在我身上?结果如下:

  1. select uuid from uuid_table limit 500000,10
617cf27d-1928-4d79-8eee-65635aee99c7
006e97ac-d539-40a3-93c2-d01048b785be
c76c69eb-911b-4ed5-a131-47fd2175102c
1006e6c6-9fa0-414a-8d12-9964de430f25
74520150-bbe4-4d46-9717-92e2d11c09ba
b7e073b3-2701-469c-bfe0-84c256647d94
80041ad8-de9a-4688-af2b-d964d4a717e9
3b3427c2-4b32-4aee-afe1-be5a37d61e36
0b349f44-cd58-4938-b244-37220f88d1cd
cd590cd4-c3ba-4fd5-ae86-8059cd9c49ae
6275ce2f-4271-403b-b1fc-0dd012d0016b
  1. select uuid from uid_table order by uuid asc limit 500000, 10
1d72b5f4-d58c-495d-8903-a64f995b845d
1d72c19f-2cfd-49ad-865d-c9ee12c413be
1d72dd3e-e378-4c84-8712-9e3e2ad19ef4
1d72e43a-3a30-4090-ab24-6ce3020c449e
1d72e967-f498-43a5-bb75-941c255d2548
1d72ec5d-3a7a-44e2-ba7f-324e91de99ce
1d72f470-6b0f-481f-a999-623fa90c27ef
1d72fd32-f342-4a21-83fa-b05c577bb8d0
1d730a35-0a53-4536-9b38-5cb2c7286666
1d732415-b2ff-4d4f-a57c-e787fb040f0c
1d7331e1-0bca-4395-8e49-83ee95395f7c
  1. select uuid from uid_table order by uuid desc limit 500000,10
e287e4a0-ab5a-428c-8a9c-c042398d440f
e2879bec-e0b4-41a4-b692-50af6edc4e0f
e28791d4-1ba2-4b9f-b27b-b3066a1d99b4
e28773a9-3747-4d6b-9014-3823d35e7d03
e28770f7-aa12-469a-bff5-030115dee05b
e2876c20-679b-488d-ad45-15d34721e406
e28749a8-777d-45ec-88b7-e64a3ec0b759
e2873c05-e6f7-43d6-97de-0b3a73c5d98e
e2873984-8175-4e55-aa2f-43fe8114c634
e2871ea7-ce92-40be-bdab-3b9a44644a49
e2871655-4b9f-4fe2-b31c-a638d53a9e18

如果您不指定order by, MySQL可以自由选择它喜欢的任何顺序。如果您将此与limit结合使用,它将使您的结果集不确定。所以一定要指定顺序。

现在是更长的答案:

从技术上讲,对于InnoDB, MySQL将使用索引的顺序,这可能会给你一个印象,它总是给你一个特定的顺序。虽然你不应该依赖于这一点,但在你的情况下,"问题"是;是MySQL选择了一个不同于你预期的索引

如果uuid是主键,那么对于select uuid from uuid_table limit 500000, 10,使用主键似乎是一个合乎逻辑的选择。但事实并非如此。这实际上是最糟糕的选择。

从技术上讲,对于InnoDB,主键包含所有列。这使得主键成为表中最大的索引。此外,从技术上讲,对于InnoDB,每个二级索引都包含主键列(以便能够找到使用主键存储的行数据)。因此,如果你有一个列a的索引,这个索引将包含auuid。这实际上是你的查询所需要的一切(它"涵盖"了)。您的查询)。因此,MySQL可以读取该索引,跳过500.000行,并从该索引中获得下一个10个uid。

该索引小于主键。读取更小的索引意味着读取更少的字节,这(忽略缓存)意味着更快地获得结果。这就是MySQL选择不使用主键的原因。你可以用explain select uuid from uuid_table limit 500000, 10来确认,这将显示MySQL使用的索引。

再次强调:你的查询应该正常工作,独立于InnoDB(或MySQL)内部实现的细节,所以总是添加排序。即使MySQL,对于InnoDB,由于技术原因显示了这种特定的行为,你也不应该依赖它。虽然我怀疑它是否会发生,MySQL可能会添加一个优化,其中select uuid from uuid_table limit 500000, 10中的偏移量将被优化掉(并且只返回前10行),因为它仍然是一个完全有效的,但更快的查询执行。

最新更新