2016-03-02 57 views
0

我是新來的SQL,並設法最終將查詢返回我正在查找的值!唯一的問題是,這運行真的很慢,大概是因爲存在的條款。我希望增加LIMIT會顯着加快速度,但不幸的是我發現經驗證明這不是事實。加速使用存在的SQL查詢

是否有另外一種方式來編寫這個查詢,它返回的是「可接受」速度的相同值?我意識到「可接受」是主觀的,但我只是在尋找新的方法。

下面是使用的表:

content 
--------------------------------------- 
id   | Int 
--------------------------------------- 

content_revision 
--------------------------------------- 
id   | Int 
content_id | ForeignKey (content) 
--------------------------------------- 

這裏是我的慢查詢:

SELECT outer_content.id AS "TEN_MOST_RECENT_CONTENTS_WITH_ONE_REVISION" 
    FROM content outer_content 
    JOIN content_revision ON outer_content.id = content_revision.content_id 
    WHERE EXISTS (
     SELECT inner_content.id 
      FROM content_revision 
      JOIN content inner_content ON content_revision.content_id = inner_content.id 
      WHERE outer_content.id = inner_content.id 
      GROUP BY inner_content.id HAVING count(*) = 1 
    ) 
ORDER BY ts_created DESC 
LIMIT 10; 

我感興趣的是尋找 「TEN_MOST_RECENT_CONTENTS_WITH_ONE_REVISION」

+0

生成執行計劃並查看最昂貴的操作(一個好的DBA可以幫助很大)。 'ts_created'上的索引可能會有所幫助。請注意,LIMIT對實際的查詢性能沒有幫助,因爲它可能需要掃描整個表以找到「前10位」結果。 –

+1

你就不能使用'選擇inner_content.id FROM content_revision JOIN內容inner_content ON content_revision.content_id = inner_content.id GROUP BY inner_content.id HAVING COUNT(*)= 1個 ORDER BY ts_created DESC LIMIT 10;' – artm

+0

@artm - 我希望能夠做到這樣的事情,不幸的是,這會導致錯誤......因爲我是通過''inner_content.id'''進行分組的,所以我不能通過ts_created進行ORDER BY,因爲有可能是由不同的ts_created組合在一起的多個列。由兩列分組將撤銷GROUP BY語句,因爲ts_created值基本上都是唯一的。 :( – wheresmycookie

回答

4

你真的需要內部的選擇?您可以使用:

SELECT inner_content.id, MAX(ts_created) 
      FROM content_revision 
      JOIN content inner_content ON content_revision.content_id = inner_content.id 
      GROUP BY inner_content.id HAVING count(*) = 1 
      ORDER BY MAX(ts_created) DESC 
      LIMIT 10; 

由於您使用的一組通過,如果你想通過ts_created訂購,您可以使用MAX(ts_created)。只有一條記錄,因爲HAVING

+0

這似乎是工作!讓我再玩幾分鐘,如果它正在做我期待的事情,我會贊成。謝謝! – wheresmycookie

+0

你需要在這裏檢查的東西是你的行的順序,'MAX(ts_created)'將總是計算到一個日期,它可能會與你期待的結果混淆。 –

+1

@JorgeCampos'MAX(ts_created)'將返回content_revision中每個結果的最大日期。所以它不會返回單個日期,而是每個內容的MAX日期,因此排序依然有效。 – artm

1

你並不需要完全可以使用WHERE EXISTS條件。所有你需要做的就是GROUP BY content.id, content.ts_created並添加HAVING count(content_revision.*) = 1,然後限制,訂單等..

-- get ten most recent contents with one revision 
SELECT content.id, content.ts_created 
FROM content 
JOIN content_revision ON content.id = content_revision.content_id 
GROUP BY content.id, content.ts_created 
HAVING count(content_revision.*) = 1 
ORDER BY content.ts_created DESC 
LIMIT 10; 
+1

這個答案是錯誤的,你將得到'column'content.ts_created「必須出現在GROUP BY子句中或在一個聚合函數中使用這不是MySql,你可以做這樣的事情 –

+0

@JorgeCampos你是對的我錯過了我修復了這個查詢 – AlexM

+0

這可能不會給你想要的結果,因爲它會分組通過ID和TS_CREATED他只想按ID分組 –