Skip to content

Commit b9f19f7

Browse files
abarkovvuvova
authored andcommitted
MDEV-26664 Store UUIDs in a more efficient manner
UUID values llllllll-mmmm-Vhhh-vsss-nnnnnnnnnnnn are now stored as nnnnnnnnnnnn-vsss-Vhhh-mmmm-llllllll inside the record: - the groups (segments separated by dash) are reordered right-to-left. - the bytes inside the groups are not reordered (stored as before, in big-endian format). This provides a better sorting order: the earlier UUID was generated, the higher it appears in the ORDER BY output. Also, this change enables a good key prefix compression, because the constant part is now in the beginning, while the non-constant part (the timestamp) is in the end.
1 parent 50bcda0 commit b9f19f7

15 files changed

+3601
-36
lines changed
Binary file not shown.
Binary file not shown.

plugin/type_uuid/mysql-test/type_uuid/type_uuid.result

Lines changed: 1065 additions & 2 deletions
Large diffs are not rendered by default.

plugin/type_uuid/mysql-test/type_uuid/type_uuid.test

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,50 @@ SELECT * FROM t1 WHERE a IN ('::', 10);
138138

139139
DROP TABLE t1;
140140

141+
--echo #
142+
--echo # ORDER BY
143+
--echo #
144+
145+
CREATE TABLE t1 (a UUID);
146+
DELIMITER $$;
147+
FOR i IN 0..15
148+
DO
149+
INSERT INTO t1 VALUES (REPLACE('XX000000-0000-0000-0000-000000000000','XX',LPAD(HEX(i),2,'0')));
150+
INSERT INTO t1 VALUES (REPLACE('00XX0000-0000-0000-0000-000000000000','XX',LPAD(HEX(i),2,'0')));
151+
INSERT INTO t1 VALUES (REPLACE('0000XX00-0000-0000-0000-000000000000','XX',LPAD(HEX(i),2,'0')));
152+
INSERT INTO t1 VALUES (REPLACE('000000XX-0000-0000-0000-000000000000','XX',LPAD(HEX(i),2,'0')));
153+
INSERT INTO t1 VALUES (REPLACE('00000000-XX00-0000-0000-000000000000','XX',LPAD(HEX(i),2,'0')));
154+
INSERT INTO t1 VALUES (REPLACE('00000000-00XX-0000-0000-000000000000','XX',LPAD(HEX(i),2,'0')));
155+
INSERT INTO t1 VALUES (REPLACE('00000000-0000-XX00-0000-000000000000','XX',LPAD(HEX(i),2,'0')));
156+
INSERT INTO t1 VALUES (REPLACE('00000000-0000-00XX-0000-000000000000','XX',LPAD(HEX(i),2,'0')));
157+
INSERT INTO t1 VALUES (REPLACE('00000000-0000-0000-XX00-000000000000','XX',LPAD(HEX(i),2,'0')));
158+
INSERT INTO t1 VALUES (REPLACE('00000000-0000-0000-00XX-000000000000','XX',LPAD(HEX(i),2,'0')));
159+
INSERT INTO t1 VALUES (REPLACE('00000000-0000-0000-0000-XX0000000000','XX',LPAD(HEX(i),2,'0')));
160+
INSERT INTO t1 VALUES (REPLACE('00000000-0000-0000-0000-00XX00000000','XX',LPAD(HEX(i),2,'0')));
161+
INSERT INTO t1 VALUES (REPLACE('00000000-0000-0000-0000-0000XX000000','XX',LPAD(HEX(i),2,'0')));
162+
INSERT INTO t1 VALUES (REPLACE('00000000-0000-0000-0000-000000XX0000','XX',LPAD(HEX(i),2,'0')));
163+
INSERT INTO t1 VALUES (REPLACE('00000000-0000-0000-0000-00000000XX00','XX',LPAD(HEX(i),2,'0')));
164+
INSERT INTO t1 VALUES (REPLACE('00000000-0000-0000-0000-0000000000XX','XX',LPAD(HEX(i),2,'0')));
165+
END FOR;
166+
$$
167+
DELIMITER ;$$
168+
169+
--echo #
170+
--echo # Logical ORDER BY
171+
--echo #
172+
SELECT * FROM t1 ORDER BY a;
173+
SELECT COALESCE(NULL, a) FROM t1 ORDER BY a;
174+
175+
--echo #
176+
--echo # Lexicographical ORDER BY
177+
--echo #
178+
179+
SELECT * FROM t1 ORDER BY CAST(a AS BINARY(16));
180+
SELECT * FROM t1 ORDER BY CAST(COALESCE(NULL,a) AS BINARY(16));
181+
182+
DROP TABLE t1;
183+
184+
141185
--echo #
142186
--echo # cmp_item_uuid: IN for non-constants
143187
--echo #

plugin/type_uuid/mysql-test/type_uuid/type_uuid_engines.inc

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,43 @@ SELECT * FROM t1 WHERE a=CAST('00000000-0000-0000-0000-0000000000ff' AS UUID);
6666
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=CAST('00000000-0000-0000-0000-0000000000ff' AS UUID);
6767

6868
DROP TABLE t1;
69+
70+
71+
CREATE OR REPLACE TABLE t1 (a UUID,KEY(a));
72+
SHOW CREATE TABLE t1;
73+
BEGIN;
74+
DELIMITER $$;
75+
FOR i IN 0..255
76+
DO
77+
INSERT INTO t1 VALUES (REPLACE('XX000000-0000-0000-0000-000000000000','XX',LPAD(HEX(i),2,'0')));
78+
INSERT INTO t1 VALUES (REPLACE('00XX0000-0000-0000-0000-000000000000','XX',LPAD(HEX(i),2,'0')));
79+
INSERT INTO t1 VALUES (REPLACE('0000XX00-0000-0000-0000-000000000000','XX',LPAD(HEX(i),2,'0')));
80+
INSERT INTO t1 VALUES (REPLACE('000000XX-0000-0000-0000-000000000000','XX',LPAD(HEX(i),2,'0')));
81+
INSERT INTO t1 VALUES (REPLACE('00000000-XX00-0000-0000-000000000000','XX',LPAD(HEX(i),2,'0')));
82+
INSERT INTO t1 VALUES (REPLACE('00000000-00XX-0000-0000-000000000000','XX',LPAD(HEX(i),2,'0')));
83+
INSERT INTO t1 VALUES (REPLACE('00000000-0000-XX00-0000-000000000000','XX',LPAD(HEX(i),2,'0')));
84+
INSERT INTO t1 VALUES (REPLACE('00000000-0000-00XX-0000-000000000000','XX',LPAD(HEX(i),2,'0')));
85+
INSERT INTO t1 VALUES (REPLACE('00000000-0000-0000-XX00-000000000000','XX',LPAD(HEX(i),2,'0')));
86+
INSERT INTO t1 VALUES (REPLACE('00000000-0000-0000-00XX-000000000000','XX',LPAD(HEX(i),2,'0')));
87+
INSERT INTO t1 VALUES (REPLACE('00000000-0000-0000-0000-XX0000000000','XX',LPAD(HEX(i),2,'0')));
88+
INSERT INTO t1 VALUES (REPLACE('00000000-0000-0000-0000-00XX00000000','XX',LPAD(HEX(i),2,'0')));
89+
INSERT INTO t1 VALUES (REPLACE('00000000-0000-0000-0000-0000XX000000','XX',LPAD(HEX(i),2,'0')));
90+
INSERT INTO t1 VALUES (REPLACE('00000000-0000-0000-0000-000000XX0000','XX',LPAD(HEX(i),2,'0')));
91+
INSERT INTO t1 VALUES (REPLACE('00000000-0000-0000-0000-00000000XX00','XX',LPAD(HEX(i),2,'0')));
92+
INSERT INTO t1 VALUES (REPLACE('00000000-0000-0000-0000-0000000000XX','XX',LPAD(HEX(i),2,'0')));
93+
END FOR;
94+
$$
95+
DELIMITER ;$$
96+
COMMIT;
97+
EXPLAIN SELECT * FROM t1 WHERE a='ff000000-0000-0000-0000-000000000000';
98+
EXPLAIN SELECT * FROM t1 WHERE a='00ff0000-0000-0000-0000-000000000000';
99+
EXPLAIN SELECT * FROM t1 WHERE a='0000ff00-0000-0000-0000-000000000000';
100+
EXPLAIN SELECT * FROM t1 WHERE a='000000ff-0000-0000-0000-000000000000';
101+
EXPLAIN SELECT * FROM t1 WHERE a='00000000-ff00-0000-0000-000000000000';
102+
EXPLAIN SELECT * FROM t1 WHERE a='00000000-00ff-0000-0000-000000000000';
103+
EXPLAIN SELECT * FROM t1 WHERE a='00000000-0000-ff00-0000-000000000000';
104+
EXPLAIN SELECT * FROM t1 WHERE a='00000000-0000-00ff-0000-000000000000';
105+
EXPLAIN SELECT * FROM t1 WHERE a='00000000-0000-0000-ff00-000000000000';
106+
EXPLAIN SELECT * FROM t1 WHERE a='00000000-0000-0000-00ff-000000000000';
107+
EXPLAIN SELECT * FROM t1 WHERE a='00000000-0000-0000-0000-ff0000000000';
108+
DROP TABLE t1;

plugin/type_uuid/mysql-test/type_uuid/type_uuid_innodb.result

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,69 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
115115
Warnings:
116116
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = UUID'00000000-0000-0000-0000-0000000000ff'
117117
DROP TABLE t1;
118+
CREATE OR REPLACE TABLE t1 (a UUID,KEY(a));
119+
SHOW CREATE TABLE t1;
120+
Table Create Table
121+
t1 CREATE TABLE `t1` (
122+
`a` uuid DEFAULT NULL,
123+
KEY `a` (`a`)
124+
) ENGINE=InnoDB DEFAULT CHARSET=latin1
125+
BEGIN;
126+
FOR i IN 0..255
127+
DO
128+
INSERT INTO t1 VALUES (REPLACE('XX000000-0000-0000-0000-000000000000','XX',LPAD(HEX(i),2,'0')));
129+
INSERT INTO t1 VALUES (REPLACE('00XX0000-0000-0000-0000-000000000000','XX',LPAD(HEX(i),2,'0')));
130+
INSERT INTO t1 VALUES (REPLACE('0000XX00-0000-0000-0000-000000000000','XX',LPAD(HEX(i),2,'0')));
131+
INSERT INTO t1 VALUES (REPLACE('000000XX-0000-0000-0000-000000000000','XX',LPAD(HEX(i),2,'0')));
132+
INSERT INTO t1 VALUES (REPLACE('00000000-XX00-0000-0000-000000000000','XX',LPAD(HEX(i),2,'0')));
133+
INSERT INTO t1 VALUES (REPLACE('00000000-00XX-0000-0000-000000000000','XX',LPAD(HEX(i),2,'0')));
134+
INSERT INTO t1 VALUES (REPLACE('00000000-0000-XX00-0000-000000000000','XX',LPAD(HEX(i),2,'0')));
135+
INSERT INTO t1 VALUES (REPLACE('00000000-0000-00XX-0000-000000000000','XX',LPAD(HEX(i),2,'0')));
136+
INSERT INTO t1 VALUES (REPLACE('00000000-0000-0000-XX00-000000000000','XX',LPAD(HEX(i),2,'0')));
137+
INSERT INTO t1 VALUES (REPLACE('00000000-0000-0000-00XX-000000000000','XX',LPAD(HEX(i),2,'0')));
138+
INSERT INTO t1 VALUES (REPLACE('00000000-0000-0000-0000-XX0000000000','XX',LPAD(HEX(i),2,'0')));
139+
INSERT INTO t1 VALUES (REPLACE('00000000-0000-0000-0000-00XX00000000','XX',LPAD(HEX(i),2,'0')));
140+
INSERT INTO t1 VALUES (REPLACE('00000000-0000-0000-0000-0000XX000000','XX',LPAD(HEX(i),2,'0')));
141+
INSERT INTO t1 VALUES (REPLACE('00000000-0000-0000-0000-000000XX0000','XX',LPAD(HEX(i),2,'0')));
142+
INSERT INTO t1 VALUES (REPLACE('00000000-0000-0000-0000-00000000XX00','XX',LPAD(HEX(i),2,'0')));
143+
INSERT INTO t1 VALUES (REPLACE('00000000-0000-0000-0000-0000000000XX','XX',LPAD(HEX(i),2,'0')));
144+
END FOR;
145+
$$
146+
COMMIT;
147+
EXPLAIN SELECT * FROM t1 WHERE a='ff000000-0000-0000-0000-000000000000';
148+
id select_type table type possible_keys key key_len ref rows Extra
149+
1 SIMPLE t1 ref a a 17 const 1 Using where; Using index
150+
EXPLAIN SELECT * FROM t1 WHERE a='00ff0000-0000-0000-0000-000000000000';
151+
id select_type table type possible_keys key key_len ref rows Extra
152+
1 SIMPLE t1 ref a a 17 const 1 Using where; Using index
153+
EXPLAIN SELECT * FROM t1 WHERE a='0000ff00-0000-0000-0000-000000000000';
154+
id select_type table type possible_keys key key_len ref rows Extra
155+
1 SIMPLE t1 ref a a 17 const 1 Using where; Using index
156+
EXPLAIN SELECT * FROM t1 WHERE a='000000ff-0000-0000-0000-000000000000';
157+
id select_type table type possible_keys key key_len ref rows Extra
158+
1 SIMPLE t1 ref a a 17 const 1 Using where; Using index
159+
EXPLAIN SELECT * FROM t1 WHERE a='00000000-ff00-0000-0000-000000000000';
160+
id select_type table type possible_keys key key_len ref rows Extra
161+
1 SIMPLE t1 ref a a 17 const 1 Using where; Using index
162+
EXPLAIN SELECT * FROM t1 WHERE a='00000000-00ff-0000-0000-000000000000';
163+
id select_type table type possible_keys key key_len ref rows Extra
164+
1 SIMPLE t1 ref a a 17 const 1 Using where; Using index
165+
EXPLAIN SELECT * FROM t1 WHERE a='00000000-0000-ff00-0000-000000000000';
166+
id select_type table type possible_keys key key_len ref rows Extra
167+
1 SIMPLE t1 ref a a 17 const 1 Using where; Using index
168+
EXPLAIN SELECT * FROM t1 WHERE a='00000000-0000-00ff-0000-000000000000';
169+
id select_type table type possible_keys key key_len ref rows Extra
170+
1 SIMPLE t1 ref a a 17 const 1 Using where; Using index
171+
EXPLAIN SELECT * FROM t1 WHERE a='00000000-0000-0000-ff00-000000000000';
172+
id select_type table type possible_keys key key_len ref rows Extra
173+
1 SIMPLE t1 ref a a 17 const 1 Using where; Using index
174+
EXPLAIN SELECT * FROM t1 WHERE a='00000000-0000-0000-00ff-000000000000';
175+
id select_type table type possible_keys key key_len ref rows Extra
176+
1 SIMPLE t1 ref a a 17 const 1 Using where; Using index
177+
EXPLAIN SELECT * FROM t1 WHERE a='00000000-0000-0000-0000-ff0000000000';
178+
id select_type table type possible_keys key key_len ref rows Extra
179+
1 SIMPLE t1 ref a a 17 const 1 Using where; Using index
180+
DROP TABLE t1;
118181
#
119182
# End of 10.5 tests
120183
#

plugin/type_uuid/mysql-test/type_uuid/type_uuid_memory.result

Lines changed: 67 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ a
2525
00000000-0000-0000-0000-0000000000ff
2626
EXPLAIN SELECT * FROM t1 WHERE a='00000000-0000-0000-0000-0000000000ff';
2727
id select_type table type possible_keys key key_len ref rows Extra
28-
1 SIMPLE t1 ref a a 17 const 2 Using where
28+
1 SIMPLE t1 ref a a 17 const 4 Using where
2929
SELECT * FROM t1 WHERE a='garbage';
3030
a
3131
Warnings:
@@ -66,7 +66,7 @@ EXPLAIN SELECT * FROM t1 WHERE a IN
6666
'00000000-0000-0000-0000-0000000000f0'
6767
);
6868
id select_type table type possible_keys key key_len ref rows Extra
69-
1 SIMPLE t1 range a a 17 NULL 6 Using where
69+
1 SIMPLE t1 range a a 17 NULL 12 Using where
7070
SELECT * FROM t1 WHERE a IN
7171
(
7272
'00000000-0000-0000-0000-000000000080',
@@ -85,7 +85,7 @@ EXPLAIN SELECT * FROM t1 WHERE a IN
8585
'garbage'
8686
);
8787
id select_type table type possible_keys key key_len ref rows Extra
88-
1 SIMPLE t1 range a a 17 NULL 4 Using where
88+
1 SIMPLE t1 range a a 17 NULL 8 Using where
8989
Warnings:
9090
Warning 1292 Incorrect uuid value: 'garbage'
9191
SELECT * FROM t1 WHERE a BETWEEN
@@ -178,10 +178,73 @@ a
178178
00000000-0000-0000-0000-0000000000ff
179179
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=CAST('00000000-0000-0000-0000-0000000000ff' AS UUID);
180180
id select_type table type possible_keys key key_len ref rows filtered Extra
181-
1 SIMPLE t1 ref a a 17 const 2 100.00 Using where
181+
1 SIMPLE t1 ref a a 17 const 4 100.00 Using where
182182
Warnings:
183183
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = UUID'00000000-0000-0000-0000-0000000000ff'
184184
DROP TABLE t1;
185+
CREATE OR REPLACE TABLE t1 (a UUID,KEY(a));
186+
SHOW CREATE TABLE t1;
187+
Table Create Table
188+
t1 CREATE TABLE `t1` (
189+
`a` uuid DEFAULT NULL,
190+
KEY `a` (`a`)
191+
) ENGINE=MEMORY DEFAULT CHARSET=latin1
192+
BEGIN;
193+
FOR i IN 0..255
194+
DO
195+
INSERT INTO t1 VALUES (REPLACE('XX000000-0000-0000-0000-000000000000','XX',LPAD(HEX(i),2,'0')));
196+
INSERT INTO t1 VALUES (REPLACE('00XX0000-0000-0000-0000-000000000000','XX',LPAD(HEX(i),2,'0')));
197+
INSERT INTO t1 VALUES (REPLACE('0000XX00-0000-0000-0000-000000000000','XX',LPAD(HEX(i),2,'0')));
198+
INSERT INTO t1 VALUES (REPLACE('000000XX-0000-0000-0000-000000000000','XX',LPAD(HEX(i),2,'0')));
199+
INSERT INTO t1 VALUES (REPLACE('00000000-XX00-0000-0000-000000000000','XX',LPAD(HEX(i),2,'0')));
200+
INSERT INTO t1 VALUES (REPLACE('00000000-00XX-0000-0000-000000000000','XX',LPAD(HEX(i),2,'0')));
201+
INSERT INTO t1 VALUES (REPLACE('00000000-0000-XX00-0000-000000000000','XX',LPAD(HEX(i),2,'0')));
202+
INSERT INTO t1 VALUES (REPLACE('00000000-0000-00XX-0000-000000000000','XX',LPAD(HEX(i),2,'0')));
203+
INSERT INTO t1 VALUES (REPLACE('00000000-0000-0000-XX00-000000000000','XX',LPAD(HEX(i),2,'0')));
204+
INSERT INTO t1 VALUES (REPLACE('00000000-0000-0000-00XX-000000000000','XX',LPAD(HEX(i),2,'0')));
205+
INSERT INTO t1 VALUES (REPLACE('00000000-0000-0000-0000-XX0000000000','XX',LPAD(HEX(i),2,'0')));
206+
INSERT INTO t1 VALUES (REPLACE('00000000-0000-0000-0000-00XX00000000','XX',LPAD(HEX(i),2,'0')));
207+
INSERT INTO t1 VALUES (REPLACE('00000000-0000-0000-0000-0000XX000000','XX',LPAD(HEX(i),2,'0')));
208+
INSERT INTO t1 VALUES (REPLACE('00000000-0000-0000-0000-000000XX0000','XX',LPAD(HEX(i),2,'0')));
209+
INSERT INTO t1 VALUES (REPLACE('00000000-0000-0000-0000-00000000XX00','XX',LPAD(HEX(i),2,'0')));
210+
INSERT INTO t1 VALUES (REPLACE('00000000-0000-0000-0000-0000000000XX','XX',LPAD(HEX(i),2,'0')));
211+
END FOR;
212+
$$
213+
COMMIT;
214+
EXPLAIN SELECT * FROM t1 WHERE a='ff000000-0000-0000-0000-000000000000';
215+
id select_type table type possible_keys key key_len ref rows Extra
216+
1 SIMPLE t1 ref a a 17 const 2 Using where
217+
EXPLAIN SELECT * FROM t1 WHERE a='00ff0000-0000-0000-0000-000000000000';
218+
id select_type table type possible_keys key key_len ref rows Extra
219+
1 SIMPLE t1 ref a a 17 const 2 Using where
220+
EXPLAIN SELECT * FROM t1 WHERE a='0000ff00-0000-0000-0000-000000000000';
221+
id select_type table type possible_keys key key_len ref rows Extra
222+
1 SIMPLE t1 ref a a 17 const 2 Using where
223+
EXPLAIN SELECT * FROM t1 WHERE a='000000ff-0000-0000-0000-000000000000';
224+
id select_type table type possible_keys key key_len ref rows Extra
225+
1 SIMPLE t1 ref a a 17 const 2 Using where
226+
EXPLAIN SELECT * FROM t1 WHERE a='00000000-ff00-0000-0000-000000000000';
227+
id select_type table type possible_keys key key_len ref rows Extra
228+
1 SIMPLE t1 ref a a 17 const 2 Using where
229+
EXPLAIN SELECT * FROM t1 WHERE a='00000000-00ff-0000-0000-000000000000';
230+
id select_type table type possible_keys key key_len ref rows Extra
231+
1 SIMPLE t1 ref a a 17 const 2 Using where
232+
EXPLAIN SELECT * FROM t1 WHERE a='00000000-0000-ff00-0000-000000000000';
233+
id select_type table type possible_keys key key_len ref rows Extra
234+
1 SIMPLE t1 ref a a 17 const 2 Using where
235+
EXPLAIN SELECT * FROM t1 WHERE a='00000000-0000-00ff-0000-000000000000';
236+
id select_type table type possible_keys key key_len ref rows Extra
237+
1 SIMPLE t1 ref a a 17 const 2 Using where
238+
EXPLAIN SELECT * FROM t1 WHERE a='00000000-0000-0000-ff00-000000000000';
239+
id select_type table type possible_keys key key_len ref rows Extra
240+
1 SIMPLE t1 ref a a 17 const 2 Using where
241+
EXPLAIN SELECT * FROM t1 WHERE a='00000000-0000-0000-00ff-000000000000';
242+
id select_type table type possible_keys key key_len ref rows Extra
243+
1 SIMPLE t1 ref a a 17 const 2 Using where
244+
EXPLAIN SELECT * FROM t1 WHERE a='00000000-0000-0000-0000-ff0000000000';
245+
id select_type table type possible_keys key key_len ref rows Extra
246+
1 SIMPLE t1 ref a a 17 const 2 Using where
247+
DROP TABLE t1;
185248
#
186249
# End of 10.5 tests
187250
#

0 commit comments

Comments
 (0)