簡體   English   中英

使用LEFT JOIN CASE的查詢速度慢10倍

[英]Query 10 times slower using LEFT JOIN CASE in order by

我有一個比較長的查詢(在下面發布以供參考)。

我試圖調試為什么查詢如此緩慢(2秒),我終於找到了原因。

在查詢的最后,我做了:

  ORDER BY 
    -- order by date
    DATE(p.date) DESC, 
    -- order by followed people
    CASE WHEN n.id IS NULL THEN '0' ELSE '1' END DESC -- this case takes the query from 20ms to 2 seconds

如果我刪除CASE命令,它將在20毫秒左右執行。

為什么是這樣?

當我使用EXPLAIN運行查詢時,我注意到CASE將在“額外”字段中添加“使用臨時”。

請參閱下面的EXPLAIN查詢:

CASE WHEN n.id IS NULL THEN '0' ELSE '1' END DESCCASE WHEN n.id IS NULL THEN '0' ELSE '1' END DESC解釋查詢, CASE WHEN n.id IS NULL THEN '0' ELSE '1' END DESC按下列順序排序: CASE WHEN n.id IS NULL THEN '0' ELSE '1' END DESC

使用orderby中的CASE語句

CASE WHEN n.id IS NULL THEN '0' ELSE '1' END DESC ,按順序解釋查詢, 不使用 CASE WHEN n.id IS NULL THEN '0' ELSE '1' END DESC按以下順序排序: CASE WHEN n.id IS NULL THEN '0' ELSE '1' END DESC

在沒有CASE語句的情況下按

完整查詢(如果有幫助):

  SELECT 
    -- feed type
    '1' AS feed_type, 
    -- fetch post data
    p.id, 
    p.receiver, 
    p.date, 
    p.message, 
    p.system_msg, 
    p.type AS post_type, 
    -- fetch author data
    u.user_id, 
    u.firstname, 
    u.lastname, 
    u.type, 
    u.permalink, 
    av.file AS avatar_file, 
    -- fetch receiever data
    u2.user_id AS receiver_user_id, 
    u2.firstname AS receiver_firstname, 
    u2.lastname AS receiver_lastname, 
    u2.permalink AS receiver_permalink, 
    u2.type AS receiver_type, 
    -- fetch post comment count
    (
      SELECT 
        COUNT(*) 
      FROM 
        edu_posts pc 
      WHERE 
        pc.comment = p.id 
        AND pc.deleted IS NULL
    ) as commentCount, 
    -- fetch post like count
    (
      SELECT 
        COUNT(*) 
      FROM 
        edu_likes l 
      WHERE 
        l.like_entity = p.id
    ) as likeCount, 
    -- user follow state
    CASE WHEN n.id IS NOT NULL THEN '1' ELSE '0' END as is_following, 
    -- check if user likes post
    CASE WHEN l.like_id IS NOT NULL THEN '1' ELSE '0' END as user_likes 
  FROM 
    edu_posts p
    INNER JOIN -- author information
    edu_users u ON u.user_id = p.author 
    LEFT JOIN -- author avatar
    edu_avatars av ON av.fk = p.author 
    AND av.temp = 0 
    AND av.fk_type = 1 
    LEFT JOIN -- receiver information (if any)
    edu_users u2 ON u2.user_id = p.receiver 
    LEFT JOIN -- check if author/receiver is followed by current user
    edu_notification_list n ON n.user = 1 
    AND n.following = 1 
    AND (
      n.fk = p.author 
      OR n.fk = p.receiver
    ) 
    AND (
      (
        n.type = 5 
        AND p.type = 3
      ) 
      OR (
        n.type = 2 
        AND p.type = 1
      )
    ) 
    LEFT JOIN -- check if user likes the post
    edu_likes l ON l.like_entity = p.id 
    AND l.like_author = 1 
  WHERE
    p.deleted IS NULL 
    AND p.comment IS NULL 
    AND (
      p.id = p.comment 
      OR 1 = 1
    ) 
    AND (
      n.id IS NOT NULL 
      OR p.system_msg = 0
    ) 
  ORDER BY 
    -- order by date
    DATE(p.date) DESC, 
    -- order by followed people
    CASE WHEN n.id IS NULL THEN '0' ELSE '1' END DESC 
  LIMIT 
    20 OFFSET 0

注意:如果您要查看其他表格,請告訴我。

您執行的操作無法使用索引。 試一試

ORDER BY DATE(p.date) DESC, 
         n.id IS NULL ASC

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM