MariaDB 字符串相关操作的优化
在我们即将发布的 MariaDB 5.3 版本中,Monty 优化了内部字符串追加代码以提升性能。我使用未打补丁的 MariaDB 5.2 与打过补丁的 MariaDB 5.2 对比,通过 sql-bench 进行了测试,结果显示整体性能提升了约 3%。
Monty 对此补丁的细节描述如下:
优化字符串追加的补丁
在检查 mysql-test-run 用例的跟踪输出时,我注意到存在大量
重新分配(reallocation)调用。这很奇怪,因为 MariaDB/MySQL 的设计
理念是尽可能少地进行 malloc/realloc 操作。系统通常是先计算所需的缓冲区大小,
然后分配一个足够大的缓冲区以满足大多数使用情况。之后还有一些安全调用,
以便在需要时扩展缓冲区。
(Continued from p i=32)随着时间推移,MySQL 代码中发生的变化是,新的开发者开始使用未预先分配的缓冲区,
并且其中充满了大量的 append calls() 调用,
每次调用都会导致一次新的 realloc() 操作。我修复了几个最糟糕的情况,使其能够正确地预先分配缓冲区,
对于其他情况,我通过让重新分配过程具有自适应性,进行了一般性修复。
(Continued from p i=38)核心是将 realloc() 调用替换为以下函数
bool realloc_with_extra(uint32 arg_length) { if (extra_alloc < 4096) extra_alloc= extra_alloc*2+128; return realloc(arg_length + extra_alloc); }在 MySQL 5.3 中,这使得一些测试用例(在调试模式下)的速度提升了
25%。对于优化版本的 MySQL,我们获得了整体
3% 的性能提升。区别在于
在调试构建中,我们对 malloc() 调用进行了很多额外检查,
而更少的 malloc() 调用带来了显著的速度提升。完整的补丁可以在 MariaDB 5.3 树中通过执行以下命令查看:
bzr log -p -r monty@askmonty.org-20101108114354-jl61qx8e36gvbzm7
以下是 sql-bench 运行的详细结果。我使用默认设置运行了 MariaDB 5.2.2 上的 sql-bench,并使用了 MyISAM 作为存储引擎。
第 1 列以秒为单位。所有其他列均以相对值表示
于此。1.00 表示相同,较大的数字表示较慢。
1) MariaDB 5.2.2.
2) 打了 Monty 字符串追加优化补丁的 MariaDB 5.2.2。
3) 打了 Monty 字符串追加优化补丁的 MariaDB 5.2.2。
4) 打了 Monty 字符串追加优化补丁的 MariaDB 5.2.2。
每个测试后面的括号中的数字显示了特定测试执行了多少条 SQL 命令。
由于一个测试可能有很多不同的参数,这只能提供一个粗略的
执行情况概览。
我在一个相当快的机器上运行了测试,因此你可以忽略运行时间在 0-3 秒左右的结果。我正在调整测试,使其至少运行 5 秒,以便获得更可靠的结果。
我使用的机器是我们新的基准测试系统“pitbull”,我也曾用它来测试 MyISAM 分段键缓存性能。
# OS: Ubuntu 10.10 # Platform: x86_64 # CPU: Two-socket x hexa-core Intel Xeon X5660 @ 2.80GHz. With hyperthreading: 24CPUs # RAM: 28GB # Disk(s): 1 x ST3500320NS S-ATA
=================================================================================
Operation | 1| 2| 3| 4|
|mysql-Linu|mysql-Linu|mysql-Linu|mysql-Linu|
---------------------------------------------------------------------------------
Relative results per test (First column is in seconds): |
---------------------------------------------------------------------------------
ATIS | 407.00| 0.980| 0.983| 0.978|
alter-table | 112.00| 0.991| 0.955| 0.991|
big-tables | 425.00| 0.965| 0.953| 0.958|
connect | 403.00| 0.893| 0.963| 0.846|
create | 918.00| 0.997| 1.001| 0.971|
insert | 536.00| 1.007| 1.034| 1.011|
select | 417.00| 0.959| 0.868| 0.986|
wisconsin | 408.00| 1.007| 0.983| 0.985|
---------------------------------------------------------------------------------
The results per operation: |
---------------------------------------------------------------------------------
alter_table_add (992) | 73.00| 0.973| 0.945| 0.973|
alter_table_drop (496) | 38.00| 1.026| 0.947| 1.000|
connect (50000) | 41.00| 1.024| 1.024| 1.000|
connect+select_1_row (50000) | 48.00| 1.042| 1.042| 1.021|
connect+select_simple (50000) | 45.00| 1.022| 1.022| 1.022|
count (100) | 3.00| 0.667| 0.667| 0.667|
count_distinct (7000) | 22.00| 1.000| 1.000| 1.000|
count_distinct_2 (7000) | 38.00| 1.000| 1.000| 1.000|
count_distinct_big (720) | 19.00| 1.105| 1.000| 1.053|
count_distinct_group (7000) | 36.00| 0.667| 0.667| 0.972|
count_distinct_group_on_key (7000) | 29.00| 1.034| 1.000| 1.034|
count_distinct_group_on_key_parts (7| 33.00| 1.000| 0.697| 0.818|
count_distinct_key_prefix (7000) | 15.00| 1.000| 0.933| 1.000|
count_group (7000) | 33.00| 1.000| 0.606| 1.030|
count_group_on_key_parts (7000) | 27.00| 1.074| 1.000| 1.037|
count_group_with_order (7000) | 34.00| 1.000| 0.618| 1.029|
count_on_key (50100) | 66.00| 0.848| 0.955| 0.955|
create+drop (10000) | 450.00| 1.002| 1.007| 0.973|
create_MANY_tables (400) | 17.00| 1.059| 1.059| 1.059|
create_index (8) | 0.00| 1.000| 0.000| 1.000|
create_key+drop (10000) | 450.00| 0.991| 0.996| 0.967|
create_table (31) | 2.00| 0.500| 0.500| 0.500|
delete_all_many_keys (1) | 5.00| 1.200| 1.200| 1.000|
delete_big (1) | 0.00| 0.000| 0.000| 0.000|
delete_big_many_keys (128) | 5.00| 1.200| 1.200| 1.000|
delete_key (10000) | 2.00| 0.500| 0.500| 0.500|
delete_range (12) | 1.00| 2.000| 1.000| 1.000|
drop_index (8) | 1.00| 0.000| 1.000| 1.000|
drop_table (28) | 0.00| 0.000| 0.000| 0.000|
drop_table_when_MANY_tables (400) | 1.00| 0.000| 0.000| 0.000|
insert (350768) | 39.00| 1.103| 1.077| 1.051|
insert_duplicates (100000) | 9.00| 1.000| 1.444| 1.333|
insert_key (100000) | 25.00| 0.960| 1.040| 0.960|
insert_many_fields (140000) | 112.00| 0.982| 0.982| 0.982|
insert_select_1_key (1) | 1.00| 1.000| 1.000| 1.000|
insert_select_2_keys (1) | 0.00| 0.000| 1.000| 1.000|
min_max (60) | 1.00| 2.000| 1.000| 2.000|
min_max_on_key (85000) | 16.00| 1.000| 1.000| 1.000|
multiple_value_insert (100000) | 1.00| 0.000| 1.000| 1.000|
once_prepared_select (100000) | 13.00| 1.000| 1.308| 1.231|
order_by_big (10) | 5.00| 1.000| 1.200| 1.200|
order_by_big_key (10) | 6.00| 0.833| 1.000| 0.833|
order_by_big_key2 (10) | 5.00| 1.000| 1.000| 1.200|
order_by_big_key_desc (10) | 5.00| 1.200| 1.000| 1.200|
order_by_big_key_diff (10) | 6.00| 1.000| 0.833| 0.833|
order_by_big_key_prefix (10) | 5.00| 1.000| 1.200| 1.000|
order_by_key2_diff (500) | 1.00| 1.000| 1.000| 1.000|
order_by_key_prefix (500) | 1.00| 1.000| 1.000| 1.000|
order_by_range (500) | 1.00| 1.000| 0.000| 0.000|
outer_join (10) | 5.00| 1.000| 1.200| 1.000|
outer_join_found (10) | 5.00| 1.000| 1.000| 1.000|
outer_join_not_found (500) | 4.00| 1.250| 1.000| 1.250|
outer_join_on_key (10) | 5.00| 1.000| 0.800| 1.000|
prepared_select (100000) | 22.00| 0.955| 0.955| 0.955|
select_1_row (500000) | 52.00| 0.750| 0.788| 0.673|
select_1_row_cache (500000) | 50.00| 0.660| 0.700| 0.660|
select_2_rows (500000) | 57.00| 0.772| 0.947| 0.684|
select_big (80) | 5.00| 1.200| 1.000| 1.200|
select_big_str (50000) | 14.00| 1.071| 1.071| 1.071|
select_cache (10000) | 18.00| 1.000| 0.944| 0.944|
select_cache2 (10000) | 18.00| 0.944| 0.944| 0.944|
select_column+column (500000) | 53.00| 0.925| 0.830| 0.792|
select_diff_key (500) | 0.00| 0.000| 0.000| 0.000|
select_distinct (40000) | 113.00| 1.018| 1.009| 1.009|
select_group (140111) | 121.00| 1.008| 1.041| 1.000|
select_group_when_MANY_tables (400) | 0.00| 0.000| 0.000| 0.000|
select_join (5000) | 22.00| 1.000| 1.000| 1.000|
select_key (200000) | 43.00| 1.000| 0.977| 0.953|
select_key2 (200000) | 46.00| 0.978| 0.957| 0.957|
select_key2_return_key (200000) | 44.00| 1.000| 0.977| 0.955|
select_key2_return_prim (200000) | 46.00| 0.978| 0.935| 0.935|
select_key_prefix (200000) | 46.00| 1.022| 0.957| 0.957|
select_key_prefix_join (5000) | 131.00| 0.908| 0.893| 0.916|
select_key_return_key (200000) | 43.00| 0.953| 0.953| 0.953|
select_many_fields (140000) | 313.00| 0.958| 0.942| 0.949|
select_range (410) | 22.00| 0.955| 0.955| 1.000|
select_range_key2 (25010) | 5.00| 1.000| 1.200| 1.000|
select_range_prefix (25010) | 6.00| 1.000| 1.000| 1.000|
select_simple (500000) | 22.00| 1.000| 1.318| 0.955|
select_simple_cache (500000) | 21.00| 0.952| 1.524| 0.952|
select_simple_join (25000) | 22.00| 1.045| 1.045| 1.000|
update_big (10) | 4.00| 1.000| 1.000| 1.000|
update_of_key (50000) | 6.00| 1.167| 1.333| 1.333|
update_of_key_big (501) | 3.00| 1.000| 1.000| 0.667|
update_of_primary_key_many_keys (256| 3.00| 0.667| 1.000| 0.667|
update_with_key (300000) | 30.00| 1.133| 1.333| 1.333|
update_with_key_prefix (100000) | 10.00| 1.100| 1.400| 1.400|
wisc_benchmark (50014) | 403.00| 1.010| 0.988| 0.988|
---------------------------------------------------------------------------------
TOTALS | 3619.00| 0.978| 0.975| 0.966|
=================================================================================