我正在以以下形式运行查询:
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.bid
,a.col1
和a.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,我想了解行为。