MySQL选择与分组不同出乎意料的缓慢

时间:2019-07-19 20:06:18

标签: mysql performance group-by distinct

我正在以以下形式运行查询:

SELECT DISTINCT
  a.col1,
  b.somecolumn
FROM a LEFT JOIN b ON a.bid = b.id
GROUP BY a.col1, a.col2

a有大约100,000条记录,而b有100条记录。这运行非常缓慢,大约一个小时或更长时间。但是,如果我稍稍更改一下,它将在几秒钟内运行:

SELECT DISTINCT * FROM (
  SELECT
    a.col1,
    b.somecolumn
  FROM a LEFT JOIN b ON a.bid = b.id
  GROUP BY a.col1, a.col2
) alias

查询在Docker容器内的专用MySQL实例上运行。资源是专用的,但数量有限(1个CPU,2-4gb RAM)。

两种查询形式的行为是否相同?

如果是这样,是什么使第二秒变得如此快?

哪些配置可能对此影响最大?为什么?

更新: 解释第一个查询的计划:

id    | select_type | table      | type | possible_keys | key | key_len | ref | rows       | extra
------------------------------------------------------------------------------------------------------------------------------------------------
1     | SIMPLE      | a          | ALL  |               |     |         |     | 100,000    | Using temporary; Using filesort
2     | SIMPLE      | b          | ALL  |               |     |         |     | 100        | Using where; Using join buffer (Block Nested Loop)

第二版说明计划:

id    | select_type | table      | type | possible_keys | key | key_len | ref | rows       | extra
------------------------------------------------------------------------------------------------------------------------------------------------
1     | PRIMARY     | <derived2> | ALL  |               |     |         |     | 10,000,000 | Using temporary
2     | DERIVED     | a          | ALL  |               |     |         |     | 100,000    | Using temporary; Using filesort
3     | DERIVED     | b          | ALL  |               |     |         |     | 100        | Using where; Using join buffer (Block Nested Loop)

更新2:没有索引;没有索引。但是,在a.bida.col1a.col2的任意组合上添加索引不会对解释产生实质性的变化(除了出现在possible_keys字段中)

更新3:启动服务器,将数据从外部系统加载到两个表中,执行所选查询,将数据导出到外部系统,然后关闭服务器。它使用以下配置选项(无cnf文件)启动:

--no-defaults
--datadir=./data
--socket=../mysql.sock
--skip-networking
--skip-slave-start
--master_info_repository=TABLE
--performance_schema=OFF
--skip-character-set-client-handshake
--transaction-isolation=READ-UNCOMMITTED
--group_concat_max_len=18446744073709551615
--default_storage_engine=InnoDB
--innodb_flush_log_at_trx_commit=2

我无法更改此批处理体系结构。每个作业都会创建/加载任意数量的表,并执行任意数量的查询,但是出于这个问题的目的,我将其隔离到这种小情况(2个表,1个查询)。

更新4(上下文):我的团队创建了一个平台,该平台可以执行用户提供的任意SQL。我不是SQL工程师,我的职责不是修复SQL。尽管我们可以间接建议人们更改SQL(即正确使用GROUP BY),但这不是问题所在。由于各种改进,我们正在迁移到新版本的平台,该平台可以更快地运行大多数批处理作业。一些工作的速度要慢100倍(例如本问题中的情况)。我希望了解这种差异。

TL; DR我无法更改SQL,我想了解行为。

0 个答案:

没有答案