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