-
Notifications
You must be signed in to change notification settings - Fork 0
AUTOID 与 UUID 性能测试
tumayun edited this page Mar 11, 2015
·
4 revisions
在 my.cnf 文件末尾添加如下配置
max_allowed_packet=100M
innodb_buffer_pool_size=2G
CREATE TABLE `test1s` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`hashed_id` varchar(16) COLLATE utf8mb4_unicode_ci NOT NULL,
`name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `index_test1_on_hashed_id` (`hashed_id`),
KEY `index_test1s_on_name` (`name`(191))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
CREATE TABLE `test2s` (
`id` binary(16) NOT NULL,
`name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `index_test2s_on_name` (`name`(191))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
user system total real
autoid insert 1th(M): 0.100000 0.060000 0.160000 ( 15.519051)
autoid insert 2th(M): 0.130000 0.040000 0.170000 ( 18.436685)
autoid insert 3th(M): 0.090000 0.050000 0.140000 ( 18.134797)
autoid insert 4th(M): 0.070000 0.090000 0.160000 ( 18.576962)
autoid insert 5th(M): 0.070000 0.040000 0.110000 ( 19.521584)
autoid insert 6th(M): 0.050000 0.030000 0.080000 ( 20.520616)
autoid insert 7th(M): 0.090000 0.030000 0.120000 ( 20.975899)
autoid insert 8th(M): 0.050000 0.040000 0.090000 ( 22.163973)
autoid insert 9th(M): 0.070000 0.030000 0.100000 ( 21.911627)
autoid insert 10th(M): 0.050000 0.030000 0.080000 ( 23.018506)
uuid insert 1th(M): 0.110000 0.050000 0.160000 ( 15.847269)
uuid insert 2th(M): 0.060000 0.070000 0.130000 ( 15.641427)
uuid insert 3th(M): 0.080000 0.040000 0.120000 ( 15.027765)
uuid insert 4th(M): 0.050000 0.080000 0.130000 ( 15.359175)
uuid insert 5th(M): 0.090000 0.080000 0.170000 ( 15.245869)
uuid insert 6th(M): 0.060000 0.090000 0.150000 ( 15.235896)
uuid insert 7th(M): 0.090000 0.080000 0.170000 ( 15.360716)
uuid insert 8th(M): 0.060000 0.090000 0.150000 ( 15.374005)
uuid insert 9th(M): 0.090000 0.080000 0.170000 ( 15.311570)
uuid insert 10th(M): 0.060000 0.090000 0.150000 ( 15.395394)
- 数据插入性能方面 UUID 略胜一筹
name 有非主键索引,hashed_id 有唯一性索引
user system total real
autoid/hashed_id: 978.910000 147.270000 1126.180000 (1736.307611)
uuid/id: 945.670000 143.720000 1089.390000 (1541.445782)
autoid/name: 950.880000 142.000000 1092.880000 (1961.690465)
uuid/name: 921.100000 136.620000 1057.720000 (1888.261413)
- UUID 做主键查询会比 hashed_id 要快那么一点点
- name 等非主键索引字段的查询,UUID 优于 AUTOID
在 Rails Console 里面执行。
ActiveRecord::Base.logger = ActiveSupport::Logger.new('/dev/null')
ActiveRecord::Base.connection.execute "drop table test1s"
ActiveRecord::Base.connection.execute "drop table test2s"
ActiveRecord::Base.connection.execute "reset query cache"
ActiveRecord::Base.connection.execute <<-SQL
CREATE TABLE `test1s` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`hashed_id` varchar(16) COLLATE utf8mb4_unicode_ci NOT NULL,
`name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `index_test1_on_hashed_id` (`hashed_id`),
KEY `index_test1s_on_name` (`name`(191))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
SQL
ActiveRecord::Base.connection.execute <<-SQL
CREATE TABLE `test2s` (
`id` binary(16) NOT NULL DEFAULT '',
`name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `index_test2s_on_name` (`name`(191))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
SQL
ActiveRecord::Base.connection.execute <<-SQL
CREATE TRIGGER `set_test2s_id_as_uuid` BEFORE INSERT ON `test2s`
FOR EACH ROW
BEGIN
SET NEW.id = UNHEX(REPLACE(UUID(),'-',''));
END
SQL
autoid_contents, uuid_contents = [], []
10.times do |a|
autoid_values, uuid_values = [], []
1000000.times do |b|
autoid_values << "('#{SecureRandom.hex(8)}','test#{a}_#{b}')"
uuid_values << "('test#{a}_#{b}')"
end
autoid_contents << "INSERT INTO test1s (hashed_id, name) VALUES #{autoid_values.join(',')}"
uuid_contents << "INSERT INTO test2s (name) VALUES #{uuid_values.join(',')}"
end
Benchmark.bm do |x|
autoid_contents.each_with_index do |sql1, index|
x.report("autoid insert #{index + 1}th(M):") {
ActiveRecord::Base.connection.execute(sql1)
}
end
uuid_contents.each_with_index do |sql2, index|
x.report("uuid insert #{index + 1}th(M):") {
ActiveRecord::Base.connection.execute(sql2)
}
end
end
hashed_ids = ActiveRecord::Base.connection.execute("SELECT hashed_id FROM test1s").to_a.flatten
uuids = ActiveRecord::Base.connection.execute("SELECT id FROM test2s").map do |array|
array.first.unpack('H*').first
end
names = ActiveRecord::Base.connection.execute("SELECT name FROM test1s").to_a.flatten
ActiveRecord::Base.connection.execute "reset query cache"
# 此处需重启 Mysql,重置 buffer。
Benchmark.bm do |x|
x.report('autoid/hashed_id:') {
hashed_ids.each do |hashed_id|
ActiveRecord::Base.connection.execute("SELECT * FROM test1s WHERE hashed_id = '#{hashed_id}' LIMIT 1")
end
}
end
# 此处需重启 Mysql,重置 buffer。
Benchmark.bm do |x|
x.report('uuid/id:') {
uuids.each do |uuid|
ActiveRecord::Base.connection.execute("SELECT * FROM test2s WHERE id = x'#{uuid}' LIMIT 1")
end
}
end
# 此处需重启 Mysql,重置 buffer。
Benchmark.bm do |x|
x.report('autoid/name:') {
names.each do |name|
ActiveRecord::Base.connection.execute("SELECT * FROM test1s WHERE name = '#{name}'")
end
}
end
# 此处需重启 Mysql,重置 buffer。
Benchmark.bm do |x|
x.report('uuid/name:') {
names.each do |name|
ActiveRecord::Base.connection.execute("SELECT * FROM test2s WHERE name = '#{name}'")
end
}
end