一千萬個為什麽

搜索

使用左外連接的mysql過濾結果

我的查詢:

        SELECT content.*, activity_log.content_id FROM content
        LEFT JOIN activity_log 
        ON content.id = activity_log.content_id 
        AND sess_id = '$sess_id'
        WHERE activity_log.content_id IS NULL
        AND visibility = $visibility
        AND content.reported < ".REPORTED_LIMIT."
        AND content.file_ready = 1
        LIMIT 1

該查詢的目的是從內容表中獲取未被用戶查看的1行(由session_id標識),但它仍返回已查看的內容。哪裏不對? (我檢查了表格,確保content_ids在那裏)

註意:我認為這比使用子查詢更有效,想法?

最佳答案

問題顯然在你的JOIN條件下。當您對內部聯接結果感興趣時,您正在使用的優化(將條件應用於基表)是有意義的,但是在外部JOIN的情況下,這將被讀取如下:查找 content 之間的對應關系當內容標識匹配且會話標識匹配時, activity_log 行,並且當缺少內容標識的日誌或內容標識不丟失時,返回 activity_log 行的空值,但是會話ID不是指定的。它幾乎不是你想要的。

您的查詢應該如下所示:

SELECT content.*, activity_log.content_id
FROM (
SELECT *
FROM content
WHERE sess_id = '$sess_id'
    AND visibility = $visibility
    AND file_ready = 1
    AND reported < ".REPORTED_LIMIT."
) as content
LEFT JOIN activity_log 
ON content.id = activity_log.content_id 
WHERE activity_log.content_id IS NULL
LIMIT 1;

如果性能不是最佳,則可以考慮在(sess_id,visibility,fileready,reported)上創建復合索引。

轉載註明原文: 使用左外連接的mysql過濾結果