[英]Sub-query Optimization Talk with an example case
我需要建議,並希望分享我在查詢優化方面的經驗。 本周,我發現自己陷入了一個有趣的困境。 我是mySql的新手(理論為2年,實踐經驗不足)
環境 :
我有一個表,其中包含帶有“類型”列的文章,另一個表article_version包含在數據庫中添加文章的日期,還有一個表,其中包含所有文章類型以及類型標簽和填充物。
前兩張桌子非常大(800000多個字段,並且每天都在增長),第三張桌子自然很小。 article表中有很多列,但是我們只需要文章中的“ ID”和“ type”以及article_version中的“ dateAdded”就可以簡化事情。
我想做的事 :
對於指定的“ dateAdded”,該查詢返回每種類型的文章數(有約50種要掃描的類型)。 已經存在的是50個獨立的計數,每種文檔類型為oO(效率不高,很長(通常〜5秒))。
我想在一個查詢中完成所有操作,然后想到了:
SELECT type,
(SELECT COUNT(DISTINCT articles.ID)
FROM articles
INNER JOIN article_version
ON article_version.ARTI_ID = legi_arti.ID
WHERE type = td.NEW_ID
AND dateAdded = '2009-01-01 00:00:00') AS nbrArti
FROM type_document td
WHERE td.NEW_ID != ''
GROUP BY td.NEW_ID;
外部選擇(type_document)允許我獲取所需的55種文檔類型。 子查詢正在計算給定日期'2009-01-01'中每個type_document的文章。
常見的結果是:
* type * nbrArti * ************************* * 123456 * 23 * * 789456 * 5 * * 16578 * 98 * * .... * .... * * .... * .... * *************************
該查詢完成了工作,但是子查詢中的聯接使此過程非常緩慢,如果我是對的,原因是服務器為每種類型進行了聯接,因此該解決方案超過了50次比每種類型分別進行50個查詢要慢得多,真棒:/
一個解法
我自己想出了一個解決方案,可以以相同的結果極大地提高性能,我只是創建了一個與subQuery相對應的視圖,對每種類型的id進行了連接……而且Boom很快
我認為,如果我錯了,請糾正我,原因是服務器僅運行一次JOIN語句。
該解決方案比現有解決方案快約5倍,比我的第一次嘗試快約20倍。 甜
問題/想法
抱歉,我不是英語,這不是我的主要語言。
您不能在(type, date_added)
上創建單個索引,因為這些字段位於不同的表中。
如果沒有該視圖,則子查詢很可能會選擇article
作為主導表,並且選擇type
的索引不是很嚴格。
通過創建視圖,您可以強制子查詢首先計算所有類型的總和(使用date
上的選擇性索引),然后使用JOIN BUFFER
(僅對55
種類型足夠快)。
您可以通過如下重寫查詢來獲得類似的結果:
SELECT new_id, COALESCE(cnt, 0) AS cnt
FROM type_document td
LEFT JOIN
(
SELECT type, COUNT(DISTINCT article_id) AS cnt
FROM article_versions av
JOIN articles a
ON a.id = av.article_id
WHERE av.date = '2009-01-01 00:00:00'
GROUP BY
type
) q
ON q.type = td.new_id
不幸的是, MySQL
無法執行表假脫機或哈希聯接,因此要提高性能,您需要對表進行非規范化:將type
添加到article_version
並在(date, type)
上創建一個復合索引。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.