Mariadb 5.5 比 MySQL 5.1 慢

Posted

技术标签:

【中文标题】Mariadb 5.5 比 MySQL 5.1 慢【英文标题】:Mariadb 5.5 slower than MySQL 5.1 【发布时间】:2016-05-02 21:02:21 【问题描述】:

我有一个查询在 mysql 5.1 服务器上运行大约需要 20 秒,但在 MariaDB 5.5 服务器上需要将近 15 分钟。 像 key_buffer_size 和 tmp_table_size 和 max_heap_table_size 这样的常见嫌疑人都是相等的(128M)。据我所知,大多数设置都是相等的(query_cache 等)

查询:

SELECT  products.id, 
concat(publications.company_name,' [',publications.quote,'] ', products.name) as n, 
products.impressions, 
products.contacts, 
is_channel, 
sl.i, 
count(*) 
FROM products 
LEFT JOIN publications ON products.publications_id = publications.id 
LEFT OUTER JOIN (  
    SELECT adspace.id AS i, 
    slots.products_id FROM adspace 
    LEFT JOIN  slots ON adspace.slots_id = slots.id 
        AND adspace.end > '2016-01-25 10:28:49' 
        WHERE adspace.active = 1) AS sl 
    ON sl.products_id = products.id  
WHERE 1 = 1 
AND publications.active=1 
GROUP BY products.id 
ORDER BY n ASC;

唯一的区别在于解释:

旧服务器(MySQL 5.1)

+----+-------------+--------------+--------+---------------+---------+---------+-----------------------------------------+--------+---------------------------------+
| id | select_type | table        | type   | possible_keys | key     | key_len | ref                                     | rows   | Extra                           |
+----+-------------+--------------+--------+---------------+---------+---------+-----------------------------------------+--------+---------------------------------+
|  1 | PRIMARY     | products     | ALL    | NULL          | NULL    | NULL    | NULL                                    |   6568 | Using temporary; Using filesort |
|  1 | PRIMARY     | publications | eq_ref | PRIMARY       | PRIMARY | 4       | db.products.publications_id |      1 | Using where                                 |
|  1 | PRIMARY     | <derived2>   | ALL    | NULL          | NULL    | NULL    | NULL                                    |  94478 |                                 |
|  2 | DERIVED     | adspace      | ALL    | NULL          | NULL    | NULL    | NULL                                    | 101454 | Using where                     |
|  2 | DERIVED     | slots        | eq_ref | PRIMARY       | PRIMARY | 4       | db.adspace.slots_id         |      1 |                                             |
+----+-------------+--------------+--------+---------------+---------+---------+-----------------------------------------+--------+---------------------------------+

新服务器 (MariaDB 5.5)

+------+-------------+--------------+--------+---------------+---------+---------+-----------------------------------------+--------+---------------------------------+
| id   | select_type | table        | type   | possible_keys | key     | key_len | ref                                     | rows   | Extra                           |
+------+-------------+--------------+--------+---------------+---------+---------+-----------------------------------------+--------+---------------------------------+
|    1 | SIMPLE      | products     | ALL    | test_idx      | NULL    | NULL    | NULL                                    |   6557 | Using temporary; Using filesort |
|    1 | SIMPLE      | publications | eq_ref | PRIMARY       | PRIMARY | 4       | db.products.publications_id |      1 | Using where                                 |
|    1 | SIMPLE      | adspace      | ALL    | NULL          | NULL    | NULL    | NULL                                    | 100938 | Using where                     |
|    1 | SIMPLE      | slots        | eq_ref | PRIMARY       | PRIMARY | 4       | db.adspace.slots_id         |      1 | Using where                                 |
+------+-------------+--------------+--------+---------------+---------+---------+-----------------------------------------+--------+---------------------------------+

在新服务器的产品表中添加了索引以加快速度,但无济于事。

引擎变量:

旧服务器:

mysql> show variables like '%engine%';
+---------------------------+--------+
| Variable_name             | Value  |
+---------------------------+--------+
| engine_condition_pushdown | ON     |
| storage_engine            | MyISAM |
+---------------------------+--------+

mysql> show variables like '%buffer_pool%';
+-------------------------+---------+
| Variable_name           | Value   |
+-------------------------+---------+
| innodb_buffer_pool_size | 8388608 |
+-------------------------+---------+

新服务器:

MariaDB [db]> show variables like '%engine%';
+---------------------------+--------+
| Variable_name             | Value  |
+---------------------------+--------+
| default_storage_engine    | InnoDB |
| engine_condition_pushdown | OFF    |
| storage_engine            | InnoDB |
+---------------------------+--------+


MariaDB [db]> show variables like '%buffer_pool%';
+---------------------------------------+-----------+
| Variable_name                         | Value     |
+---------------------------------------+-----------+
| innodb_blocking_buffer_pool_restore   | OFF       |
| innodb_buffer_pool_instances          | 1         |
| innodb_buffer_pool_populate           | OFF       |
| innodb_buffer_pool_restore_at_startup | 0         |
| innodb_buffer_pool_shm_checksum       | ON        |
| innodb_buffer_pool_shm_key            | 0         |
| innodb_buffer_pool_size               | 134217728 |
+---------------------------------------+-----------+

查询中使用的所有表都是 MyISAM(旧服务器和新服务器)

分析显示,旧查询在“复制到 tmp 表”中花费了大约 16 秒,而新服务器在此情况下花费了大约 800 秒。

新服务器都有SSD盘存储,旧服务器有普通盘。

编辑:我还有一个 MySQL 5.5 服务器,查询只需要大约 10 秒。就我所见,也具有所有相同的设置。

我试着用表格总结一下:

Location:       Customer                    Own                     Customer
MySQL Type:     MySQL                       MySQL                   MariaDB
Mysql Version:  5.1.56-community-log        5.5.39-1-log (Debian)   5.5.44-MariaDB-log
HDD:            Normal                      Normal                  SSD
Type:           Virtual                     Real                    Virtual
Query time:     ~15s                        ~10s                    ~15min
DB engine:      MyISAM                      InnoDB                  InnoDB
Table Engine:   MyISAM                      MyISAM                  MyISAM

我不想重写查询(虽然它可能需要一些工作)但我想找出两台机器之间的区别,我猜是 MariaDB 中不理想的设置但我找不到它。

【问题讨论】:

您确定对两个数据库使用相同的表引擎吗? 也许这回答了你的问题:完全不同的存储引擎... 如果我理解正确,即使表级别的引擎相同,数据库级别的引擎也会有所作为? 编辑:我也有一个 MySQL 5.5 的服务器,它只需要 8 秒。所以它应该与 MariaDB 相关。由于 Mysql 5.5 还有默认引擎=InnoDB 和存储引擎=InnoDB。 对于新服务器,SHOW VARIABLES LIKE '%buffer_pool%'; 说什么?基本上,默认情况下,InnoDB 已“调整”以使用低 RAM 设置。新服务器有多少内存,你分配给 InnoDB 多少,你的数据库中有多少数据?不同性能级别的原因是 InnoDB 显然无法为 I/O 使用足够的内存,因此它从磁盘读取 - 在您的情况下,您的磁盘非常慢,因为扫描 1m 以下的记录需要很长时间。 【参考方案1】:

从上面的解释可以看出使用了Derived Table Merge Optimization。不幸的是,在你的情况下,这意味着不是只对adspacesome ~6k 进行一次全表扫描。

一个可能的解决方案是通过发出set optimizer_switch='derived_merge=off'; 在查询之前禁用优化。向后兼容的替代方法是将GROUP BY adspace.id, slots.products_id 添加到子查询中(如果它不改变结果 - 最安全的是对所有连接表的 PK 进行分组),这通过具有不同的语义来禁止合并。

据报道,optimizer bug 对此有所报道 - 您的案例可能会有所帮助。

【讨论】:

derived_merge=OFF 的设置使查询从 ~15 分钟缩短到 ~0.3 秒。小幅提速:) @darkownage - 我对你的评论感到困惑 - 这是显着的减少吗?还是增加 @RickJames - 很抱歉这个奇怪的句子:) 查询从大约 15 分钟到 0.5 秒。所以速度提升是巨大的。我们选择关闭这个“优化”,因为它是阻塞的,并且查询完成了它的工作并且是最简单的修复。希望这能回答你的问题:) @jkavalik 你救了我的命。花了一整天的时间试图弄清楚为什么在旧的 MySQL 数据库服务器上花费 0.9 秒的查询在 MariaDB 服务器上花费了 4.5 分钟。关闭 'derived_merge' 标志将 MariaDB 查询的时间减少到 0.8 秒。有什么不同!如果性能影响如此之大,我不明白为什么这个标志默认为 ON。或者至少 MariaDB 应该为从 MySQL 切换的用户更好地记录它。 @Johnny 仅在特定情况下速度较慢。它对其他查询有很大帮助。唯一的问题是优化器无法自动识别有问题的情况,这可能是一个相当困难的问题。【参考方案2】:

这可能不是答案,但 MariaDB 5.5 使用不同的算法来执行连接。据我所知,在 MariaDB 5.5 中引入了 Batch Key Access Join。旧版本的 MySQL 或 MariaDB 使用不同的版本。 虽然在大多数情况下新版本应该更快,但也许您的特定表格在使用旧表格时表现更好。

编辑:这个答案可能已经过时,因为您提到您使用了不同的存储引擎。

【讨论】:

以上是关于Mariadb 5.5 比 MySQL 5.1 慢的主要内容,如果未能解决你的问题,请参考以下文章

MariaDB 10.4.13 性能比 MySQL 5.7.30 慢

MySQL的二进制安装方式

MySQL审计工具Audit插件使用

数据库 之 自动化编译安装Mariadb数据库

CentOS 7 yum安装MySQL

在 CentOS 6.2 中将 MySQL 版本从 5.1 更新到 5.5