简体   繁体   中英

Optimize Subquery in Join

I have the following query:

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

Is there a simple way to optimize this so that I can do the JOIN directly and utilize indexes?

UPDATE

The created field is part of the GROUP BY statement because due to the limitations of our version of MySQL and the ORM being used it is possible to have multiple records with the same created timestamp value. As a result I need to find the first record for each combination of borrowerId and created .

Typically I might attempt something like this:

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;

But I'm not sure if that works 100% the way I want.

EXPLAIN from MySQL outputs the following:

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

As you can see, it has to query a massive number of records to build the subquery data set and when joining to the derived subquery, no indexes are found and so no indexes are used.

The first query needs this composite index:

INDEX(borrowerId, created, id)

Note that MySQL rarely uses two indexes for one SELECT , but a composite index is often very handy.

The second query seems grossly inefficient.

Please provide SHOW CREATE TABLE for each table.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM