2009-02-12 209 views
3

我還能做些什麼來優化此查詢?優化SQL查詢

SELECT * FROM 
    (SELECT `item`.itemID, COUNT(`votes`.itemID) AS `votes`, 
      `item`.title, `item`.itemTypeID, `item`. 
      submitDate, `item`.deleted, `item`.ItemCat, 
      `item`.counter, `item`.userID, `users`.name, 
      TIMESTAMPDIFF(minute,`submitDate`,NOW()) AS 'timeMin' , 
      `myItems`.userID as userIDFav, `myItems`.deleted as myDeleted 
     FROM (votes `votes` RIGHT OUTER JOIN item `item` 
        ON (`votes`.itemID = `item`.itemID)) 
      INNER JOIN 
       users `users` 
      ON (`users`.userID = `item`.userID) 
    LEFT OUTER JOIN 
       myItems `myItems` 
      ON (`myItems`.itemID = `item`.itemID) 
    WHERE (`item`.deleted = 0) 
    GROUP BY `item`.itemID, 
       `votes`.itemID, 
       `item`.title, 
       `item`.itemTypeID, 
       `item`.submitDate, 
       `item`.deleted, 
       `item`.ItemCat, 
       `item`.counter, 
       `item`.userID, 
       `users`.name, 
       `myItems`.deleted, 
       `myItems`.userID 
    ORDER BY `item`.itemID DESC) as myTable 
where myTable.userIDFav = 3 or myTable.userIDFav is null 
      limit 0, 20 

我使用MySQL

感謝

回答

5

當然,作爲@theomega說,看執行計劃。

但我也建議嘗試「清理」你的陳述。 (我不知道哪一個更快 - 這取決於你的表格大小。)通常,我會嘗試從一個乾淨的聲明開始,並從那裏開始優化。但通常情況下,乾淨的聲明使優化器可以更容易地制定出良好的執行計劃。

因此,這裏有你的語句可能會使事情慢一些意見:

  • 一對夫婦外的連接(使得它很難爲optimzer找出一個索引使用)的
  • 一組
  • 通過

據我理解你的SQL很多組列,這句話應該做的大部分東西你是做:

SELECT `item`.itemID, `item`.title, `item`.itemTypeID, `item`. 
     submitDate, `item`.deleted, `item`.ItemCat, 
     `item`.counter, `item`.userID, `users`.name, 
     TIMESTAMPDIFF(minute,`submitDate`,NOW()) AS 'timeMin' 
    FROM (item `item` INNER JOIN users `users` 
     ON (`users`.userID = `item`.userID) 

WHERE

當然,這丟了你外連接的表的信息,我建議你嘗試通過子選擇添加所需的列:

SELECT `item`.itemID, 
     (SELECT count (itemID) 
     FROM votes v 
     WHERE v.itemID = 'item'.itemID) as 'votes', <etc.> 

這樣,你可以通過刪除一個外部聯接和組。外部連接被替換後的替代,所以存在一個折衷,這對於「更乾淨」的語句可能是不利的。

根據item和myItems之間的基數,您可以做同樣的事情,或者您必須堅持外連接(但不需要重新引入分組)。

希望這會有所幫助。

9

什麼是分析此查詢說呢?不知道表中有多少行,你不能告訴任何優化。所以運行分析儀,你會看到哪些部件需要花費什麼。

1

一些快速的半隨機想法:

您的itemID和userID列索引?

如果將「EXPLAIN」添加到查詢的開頭並運行它會發生什麼?它使用索引嗎?他們是否合理?

你需要運行整個內部查詢和過濾器,或者你可以把where myTable.userIDFav = 3 or myTable.userIDFav is null部分移動到內部查詢中嗎?

0

你好似在Group By列表中有太多的字段,因爲其中一個是itemID,我懷疑你可以使用內部SELECT來執行分組,並使用外部SELECT來返回所需的字段集合。

0

不能添加where子句myTable.userIDFav = 3或myTable.userIDFav爲空WHERE(item .deleted = 0)

問候
利芬

0

看看你的查詢的構建方式。你加入了很多東西,然後將輸出限制爲20行。由於條件僅適用於這兩個表,因此您應該對項目和myitems有外連接,將輸出限制爲前20行,然後進行連接和聚合。在這裏,你正在執行許多將被丟棄的工作。