在Join中优化子查询

时间:2015-07-30 15:59:00

标签: mysql query-optimization

我有以下查询:

SELECT *
FROM s
JOIN b ON s.borrowerId = b.id
JOIN (
    SELECT MIN(id) AS id
    FROM tbl
    WHERE dealId IS NULL
    GROUP BY borrowerId, created
) s2 ON s.id = s2.id

有没有一种简单的方法来优化它,以便我可以直接进行JOIN并利用索引?

更新

created字段是GROUP BY语句的一部分,因为由于我们的MySQL版本和使用的ORM的限制,可能有多个具有相同created的记录时间戳值。因此,我需要找到borrowerIdcreated的每个组合的第一条记录。

通常我会尝试这样的事情:

SELECT *
FROM s
INNER JOIN b ON s.borrowerId = b.id
LEFT OUTER JOIN s2
    ON s.borrowerId = s2.borrowerId
    AND s.created = s2.created
    AND s.id <> s2.id
    AND s.id < s2.id
WHERE s2.id IS NULL
AND s.dealId IS NULL;

但我不确定这是否能按我想要的方式运作。

来自MySQL的EXPLAIN输出以下内容:

1   PRIMARY b   ALL NULL    NULL    NULL    NULL    129690  
1   PRIMARY <derived2>  ALL NULL    NULL    NULL    NULL    317751  Using join buffer
1   PRIMARY s   eq_ref  PRIMARY,borrowerId_2,borrowerId PRIMARY 4   s2.id   1   Using where
2   DERIVED statuses    ref dealId  dealId  5       183987  Using where; Using temporary; Using filesort

正如您所看到的,它必须查询大量记录以构建子查询数据集,并且在连接到派生子查询时,未找到索引,因此不使用索引。

1 个答案:

答案 0 :(得分:0)

第一个查询需要这个复合索引:

INDEX(borrowerId, created, id)

请注意,MySQL很少为一个SELECT使用两个索引,但复合索引通常非常方便。

第二个查询似乎非常低效。

请为每张表提供SHOW CREATE TABLE

相关问题