簡體   English   中英

Mysql Select INNER JOIN with order by very slow

[英]Mysql Select INNER JOIN with order by very slow

我正在嘗試加快 mysql 查詢的速度。 Listings 表有幾百萬行。 如果我稍后不對它們進行排序,我會在 0.1 秒內得到結果,但一旦我排序它需要 7 秒。 我可以改進什么來加快查詢速度?

SELECT l.* 
FROM listings l 
INNER JOIN listings_categories lc 
ON l.id=lc.list_id 
AND lc.cat_id='2058' 
INNER JOIN locations loc 
ON l.location_id=loc.id 
WHERE l.location_id 
IN (7841,7842,7843,7844,7845,7846,7847,7848,7849,7850,7851,7852,7853,7854,7855,7856,7857,7858,7859,7860,7861,7862,7863,7864,7865,7866,7867,7868,7869,7870,7871,7872,7873,7874,7875,7876,7877,7878,7879,7880,7881,7882,7883,7884,7885,7886,7887,7888,7889,7890,7891,7892,7893,7894,7895,7896,7897,7898,7899,7900,7901,7902,7903) 
ORDER BY date 
DESC LIMIT 0,10;

EXPLAIN SELECT:使用索引 l=date,loc=primary,lc=primary

這樣的性能問題真的很難回答,取決於設置、索引等。因此,可能沒有唯一的解決方案,甚至沒有真正正確或不正確的提高速度的嘗試。 這是大量的嘗試和錯誤。 無論如何,我注意到一些經常導致性能問題的點是:

  • 避免連接中應該放在 where 中的條件。 連接應該只包含將要連接的列,沒有其他條件。 所以“lc.cat_id='2058”應該放在 where 子句中。
  • 使用 IN 通常很慢。 您可以嘗試使用 OR (l.location_id = 7841 OR location_id = 7842 OR...) 替換它
  • 打開查詢執行計划並檢查是否有對您有用的東西。
  • 嘗試找出受影響的列中是否有特殊情況/值會減慢您的查詢速度
  • 將“ORDER BY date”更改為“ORDER BY tablealias.date”並檢查這是否會對性能產生影響。 就算不會,讀書也好。
  • 如果您可以重命名列“日期”,請這樣做,因為使用 SQL 關鍵字作為表名或列名並不是一個好主意。 我不確定這是否會影響性能,但應盡可能避免。

祝你好運!

您可以嘗試使用附加索引來加快查詢速度,但在創建/操作數據時需要權衡取舍。

這些組合鍵可以加快查詢速度:

listings: date, location_id 
listings_categories: cat_id, list_id

由於計划說它使用日期索引,所以在使用新索引時不需要讀取記錄來檢查location_id,並且對於與listinngs_category的連接,讀取索引就足夠了

l:  INDEX(location_id, id)
lc:  INDEX(cat_id, list_id)

如果這些還不夠,請嘗試以下重寫。

SELECT  l2.*
    FROM  
    (
        SELECT  l1.id
            FROM  listings AS l1
            JOIN  listings_categories AS lc  ON lc.list_id = l1.id
            JOIN  locations AS loc  ON loc.id = l1.location_id
            WHERE  lc.cat_id='2058'
              AND  l1.location_id IN (7841, ..., 7903)
            ORDER BY  l1.date DESC
            LIMIT  0,10 
    ) AS x
    JOIN  listings l2  ON l1.id = x.id
    ORDER BY  l2.date DESC 

listings:  INDEX(location_id, date, id)
listings_categories:  INDEX(cat_id, list_id)

這里的想法是在到達表本身之前從索引中獲取 10 個 id。 您的版本可能在排序之前在整個表格周圍鏟過,然后交付 10。

暫無
暫無

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

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