我有一个带有InnoDB表的MySQL数据库,总计超过10个GB的数据,我想从MySQL 5.5迁移到MySQL 5.7。我的查询看起来有点像:
SELECT dates.date, count(mySub2.myColumn1), sum(mySub2.myColumn2)
FROM (
SELECT date
FROM dates -- just a table containing all possible dates next 5 years
WHERE date BETWEEN '2016-06-01' AND '2016-09-03'
) AS dates
LEFT JOIN (
SELECT o.id, time_start, time_end
FROM order AS o
INNER JOIN order_items AS oi on oi.order_id = o.id
WHERE time_start BETWEEN '2016-06-01' AND '2016-09-03'
) AS mySub1 ON dates.date >= mySub1.time_start AND dates.date < mySub1.time_end
LEFT JOIN (
SELECT o.id, time_start, time_end
FROM order AS o
INNER JOIN order_items AS oi on oi.order_id = o.id
WHERE o.shop_id = 50 AND time_start BETWEEN '2016-06-01' AND '2016-09-03'
) AS mySub2 ON dates.date >= mySub2.time_start AND dates.date < mySub2.time_end
GROUP BY dates.date;
我的问题是这个查询在MySQL 5.5中执行速度很快,但在MySQL 5.7中速度极慢。
在MySQL 5.5中,它首先占用1秒以上,并且&lt;每次重复执行都需要0.001秒而不重启MySQL 在MySQL 5.7中,它首先需要11.5秒,每次重复执行需要1.4秒而不重启MySQL 我添加到查询中的LEFT JOIN越多,查询在MySQL 5.7中就越慢。
现在,两个实例都运行在同一台计算机上,在同一个硬盘驱动器上,并且具有相同的my.ini设置。所以它不是硬件 执行计划确实有所不同,但我不知道该怎么做。
这是MySQL 5.5上的EXPLAIN EXTENDED:
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | extra |
|----|-------------|------------|-------|---------------|-------------|---------|-----------|-------|----------|---------------------------------|
| 1 | PRIMARY | dates | ALL | | | | | 95 | 100.00 | Using temporary; Using filesort |
| 1 | PRIMARY | <derived2> | ALL | | | | | 281 | 100.00 | '' |
| 1 | PRIMARY | <derived3> | ALL | | | | | 100 | 100.00 | '' |
| 3 | DERIVED | o | ref | xxxxxx | shop_id_fk | 4 | '' | 1736 | 100.00 | '' |
| 3 | DERIVED | oc | ref | xxxxx | order_id_fk | 4 | myDb.o.id | 1 | 100.00 | Using index |
| 2 | DERIVED | o | range | xxxx | date_start | 3 | | 17938 | 100.00 | Using where |
| 2 | DERIVED | oc | ref | xxx | order_id_fk | 4 | myDb.o.id | 1 | 100.00 | Using where |
这是MySQL 5.7上的EXPLAIN EXTENDED:
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | extra |
|----|-------------|-------|--------|---------------|-------------|---------|------------------|------|----------|----------------|
| 1 | SIMPLE | dates | ALL | | | | | 95 | 100.00 | Using filesort |
| 1 | SIMPLE | oi | ref | xxxxxx | order_id_fk | 4 | const | 228 | 100.00 | |
| 1 | SIMPLE | o | eq_ref | xxxxx | PRIMARY | 4 | myDb.oi.order_id | 1 | 100.00 | Using where |
| 1 | SIMPLE | o | ref | xxxx | shop_id_fk | 4 | const | 65 | 100.00 | Using where |
| 1 | SIMPLE | oi | ref | xxx | order_id_fk | 4 | myDb.o.id | 1 | 100.00 | Using where |
我想理解为什么MySQL会处理相同的查询,以及如何调整MySQL 5.7以便更快? 我没有寻求帮助重写查询更快,因为这是我自己已经做的事情。
答案 0 :(得分:9)
正如评论中所读,@ wchiquito建议查看optimizer_switch
。在这里,我发现交换机derived_merge
可以设置为关闭,以修复这个新的,并在这种特定情况下不受欢迎的行为。
set session optimizer_switch='derived_merge=off';
解决了这个问题
(这也可以使用set global ...
完成,也可以放在my.cnf / my.ini中)
答案 1 :(得分:1)
答案 2 :(得分:0)
在迁移到mysql 5.7之后,我也面临缓慢的查询执行问题,就我而言,甚至将会话optimizer_switch设置为'derived_merge = off';没有帮助。
然后,我点击了以下链接:https://www.saotn.org/mysql-innodb-performance-improvement/,查询速度恢复正常。
具体来说,我的更改只是按照链接中的说明在my.ini中设置了这四个参数:
innodb_buffer_pool_size
innodb_buffer_pool_instances
innodb_write_io_threads
innodb_read_io_threads