Home > Blockchain >  Confusion about sqlite query planner
Confusion about sqlite query planner

Time:09-17

I have a view which is wrote in SQLite which is V_Order_Calculator3. And also 1.5 million records inside the orders table.

imagine the code below:

select * from (
    SELECT 
        order_id
    FROM V_Order_Calculator3 
    WHERE /* CHOICE1 order_id = '00002092-03b4-4661-a9f4-afa73984860a'*/
    GROUP BY
    (CASE 
        WHEN order_type IN ('webshop_sell','sell','buy') THEN order_id
        WHEN order_type IN ('sell_return','buy_return')  THEN order_linked_id
        ELSE 0
    END)
) a /* CHOICE2 where a.order_id = '00002092-03b4-4661-a9f4-afa73984860a'*/

If I uncomment CHOICE1 then the the query takes 15 milliseconds to run. and if I uncomment CHOICE2 then it will be 18000 milliseconds.

It seems the sqlite query planner not calculating the CHOICE2 where clause before using the view.

I got confused and tried many ways but no luck.

CodePudding user response:

You think that the time should be the same because you assume that the queries have the same meaning and should give the same results, so sqlite should optimize the second query by pushing the WHERE down in the inner query, but your assumption is wrong.

The first one (inside WHERE) will filter the table for a single order_id, then will create groups based on the values of order_type, order_id and order_linked_id that it finds on the filtered rows. For every group it will return the order_id of an unspecified row of the group. Since you filtered for a specific order_id, it will always be the same value for every group.

The second one (outside WHERE) will scan all the table, creating groups based on the values of order_type, order_id and order_linked_id that it finds on all rows. For every group it will return the order_id of an unspecified row of the group, which at this point could be any value. The outside WHERE will then filter the result based on THESE values.

This is an example data where your two queries give different results: https://www.db-fiddle.com/f/xqiFACuv8PzU3VBnLbEoWF/2

It doesn't matter that in your application this set of data would not be possible or meaningful. Since the queries are not semantically equivalent, sqlite cannot transform the second one into the first.

  • Related