2013-12-10 48 views
5

我需要請改變這個SQL查詢不使用子查詢與IN,我需要這個查詢工作更快。改變和優化sql查詢

這裏是我正在處理的查詢。大約700萬行。

SELECT `MovieID`, COUNT(*) AS `Count` 
FROM `download` 
WHERE `UserID` IN (
SELECT `UserID` FROM `download` 
    WHERE `MovieID` = 995 
) 
GROUP BY `MovieID` 
ORDER BY `Count` DESC 

感謝

回答

7

像這樣的東西 - 但(在您切換到外部聯接的情況下),請確保您計算的是正確的事情...

SELECT MovieID 
     , COUNT(*) ttl 
    FROM download x 
    JOIN download y 
    ON y.userid = x.userid 
    AND y.movieid = 995 
    GROUP 
    BY x.MovieID 
    ORDER 
    BY ttl DESC; 
+2

我看過很多關於你的歷史的疑問,以及與OP相當的目標。只有缺點,也許未來,擴大到用戶,讓他們明白爲什麼事情以一定的方式工作將有助於他們和其他人,讓他們學習未來如何做,只是剪切/粘貼......只是建設性的批評,但同樣,你與職位的目標。 – DRapp

+0

是的,公平的評論。 – Strawberry

-2

過濾器上直接movieId..you並不需要添加子查詢。它可以通過在where子句中使用movieID = 995來完成。

SELECT `MovieID`, COUNT(*) AS `Count` 
FROM `download` 
WHERE `MovieID` = 995 
GROUP BY `MovieID` 
ORDER BY `Count` DESC 
+1

這不等同於原始查詢。他要求下載給定電影的任何用戶的所有電影。 – YXD

+0

爲什麼?這是正確的 –

+0

此查詢將只包含結果集中的單個MovieID(995)。這不是原始查詢中發生的情況。 – YXD

0

使用Exists相反,看到Optimizing Subqueries with EXISTS Strategy

考慮下面的子查詢比較:

outer_expr IN(SELECT inner_expr FROM ... WHERE subquery_where)的MySQL 評估查詢「從外到裏面「。也就是說,它首先獲得外部表達式outer_expr的值 ,然後運行 子查詢並捕獲它生成的行。

一個非常有用的優化是「通知」子查詢,唯一的 行的內部表達inner_expr是 等於outer_expr。這是通過向子查詢的WHERE子句中按下適當的 等式來完成的。即,比較 轉換成這樣:

EXISTS(SELECT 1 FROM ... WHERE subquery_where AND outer_expr = inner_expr)轉換後,MySQL能夠使用 下推平等來限制的行數在評估子查詢時必須檢查 。

+0

你可以解釋這個通過寫查詢。這對我來說還是很讓人困惑的 –