【问题标题】:Slow query times on AWS RDS but not on DigitalOcean LAMPAWS RDS 上的查询时间很慢,但在 DigitalOcean LAMP 上却没有
【发布时间】:2016-05-22 13:44:47
【问题描述】:

我有一个数据库转储和 MySQL 查询在三个环境中是相同的,但在 AWS 上非常慢,我想知道原因。

查询在 AWS RDS 上运行 15s ~ 30s,但在 DigitalOcean LAMP 上运行 8ms ~ 12ms。 (对照实验:本地 MAMP 堆栈运行 8s ~ 10s)。

DigitalOcean LAMP 堆栈怎么可能在毫秒内运行相同的查询?

背景故事:我从 DigitalOcean 迁移到 AWS RDS。我对查询速度感到非常震惊。我不知道为什么。

注意:使用 T2.micro RDS 实例。还用 M4.2xLarge RDS 实例进行了测试。查询时间相同。

这里是查询:

SELECT `t`.`col1` AS `t0_c0`,
       `t`.`col2` AS `t0_c1`,
       `t`.`col3` AS `t0_c2`,
       `t`.`col4` AS `t0_c3`,
       `t`.`col5` AS `t0_c4`,
       `t`.`col6` AS `t0_c5`,
       `t`.`col7` AS `t0_c6`,
       `t`.`col8` AS `t0_c7`,
       `t`.`col9` AS `t0_c8`,
       `t`.`col10` AS `t0_c9`,
       `t`.`col11` AS `t0_c10`,
       `t`.`col12` AS `t0_c11`,
       `t`.`col13` AS `t0_c12`,
       `t`.`col14` AS `t0_c13`,
       `t`.`col15` AS `t0_c14`,
       `t`.`col16` AS `t0_c15`,
       `t`.`col17` AS `t0_c16`,
       `t`.`col18` AS `t0_c17`,
       `t`.`col19` AS `t0_c18`,
       `t`.`col20` AS `t0_c19`,
       `t`.`col21` AS `t0_c20`,
       `t`.`col22` AS `t0_c21`,
       `t`.`col23` AS `t0_c22`,
       `t`.`col24` AS `t0_c23`,
       `t`.`col25` AS `t0_c24`,
       `t`.`col26` AS `t0_c25`,
       `t`.`col27` AS `t0_c26`,
       `t`.`col28` AS `t0_c27`,
       `t`.`col29` AS `t0_c28`,
       `t`.`col30` AS `t0_c29`,
       `t`.`col31` AS `t0_c30`,
       `t`.`col32` AS `t0_c31`,
       `t`.`col33` AS `t0_c32`,
       `t`.`col34` AS `t0_c33`,
       `t`.`col35` AS `t0_c34`,
       `t`.`col36` AS `t0_c35`,
       `t`.`col37` AS `t0_c36`,
       `t`.`col38` AS `t0_c37`,
       `t`.`col39` AS `t0_c38`,
       `t`.`col40` AS `t0_c39`,
       `t`.`col41` AS `t0_c40`,
       `t`.`col42` AS `t0_c41`,
       `t`.`col43` AS `t0_c42`,
       `t`.`col44` AS `t0_c43`,
       `t`.`col45` AS `t0_c44`,
       `t`.`col46` AS `t0_c45`,
       `t`.`col47` AS `t0_c46`,
       `t`.`col48` AS `t0_c47`,
       `t`.`col49` AS `t0_c48`,
       COUNT(exactTagMatch.id) AS exactMatches,
       COUNT(tags.id) AS matches,
       `vendor`.`col1` AS `t1_c0`,
       `vendor`.`col2` AS `t1_c1`,
       `vendor`.`col3` AS `t1_c2`,
       `vendor`.`col4` AS `t1_c3`,
       `vendor`.`col5` AS `t1_c4`,
       `vendor`.`col6` AS `t1_c5`,
       `vendor`.`col7` AS `t1_c6`,
       `vendor`.`col8` AS `t1_c7`,
       `vendor`.`col9` AS `t1_c8`,
       `vendor`.`col10` AS `t1_c9`,
       `vendor`.`col11` AS `t1_c10`,
       `vendor`.`col12` AS `t1_c11`,
       `vendor`.`col13` AS `t1_c12`,
       `vendor`.`col14` AS `t1_c13`,
       `vendor`.`col15` AS `t1_c14`,
       `vendor`.`col16` AS `t1_c15`,
       `vendor`.`col17` AS `t1_c16`,
       `vendor`.`col18` AS `t1_c17`,
       `vendor`.`col19` AS `t1_c18`,
       `vendor`.`col20` AS `t1_c19`,
       `vendor`.`col21` AS `t1_c20`,
       `vendor`.`col22` AS `t1_c21`,
       `vendor`.`col23` AS `t1_c22`,
       `vendor`.`col24` AS `t1_c23`,
       `vendor`.`col25` AS `t1_c24`,
       `vendor`.`col26` AS `t1_c25`,
       `vendor`.`col27` AS `t1_c26`,
       `vendor`.`col28` AS `t1_c27`,
       `tags`.`col1` AS `t2_c0`,
       `tags`.`col2` AS `t2_c1`,
       `tags`.`col3` AS `t2_c2`,
       `tags`.`col4` AS `t2_c3`,
       `tags`.`col5` AS `t2_c4`,
       `tags`.`col6` AS `t2_c5`,
       `tags`.`col7` AS `t2_c6`,
       `tags`.`col8` AS `t2_c7`,
       `tags`.`col9` AS `t2_c8`,
       `tags`.`col10` AS `t2_c9`,
       `tags`.`col11` AS `t2_c10`,
       `tags`.`col12` AS `t2_c11`
FROM `table1` `t`
LEFT JOIN table3 AS exactTagMatch ON exactTagMatch.col1 = 1545
AND exactTagMatch.col1 = t.col1
LEFT OUTER JOIN `table2` `vendor` ON (`t`.`col1`=`vendor`.`id`)
LEFT OUTER JOIN `table3` `tags_tags` ON (`t`.`col1`=`tags_tags`.`col1`)
LEFT OUTER JOIN `table3` `tags` ON (`tags`.`id`=`tags_tags`.`col1`)
WHERE (((((t.col2 LIKE '%search query%')
          OR (vendor.col2 LIKE '%search query%'))
         OR (tags.col1 IN ('1386',
                         '1407',
                         '1408',
                         '1409',
                         '1410',
                         '1411',
                         '1416',
                         '1418',
                         '1512',
                         '1519',
                         '1528',
                         '1545',
                         '1583',
                         '1584',
                         '1585',
                         '1586',
                         '1604',
                         '1605')))
        AND (t.col2='active'))
       AND (t.col3='0'))
GROUP BY t.col1
ORDER BY exactMatches DESC,
         matches DESC,
         t.col5 DESC LIMIT 12;

MySQL 计划:AWS RDS(慢速)

+----+-------------+---------------+--------+---------------------------------+-------------------------+---------+-----------------------+-------+--------------------------------------------------------+
| id | select_type | table         | type   | possible_keys                   | key                     | key_len | ref                   | rows  | Extra                                                  |
+----+-------------+---------------+--------+---------------------------------+-------------------------+---------+-----------------------+-------+--------------------------------------------------------+
|  1 | SIMPLE      | t             | ref    | PRIMARY,activity_status_premium | activity_status_premium | 2       | const,const           |   594 | Using index condition; Using temporary; Using filesort |
|  1 | SIMPLE      | exactTagMatch | ALL    | NULL                            | NULL                    | NULL    | NULL                  | 24434 | Using where; Using join buffer (Block Nested Loop)     |
|  1 | SIMPLE      | vendor        | eq_ref | PRIMARY                         | PRIMARY                 | 4       | ebdb.t.vendor_id      |     1 | NULL                                                   |
|  1 | SIMPLE      | tags_tags     | ALL    | NULL                            | NULL                    | NULL    | NULL                  | 24434 | Using where; Using join buffer (Block Nested Loop)     |
|  1 | SIMPLE      | tags          | eq_ref | PRIMARY                         | PRIMARY                 | 4       | ebdb.tags_tags.tag_id |     1 | Using where                                            |
+----+-------------+---------------+--------+---------------------------------+-------------------------+---------+-----------------------+-------+--------------------------------------------------------+
5 rows in set (0.02 sec)

MySQL 计划:DigitalOcean(快速)

+----+-------------+---------------+--------+-------------------------+-------------------------+---------+-------------------------------+-------+----------------------------------------------+
| id | select_type | table         | type   | possible_keys           | key                     | key_len | ref                           | rows  | Extra                                        |
+----+-------------+---------------+--------+-------------------------+-------------------------+---------+-------------------------------+-------+----------------------------------------------+
|  1 | SIMPLE      | t             | ref    | activity_status_premium | activity_status_premium | 2       | const,const                   |   590 | Using where; Using temporary; Using filesort |
|  1 | SIMPLE      | exactTagMatch | ALL    | NULL                    | NULL                    | NULL    | NULL                          | 32473 |                                              |
|  1 | SIMPLE      | vendor        | eq_ref | PRIMARY                 | PRIMARY                 | 4       | db.t.vendor_id      |     1 |                                              |
|  1 | SIMPLE      | tags_tags     | ALL    | NULL                    | NULL                    | NULL    | NULL                          | 32473 |                                              |
|  1 | SIMPLE      | tags          | eq_ref | PRIMARY                 | PRIMARY                 | 4       | db.tags_tags.tag_id |     1 | Using where                                  |
+----+-------------+---------------+--------+-------------------------+-------------------------+---------+-------------------------------+-------+----------------------------------------------+
5 rows in set (0.01 sec)

这是 MySQL 版本之间的比较:

MySQL 版本:AWS RDS(慢速)

mysql> SHOW VARIABLES LIKE "%version%";
+-------------------------+------------------------------+
| Variable_name           | Value                        |
+-------------------------+------------------------------+
| innodb_version          | 5.6.27                       |
| protocol_version        | 10                           |
| slave_type_conversions  |                              |
| version                 | 5.6.27                   |
| version_comment         | MySQL Community Server (GPL) |
| version_compile_machine | x86_64                       |
| version_compile_os      | Linux                        |
+-------------------------+------------------------------+
7 rows in set (0.03 sec)

MySQL 版本:DigitalOcean(快速)

mysql> SHOW VARIABLES LIKE "%version%";
+-------------------------+-------------------------+
| Variable_name           | Value                   |
+-------------------------+-------------------------+
| innodb_version          | 5.5.44                  |
| protocol_version        | 10                      |
| slave_type_conversions  |                         |
| version                 | 5.5.44-0ubuntu0.14.04.1 |
| version_comment         | (Ubuntu)                |
| version_compile_machine | x86_64                  |
| version_compile_os      | debian-linux-gnu        |
+-------------------------+-------------------------+
7 rows in set (0.01 sec)

这是.cnf文件之间的比较:https://www.diffnow.com/?report=ze4m0

注意:必须使用外部链接,因为正文超出了字符数


更新

刚刚进行了更多测试。在 DigitalOcean 上,我第一次运行查询需要 14 秒。此后它在毫秒内运行。我相信那里正在进行某种缓存/索引。想知道会导致这种情况的原因。

【问题讨论】:

  • 事实上,也许是一种清晰易读的形式。了解 DO 使用所有固态设备。
  • 我知道这很辛苦,但是你能不能给我们两个服务器和 my.cnf 文件中的 MySQL 版本?优化器的输出是相似的,但差异很大,以至于有点令人困惑。在这两种情况下,对计数的全表扫描都将具有破坏性。由于 SAN 路由,我也看到了非常奇怪的行为(像这样的事情)。鉴于 AWS 和 DO 的性质,您可能无法确定这是否是一个问题。不过,它确实“感觉”有点像 I/O 问题。
  • 感谢您的询问和解释计划,下次请make them readable
  • 我正抓着稻草——似乎没有任何明显的迹象。 query_cache_size 是 AWS 上的大小的 1/16(左右),因为它在 DO 上(在你的解释中有一些可能是一个问题)1048576 AWS,16777216 DO。另一方面,AWS innodb_buffer_pool_size 大 4 倍。没有太多其他东西冒出来。几篇有趣的文章:bugs.mysql.com/bug.php?id=71130percona.com/blog/2013/02/18/is-mysql-5-6-slower-than-mysql-5-5dba.stackexchange.com/questions/66406/…
  • 很高兴您修复了它!请注意,我已经恢复了 SQL 查询,因为解释计划与它直接相关。虽然事实证明问题是由于配置切换造成的,但一旦发现答案,我们不会追溯修改问题 - Stack Overflow 的目的是保留问题和答案,以便未来的读者可以从中学习。

标签: mysql database amazon-web-services amazon-rds digital-ocean


【解决方案1】:

在 MySql 5.6+ 中,查询缓存默认是禁用的。在您的 my.cnf 文件中,您可以通过查找“query_cache_type”看到它 - 您会看到它在 RDS 上处于关闭状态,但在 DO db 上却没有。

我敢打赌,如果您第一次在 DO 上运行查询,它的速度将会相似 - 没有其他配置更改可能会导致如此巨大的差异。

由于默认情况下缓存现在处于关闭状态,您应该阅读更改的原因 - 如果您需要,请自行决定,但请注意它是故意禁用的!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-20
    • 2017-09-29
    • 2015-05-05
    • 1970-01-01
    • 2011-11-09
    • 1970-01-01
    • 1970-01-01
    • 2021-12-23
    相关资源
    最近更新 更多