【问题标题】:Queries in mysql 5.7 2 or more times slower than in 5.1mysql 5.7 中的查询比 5.1 慢 2 倍或更多倍
【发布时间】:2018-12-22 00:39:26
【问题描述】:

我们将完整的数据库从 MySQL 5.1.63 迁移到不同的(更好一点的)服务器到 MySQL 5.7.22。现在大多数查询平均慢了 2 倍。 MySQL 5.1 我们并没有做太多的优化。

这是我们更改的配置:

table_open_cache            = 4096
tmp_table_size=256M
max_heap_table_size=256M
query_cache_limit       = 1000000
query_cache_size        = 32000000
innodb_buffer_pool_size = 3200M
innodb_log_buffer_size  = 1024M

这是一个具体的例子:

我想获取课程中所有被标记为教师的人:

SELECT id, TRIM(CONCAT_WS(" ", name, lastname)) AS name
FROM person
WHERE id IN (SELECT DISTINCT teacher_id FROM course)
ORDER BY name;

运行时间:

  • mysql 5.1:0.03s。后续查询:0.00s
  • mysql 5.7:1.27s。后续查询:0.80s

相差40倍以上。

在 5.1 中解释:

+----+--------------------+----------+----------------+--------------------+--------------------+---------+------+-------+-----------------------------+
| id | select_type        | table    | type           | possible_keys      | key                | key_len | ref  | rows  | Extra                       |
+----+--------------------+----------+----------------+--------------------+--------------------+---------+------+-------+-----------------------------+
|  1 | PRIMARY            | person   | ALL            | NULL               | NULL               | NULL    | NULL | 16293 | Using where; Using filesort |
|  2 | DEPENDENT SUBQUERY | course   | index_subquery | teacher_id         | teacher_id         | 5       | func |  2677 | Using index; Using where    |
+----+--------------------+----------+----------------+--------------------+--------------------+---------+------+-------+-----------------------------+

在 5.7 中解释:

+----+--------------+-------------+------------+--------+--------------------+--------------------+---------+----------------------+--------+----------+-------------+
| id | select_type  | table       | partitions | type   | possible_keys      | key                | key_len | ref                  | rows   | filtered | Extra       |
+----+--------------+-------------+------------+--------+--------------------+--------------------+---------+----------------------+--------+----------+-------------+
|  1 | SIMPLE       | person      | NULL       | ALL    | PRIMARY            | NULL               | NULL    | NULL                 |  16491 |   100.00 | Using where |
|  1 | SIMPLE       | <subquery2> | NULL       | eq_ref | <auto_key>         | <auto_key>         | 5       | db.person.id         |      1 |   100.00 | Using where |
|  2 | MATERIALIZED | course      | NULL       | index  | teacher_id         | teacher_id         | 5       | NULL                 | 109741 |   100.00 | Using index |
+----+--------------+-------------+------------+--------+--------------------+--------------------+---------+----------------------+--------+----------+-------------+

现在如果我这样写查询:

select distinct person.id, trim(concat_ws(" ", name, lastname)) as name 
from person, course
where person.id = course.teacher_id
order by name;

时间会变成:

  • mysql 5.1:0.01s
  • mysql 5.7:0.03s

所以,它好一点,但仍然慢。

course.teacher_id 有一个索引。

安装之间的一个区别是在5.7服务器中,数据文件夹在另一个驱动器上(SSD,性能比5.1服务器中的驱动器好一点)。

我应该配置什么以使 5.7 达到与 5.1 相同的速度有什么建议吗?可能一些查询也必须重写,但我认为配置似乎是必要的。

【问题讨论】:

  • MySQL 5.7 有一个更好的优化器和优化查询与 MySQL 5.1 不同...哦,放弃旧的逗号连接语法 from person, course 超过 25 年使用正确的 table1 JOIN table2 ON table1.column = table2.column 语法..
  • "运行时间:mysql 5.1:0.03s。后续查询:0.00s mysql 5.7:1.27s。后续查询:0.80s" 我感觉查询缓存在 MySQL 5.1 服务器上启动...此外,您无论如何都不应该使用查询缓存。查询缓存自 MySQL 5.7.20 起已弃用,并在 MySQL 8.0 中删除。
  • 多少内存?..
  • namelastname在哪个表?您希望ORDER BY 使用哪个name
  • 计时请使用SELECT SQL_NO_CACHE ...。这样可以避免 QC。

标签: mysql query-optimization


【解决方案1】:

您可以使用内部联接来使用更好的查询优化

  SELECT id, TRIM(CONCAT_WS(" ", name, lastname)) AS name
  FROM person
  INNER JOIN (
    SELECT DISTINCT teacher_id FROM course
  ) t on  t.teacher_id = person.id 

  ORDER BY name;

并确保您的测试是在相同的条件下进行的......相同的数据......并且两个查询的第一次执行

【讨论】:

  • 不,第二次执行,但关闭了 QC。第一个可能涉及启动 buffer_pool;第二个更好,因为它避免了这种情况。
  • 好的,这很酷,我得到 0.00 次查询。问题是,我有一个有数百个查询的系统(有些将 20 个表连接在一起)。我更喜欢(至少作为临时解决方案)以某种方式使用与 5.1 中相同的查询。
  • 正如@RaymondNijland 对您的问题的评论中一样,QC 已更改.. 如果您需要更好的性能,您应该评估最慢查询的重构..如我的回答.. 特别是在哪里您使用基于子查询的 IN 子句 .. 这些应该使用内部连接进行更改
  • 正如我所见,我可以更改查询,但我的问题是这些查询太多了。我最初的目标是让 5.7 的运行速度与 5.1 一样快(首先不更改查询)。
猜你喜欢
  • 2015-01-03
  • 2021-04-12
  • 1970-01-01
  • 2021-05-10
  • 1970-01-01
  • 1970-01-01
  • 2021-02-13
  • 1970-01-01
  • 2018-04-16
相关资源
最近更新 更多