mysql 5.7中的查询速度比5.1慢2倍或更多

mysql 5.7中的查询速度比5.1慢2倍或更多,mysql,query-optimization,Mysql,Query Optimization,我们将一个完整的数据库从MySQL 5.1.63迁移到另一个(稍微好一点的)服务器,并迁移到MySQL 5.7.22中。现在大多数查询的速度平均要慢两倍。我们没有对MySQL 5.1做太多优化 以下是我们已更改的配置: table_open_cache = 4096 tmp_table_size=256M max_heap_table_size=256M query_cache_limit = 1000000 query_cache_size =

我们将一个完整的数据库从MySQL 5.1.63迁移到另一个(稍微好一点的)服务器,并迁移到MySQL 5.7.22中。现在大多数查询的速度平均要慢两倍。我们没有对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.80
相差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 |
+----+--------------+-------------+------------+--------+--------------------+--------------------+---------+----------------------+--------+----------+-------------+
时代将变成:

  • mysql 5.1:0.01s
  • mysql 5.7:0.03s
所以,它稍微好一点,但还是慢一点

课程。教师id
有一个索引

安装之间的差异之一是,在5.7服务器中,数据文件夹位于另一个驱动器上(SSD,性能比5.1服务器中的驱动器稍好)


有什么建议我应该配置什么使5.7达到与5.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;

并确保在相同条件下进行测试。。同样的数据。。第一次执行这两个查询

MySQL 5.7的优化器和优化查询与MySQL 5.1不同。。。哦,从person,course中删除旧的逗号连接语法
,该语法已经超过25年了,请使用适当的
table1连接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中被删除。有多少RAM?。中的
name
lastname
是哪个表?要使用哪个<代码>名称
排序依据吗?计时时请使用
选择SQL\u NO\u缓存…
。这避免了QC。否,第二次执行,但QC已关闭。第一种可能涉及启动缓冲池;第二个更好,因为它避免了这种情况。好吧,这很酷,我用这个查询得到了0.00的时间。问题是,我有一个系统,它有数百个查询(其中一些连接了20个表)。我更愿意(至少作为临时解决方案)以某种方式使用与5.1相同的查询时间。正如@RaymondNijland对您的问题的评论中所述,QC发生了变化。。如果你需要更好的性能,你应该对最慢的查询进行重构,就像我的回答一样。。特别是在基于子查询的情况下使用IN子句。。应该使用内部连接来更改这些查询,因为我可以更改查询,我的问题是这些查询太多了。我最初的目标是让5.7与5.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;