0

クエリは次のとおりです。

SELECT DISTINCT
    spentits.*,
    username,
    (SELECT count(*) from likes where likes.spentit_id = spentits.id) as like_count,
    (SELECT count(*) from comments where comments.spentit_id = spentits.id) as comment_count,
    (SELECT count(*) from wishlist_items where wishlist_items.spentit_id = spentits.id) as wishlist_count,
    (case when likes.id is null then 0 else 1 end) as is_liked_by_me,
    (case when wishlist_items.id is null then 0 else 1 end) as is_wishlisted_by_me
FROM spentits
LEFT JOIN users ON users.id = spentits.user_id
LEFT JOIN likes ON likes.user_id = 9 AND likes.spentit_id = spentits.id
LEFT JOIN wishlist_items ON wishlist_items.user_id = 9 AND wishlist_items.spentit_id = spentits.id
WHERE spentits.user_id IN
    (SELECT follows.following_id
     FROM follows
     WHERE follows.follower_id = 9)
ORDER BY id DESC 
LIMIT 15;

これは平均43msして実行に時間がかかります。ここで、where 句を持たない別のクエリ (以下) は言うまでもなく、2 番目の SELECT サブクエリの実行速度が 5 倍遅くなります ( 240ms)。

SELECT DISTINCT
    spentits.*,
    username,
    (SELECT count(*) from likes where likes.spentit_id = spentits.id) as like_count,
    (SELECT count(*) from comments where comments.spentit_id = spentits.id) as comment_count,
    (SELECT count(*) from wishlist_items where wishlist_items.spentit_id = spentits.id) as wishlist_count,
    (case when likes.id is null then 0 else 1 end) as is_liked_by_me,
    (case when wishlist_items.id is null then 0 else 1 end) as is_wishlisted_by_me
FROM spentits
LEFT JOIN users ON users.id = spentits.user_id
LEFT JOIN likes ON likes.user_id = 9 AND likes.spentit_id = spentits.id
LEFT JOIN wishlist_items ON wishlist_items.user_id = 9 AND wishlist_items.spentit_id = spentits.id
ORDER BY id DESC 
LIMIT 15;

なんで?条件がなく、2 番目のクエリがないため、2 番目のクエリははるかに高速ではありません。データベースが行う必要があるのは、最後の 15 レコードを選択し、サブクエリを実行した後にすべてのレコードをスキャンする必要がある最初のレコードと比較し、ID が含まれているかどうかを確認することだけです。はるかに高速に実行するはずのクエリが、実際には5倍遅く実行されていることに本当に混乱しています。

4

1 に答える 1

1

統計とメタデータに関連する実行パスがあり、explain plan両方を実行して実行パスを調べます。

さらに、ID によるフィルタリングは、一致する行を持たないテーブルでスキップを実行する可能性があります。その ID でフィルタリングしない場合、行は射影されます。

于 2013-06-04T15:43:04.343 に答える