今天優化了一個查詢語句,覺得蠻可以的,拿出來跟大家分享一下,為方便起見,用了三個表作為示例說明。分別有:
tbl_commpany主要是記錄廠商的信息,包括該廠商的狀態。
tbl_product主要是記錄產品的信息,包括產品的狀態,與廠商信息表關聯。
tbl_company_top主要記錄廠商瀏覽訪問的排行榜信息(按年)。
tbl_company(name, status)
tbl_product(name, company_id,status)
tbl_company_top(company_id,rank,count,year)
現在要查詢顯示:
查詢按排行榜排序的前100個廠商列表,顯示廠商名以及廠商下有多少產品數。
三星(1560) HTC(581) ……
思路是用 tbl_company_top(廠商排名表)與 b臨時表(每個廠商對應的產品數表) 與 tbl_company表(需要根據廠商的狀態進行過濾)三表關聯:
SELECT
c.name, b.product_count
FROM
(SELECT * FROM tbl_company_top WHERE year = 2011) a,
(SELECT company_id, COUNT(*) AS product_count FROM tbl_product WHERE status = 1 GROUP BY company_id) b,
tbl_company c
WHERE
a.company_id = c.id
AND b.company_id = c.id
AND c.status = 1
ORDER BY a.rank,a.count DESC LIMIT 50;
查詢了一下。速度非常慢。
以下是EXPLAIN的信息:
按照少關聯,多篩選,盡可能減少最大條數再進行關聯的原則。原本打算在子查詢中直接LIMIT掉50條數據。不幸的是:This version of MySQL doesn’t yet support ‘LIMIT & IN/ALL/ANY/SOME subquery
SELECT
b.copmany_id, COUNT(b.id), a.cnt
FROM
(SELECT copmany_id, MAX(COUNT) AS cnt FROM tbl_company_top a WHERE year = 2011 GROUP BY copmany_id) a,
tbl_product b,
tbl_copmany c
WHERE
b.company_id = a.company_id
AND c.id = a.company_id
AND b.status = 1
AND c.status = 9
GROUP BY b.company_id, a.cnt
ORDER BY a.cnt DESC LIMIT 50;
EXPLAIN的信息如下:
此時,查詢語句可以達到接受級別(當然視乎數據的級別)

另外,給必要的查詢字段加上索引,也有不錯的效果。