【发布时间】:2016-06-09 18:48:34
【问题描述】:
我有一个 MySQL 数据库,其中 InnoDB 表汇总了超过 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 秒,每次重复执行需要
在 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 调整得更快?
我不是在寻求帮助以更快地重写查询,因为这是我自己已经在做的事情。
【问题讨论】:
-
只是为了确保... (1) 查询完全相同? (2)表,包括索引,完全一样吗?
-
@Uueerdo 是的,完全正确。起初它在不同的机器上。但是当我遇到这种情况时,我在笔记本电脑上同时安装了 MySQL 5.5 和 MySQL 5.7,并两次导入了相同的转储。我采用了相同的 my.ini 并对其进行了最少的更改,因此我可以一次运行这两个实例。所以一切都是一样的。然后我才对它们运行相同的查询。
-
那我就不知道了。我的猜测是针对对这个特定(和特殊)查询产生负面影响的更常见的查询类型进行优化。
-
查询计划会不会是无关的,而 MySQL 5.7 只是默认关闭了一些功能,例如某种键缓冲?
标签: mysql database performance migration