【问题标题】:Concurrent query execution is slow in MySQL 5.7MySQL 5.7 中的并发查询执行速度很慢
【发布时间】:2021-06-20 12:44:23
【问题描述】:

在 MySQL 5.7 中并发查询执行速度很慢。

当我只运行以下查询时,它需要 - 5.28 秒

select pkid,lastname
    from Table1
    where pkid in (select fkid from Table2)
    order by 2 desc limit 10; 

但如果我同时触发同一个查询 10 次,每个查询大约需要 11 秒。我不确定它为什么会发生,即使我的 innodb_thread_concurrency 是 10。

并发执行统计 - no_of_queries vs each_query_time:

1 time - 5.3sec
5 time - 7.8sec
10 times - 11sec

变量:

max_connections - 1500
innodb_thread_concurrency - 10

CPU - 16核

有人可以指导我在这里缺少什么。

注意:这不是查询优化。我的问题是并发查询执行速度很慢。只是为了显示单独执行单个查询与同时执行相同查询 10/5 项之间的区别,我使用了这个查询。

解释

{
  "query_block": {
    "select_id": 1,
    "cost_info": {
      "query_cost": "1541542.63"
    },
    "ordering_operation": {
      "using_temporary_table": true,
      "using_filesort": true,
      "cost_info": {
        "sort_cost": "1.00"
      },
      "nested_loop": [
        {
          "table": {
            "table_name": "Table2",
            "access_type": "index",
            "possible_keys": [
              "Table2_FK4_IDX"
            ],
            "key": "Table2_FK4_IDX",
            "used_key_parts": [
              "FKID"
            ],
            "key_length": "9",
            "rows_examined_per_scan": 1246072,
            "rows_produced_per_join": 732208,
            "filtered": "58.76",
            "using_index": true,
            "loosescan": true,
            "cost_info": {
              "read_cost": "2586.21",
              "eval_cost": "146441.71",
              "prefix_cost": "149027.92",
              "data_read_per_join": "2G"
            },
            "used_columns": [
              "TABLE2ID",
              "FKID"
            ],
            "attached_condition": "(`db1234`.`Table2`.`FKID` is not null)"
          }
        },
        {
          "table": {
            "table_name": "Table1",
            "access_type": "eq_ref",
            "possible_keys": [
              "PRIMARY"
            ],
            "key": "PRIMARY",
            "used_key_parts": [
              "PKID"
            ],
            "key_length": "8",
            "ref": [
              "db1234.Table2.FKID"
            ],
            "rows_examined_per_scan": 1,
            "rows_produced_per_join": 1,
            "filtered": "100.00",
            "cost_info": {
              "read_cost": "1246072.00",
              "eval_cost": "0.20",
              "prefix_cost": "1541541.63",
              "data_read_per_join": "19K"
            },
            "used_columns": [
              "PKID",
              "LASTNAME"
            ]
          }
        }
      ]
    }
  }
}

【问题讨论】:

  • 我认为改进您的查询(将 5.28 秒缩短到更少)是您解决方案的开始,但需要更多信息。能否分享一下table1和table2的DDL,以及table2的记录数,以及结果记录数的平均值?
  • 这完全正常:所有进程都必须共享相同的资源,而且它们是有限的,因此每增加一个进程,您就会大大减少资源,因此答案可以做出更好的查询,增加硬件资源
  • 当您请求查询优化帮助时,您应该为查询中的每个表包含SHOW CREATE TABLE <tablename> 的输出,这样我们就不必猜测您的列、索引或约束表。还包括EXPLAIN <query> 的输出是有帮助的。
  • 好的,您曾经在一台计算机上运行多个繁忙的应用程序吗?它们必须共享 CPU、RAM、磁盘 I/O 带宽。每个人都可以减慢另一个人的速度。如果您添加更多繁忙的应用程序,它们都会变慢。这是常见且可预测的。
  • 改善这一点的关键是让查询每次消耗更少的资源,从而使并发实例更少机会同时需要相同的资源,并且必须等待资源.而那就是查询优化!

标签: mysql sql database innodb


【解决方案1】:

查询正在竞争资源来做同样的事情。它们相互干扰。

也许如果您使用 exists 编写查询并拥有正确的索引,那么整个事情会更快:

select t1.pkid, t1.lastname
from Table1 t1
where exists (select 1 from table2 t2 where t2.fkid = t1.pkid)
order by 2 desc
limit 10; 

您肯定想要在table2(fkid) 上建立索引(尽管您可以通过 MySQL 中的foreign key 声明免费获得此索引)。可能比table1(lastname desc, pkid) 上的索引也有帮助。

【讨论】:

  • 感谢您的回复。这里 FKid 被索引。只是为了解释我接受了这个查询。 The queries are computing for resources to do the same thing你能详细解释一下吗/分享信息网址注册这个。因为我只是在这里阅读,我认为mysql不会获得排他锁。所以每个线程都可以并行读取吗?
  • @vinieth 。 . .我没有意识到“计算”和“竞争”有多接近。无论如何,MySQL 在优化in 子查询方面存在问题。我推荐带有索引的exists
  • 好的,你可以忽略 suqbuery。但是对于连接查询,同样的问题可重现select pkid,lastname from Table1 inner join Table2 on pkid = fkid order by 2 desc limit 10; 创建此查询只是为了显示单独执行单个查询与同时执行相同查询 10 个项目之间的示例。只有当两个表(连接/子查询)在一个查询中时,这个并行执行问题才可重现
  • 而且我检查了带有索引的退出该查询需要 42 秒,而使用松散扫描半连接的子查询更快。顺便说一句,这里的问题不是查询优化。并发执行速度较慢..
  • @vinieth 。 . .那是索引吗?
猜你喜欢
  • 2016-06-08
  • 1970-01-01
  • 1970-01-01
  • 2013-08-14
  • 1970-01-01
  • 2021-03-06
  • 1970-01-01
  • 2017-08-29
  • 1970-01-01
相关资源
最近更新 更多