简体   繁体   中英

how are uuids which are used as index in mysql sorted by in b-tree?

I know the index itself is sorted when it stored in B-tree.

When I select uuids which are used as primary key of a table, the results are different by when it has 'order by' clause or not. I assumed the result without 'order by' should be same with 'order by asc' but it's not. Because they will get selected from index tree.

Can anyone explain why this happens to me please?

The results are below.

  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 uuid_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 uuid_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

If you do not specify an order by , MySQL is free to chose any order it likes. If you do this in combination with limit , it will make your resultset nondeterministic. So always specify the order.

Now the longer answer:

Technically, for InnoDB, MySQL will use the order of the index it uses, which might give you the impression that it will always give you a specific order. While you should not rely on that, in your case, the "problem" is that MySQL chose a different index than you expected.

With uuid being the primary key, for select uuid from uuid_table limit 500000, 10 , using the primary key seems like a logical choice. But it isn't. It actually is the worst possible choice.

Technically, for InnoDB, the primary key contains all columns. This makes the primary key the largest index in your table. Also technically, for InnoDB, every secondary index includes the primary key columns (to be able to find the row data, which is stored using the primary key). So if you have eg an index on a column a , this index will contain a and uuid . This is actually everything your query needs (it "covers" your query). So MySQL can read that index, skip 500.000 rows, and get the next 10 uuids from that index.

This index is smaller than the primary key. And reading a smaller index means reading less bytes, which (disregarding cache) means getting your result faster. That is why MySQL will choose not to use the primary key. You can confirm that with explain select uuid from uuid_table limit 500000, 10 , which will reveal the index MySQL used.

And just do stress it again: your query should work properly, independently from the details of how InnoDB (or MySQL) is implemented internally, so always add the ordering. Even if MySQL, for InnoDB, for technical reasons shows this specific behaviour, you should not rely on it. Although I doubt it will happen, MySQL may eg add an optimization where the offset in select uuid from uuid_table limit 500000, 10 would get optimized away (and just returns the first 10 rows), as it would still be a completely valid, but faster, execution of your query.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM