首页 > 解决方案 > 内查询无结果时外查询很慢

问题描述

我正在尝试从名为export随机权重的表中获取一行。export_chunk然后它应该从引用第一行的另一个表中获取一行。这是查询:

SELECT * FROM export_chunk
WHERE export_id=(
    SELECT id FROM export 
    WHERE schedulable=1 
    ORDER BY -LOG(1 - RAND())/export.weight LIMIT 1)
AND status='PENDING' 
LIMIT 2;

export表可以有 1000 行,而 export_chunk 表可以有数百万行。

当内部查询返回一行时,查询速度非常快。但是,如果没有带有schedulable=1的行,外部查询将对 执行全表扫描export_chunk。为什么会发生这种情况,有什么方法可以防止它发生?

编辑:尝试 COALESCE()

Akina 在评论中建议使用 COALESCE,即:

SELECT * FROM export_chunk
WHERE export_id=COALESCE(
    SELECT id FROM export 
    WHERE schedulable=1 
    ORDER BY -LOG(1 - RAND())/export.weight LIMIT 1)
    ,-1)
AND status='PENDING' 
LIMIT 2;

这应该有效。当我运行时:

SELECT COALESCE((SELECT id FROM export WHERE schedulable=1 ORDER BY -LOG(1-RAND())/export.weight LIMIT 1), -1) FROM export;

它确实为 Akina 预测的每一行返回 -1。如果我手动搜索 -1 而不是内部查询,它不会很快返回任何行。但是,当我尝试在内部查询上使用 COALESCE 时,它仍然很慢。我不懂为什么。

标签: mysqlsqlquery-optimization

解决方案


测试这个:

SELECT export_chunk.* 
FROM export_chunk
JOIN ( SELECT id 
       FROM export 
       WHERE schedulable=1 
       ORDER BY -LOG(1 - RAND())/export.weight 
       LIMIT 1 ) AS random_row ON export_chunk.export_id=random_row.id
WHERE export_chunk.status='PENDING' 
LIMIT 2;

这是否符合所需的逻辑?特别是当子查询中没有匹配的行时 - 在这种情况下,您是否不需要输出行(如现在)或任何 2 行?

PS。外部查询中没有 ORDER BY 的 LIMIT 很奇怪。


推荐阅读