我有以下查询和计划:
SELECT data.*
FROM data
WHERE channel_id = 1
AND timestamp >= IFNULL((
SELECT UNIX_TIMESTAMP(DATE_ADD(FROM_UNIXTIME(MAX(timestamp) / 1000, "%Y-%m-%d"), INTERVAL 1 day)) * 1000
FROM aggregate
WHERE type = '3' AND aggregate.channel_id = data.channel_id
), 0)
AND timestamp < UNIX_TIMESTAMP(DATE_FORMAT(NOW(), "%Y-%m-%d")) * 1000
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
'1' 'PRIMARY' 'data' NULL 'ref' 'data_unique IDX_ADF3F36372F5A1AA' 'IDX_ADF3F36372F5A1AA' '5' 'const' '860512' '11.11' 'Using where'
'2' 'DEPENDENT SUBQUERY' 'aggregate' NULL 'ref' 'aggregate_unique IDX_B77949FF72F5A1AA' 'aggregate_unique' '7' 'volkszaehler.data.channel_id const' '1473' '100.00' 'Using index'
data
表有几百万行,所有表都被编入索引:
data: `channel_id`, `timestamp`
aggregate: `type`, `channel_id`, `timestamp`
当aggregate.channel_id = data.channel_id
替换为外部查询的channel_id
的实际值时,查询变得很快。并且从属子查询变成一个简单的子查询。
但是,我不想这样做以允许查询一次对&gt; 1个channel_ids进行操作。
为什么MySQL(5.7自制程序)不会认识到这个子查询确实不依赖(或者它是什么?)以及如何优化它?
我已经确认删除IFNULL
功能或将其向内推送并不能解决问题。我也没有按照Can i force mysql to perform subquery first?中的建议将子查询推下另一个级别,因为当时不再知道data.channel_id
引用。