[Solved] View doesn\'t increase performance of correlated subquery?
Looking to automatically optimize YOUR SQL query? Start for free.

EverSQL Database Performance Knowledge Base

View doesn\'t increase performance of correlated subquery?

I have table User and table Order, now I want to find the names of user who made more than 100 orders, I can do a query like below:

SELECT U.name
FROM User U
WHERE 100 < (
SELECT COUNT(*) FROM Orders O
WHERE O.uid=U.uid
)

This is slow because of correlated subquery.

Therefore I think I can optimize it by creating a view which contains how many order each user has made like below

View UserOrderCount

uid    orderCount
0       11
1       108
2       100
3       99
4       32
5       67

Then the query is much simpler:

SELECT U.name
FROM User U, UserOrderCount C
WHERE 100 < C.orderCount And U.uid=C.cid;

But this turn out to take more time, I can't figure out why... Please shed some light on this, thanks in advance!

EDIT:

Here is how the view is created:

CREATE VIEW UserOrderCount
AS
select U.uid, count(*) AS orderCount
from User U, orders O
group by U.uid;

How to optimize this SQL query?

The following recommendations will help you in your SQL tuning process.
You'll find 3 sections below:

  1. Description of the steps you can take to speed up the query.
  2. The optimal indexes for this query, which you can copy and create in your database.
  3. An automatically re-written query you can copy and execute in your database.
The optimization process and recommendations:
  1. Avoid Correlated Subqueries (query line: 7): A correlated subquery is a subquery that contains a reference (column: uid) to a table that also appears in the outer query. Usually correlated queries can be rewritten with a join clause, which is the best practice. The database optimizer handles joins much better than correlated subqueries. Therefore, rephrasing the query with a join will allow the optimizer to use the most efficient execution plan for the query.
  2. Create Optimal Indexes (modified query below): The recommended indexes are an integral part of this optimization effort and should be created before testing the execution duration of the optimized query.
Optimal indexes for this query:
ALTER TABLE `Orders` ADD INDEX `orders_idx_uid` (`uid`);
The optimized query:
SELECT
        U.name 
    FROM
        User U 
    WHERE
        100 < (
            SELECT
                COUNT(*) 
            FROM
                Orders O 
            WHERE
                O.uid = U.uid
        )

Related Articles



* original question posted on StackOverflow here.