0

Consider there are 2M records in both shipment and order table.

SELECT DISTINCT
    s0_.id         AS id0,
    s0_.updated_at AS updated_at1
FROM
    `shipment` s0_
        LEFT JOIN `order` s1_ ON s0_.order_id = s1_.id -- These line
        LEFT JOIN `address` s2_ ON s1_.shipping_address_id = s2_.id -- These line
ORDER BY s0_.updated_at DESC
LIMIT 20 OFFSET 0

If I remove the left join MariaDB will use the index specified, why? Is there any solution?

This SQL is generated by a library and I have limited options to fix it.

This SQL is generated by a library and I have limited options to fix it.

This SQL is generated by a library and I have limited options to fix it.

This SQL is generated by a library and I have limited options to fix it.

This SQL is generated by a library and I have limited options to fix it.

Don't ask me to remove it. I know it has no use. And I think query optimizer need to think so too as it is just LEFT JOIN.

I am using MariaDB 10.1

5
  • 1
    EXPLAIN {query} and SHOW CREATE TABLE shipment and SHOW CREATE TABLE orders to see what indexes you have. Commented Dec 6, 2018 at 4:04
  • order by limit clauses have a few optimizations to go. Commented Dec 6, 2018 at 4:13
  • 1
    Report the LEFT JOINs as a bug in the Pagerfanta library :-) Take responsibility for the code you use. Commented Dec 6, 2018 at 6:54
  • You could fork the project and fix it. github.com/whiteoctober/Pagerfanta Commented Dec 6, 2018 at 7:03
  • I seriously want to delete this question Commented Dec 6, 2018 at 7:03

1 Answer 1

1

The left join needs to find the order_id of the shipment before it orders the output.

Forcing the index is usually the wrong thing to do, even if it can discover some things.

Use a compound index of shipment(order_id, updated_at) and you won't need to force an index.

ref: compound indexes query optimization

Sign up to request clarification or add additional context in comments.

5 Comments

I think you are correct, but it is also silly to see the optimizer process this query like this as it is just LEFT JOIN
Can you check the updated question? Your solution works if there is only one direct left join but not like the updated query
When I remove DISTINCT, then it is fast. s0_.id is primary key already. Do I need to add a unique constraint? Will it works?
a primary key is always unique, so yes, distinct isn't needed. EXPLAIN and SHOW CREATE TABLE info please. The additional join on addresses isn't used in the result set or any aspect of filtering.
This whole query is generated by Pagerfanta

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.