【发布时间】: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=71130 和 percona.com/blog/2013/02/18/is-mysql-5-6-slower-than-mysql-5-5 和 dba.stackexchange.com/questions/66406/…。
-
很高兴您修复了它!请注意,我已经恢复了 SQL 查询,因为解释计划与它直接相关。虽然事实证明问题是由于配置切换造成的,但一旦发现答案,我们不会追溯修改问题 - Stack Overflow 的目的是保留问题和答案,以便未来的读者可以从中学习。
标签: mysql database amazon-web-services amazon-rds digital-ocean