當(dāng)業(yè)務(wù)數(shù)據(jù)量較大時(shí)猿推,有時(shí)sql查詢會(huì)變慢秘症,影響數(shù)據(jù)的展示和用戶體驗(yàn)素挽,所以我們在編寫sql時(shí)要盡量考慮到數(shù)據(jù)量較大的場景蔑赘,以免影響后續(xù)的使用,但有的時(shí)候計(jì)劃趕不上變化预明,這個(gè)時(shí)候我們不得不進(jìn)行sql語句優(yōu)化
原始sql:
SELECT
b.store_id AS `storeId` ,
b.goods_id AS `goodsId` ,
b.goods_info_id AS `goodsInfoId` ,
b.sale_price AS `salePrice`
FROM
brand_store_goods b
LEFT JOIN goods g ON b.goods_id = g.goods_id
WHERE
b.del_flag = 0
AND g.del_flag = 0
AND g.audit_status = 1
AND(g.added_flag = 1 OR g.added_flag = 2)
AND b.supplier_added_flag = 1
GROUP BY b.store_id , b.goods_id
limit 0,10
explain分析sql
當(dāng)發(fā)現(xiàn)一條sql的查詢耗時(shí)較多時(shí)缩赛,首先我們要判斷sql語句的執(zhí)行效率,explain后發(fā)現(xiàn)都是全表掃描撰糠,還沒有索引酥馍。因?yàn)殡m然分頁,但使用了group by關(guān)鍵詞阅酪,mysql還是會(huì)進(jìn)行全表掃描
建立索引
首先我們在group by的字段上添加上索引旨袒,然而發(fā)現(xiàn)速度并沒有什么變化,這個(gè)時(shí)候我們看sql是先left join再group by的术辐,那是不是和sql的執(zhí)行順序有關(guān)呢
sql執(zhí)行順序
FROM
ON
JOIN
WHERE
GROUP BY
WITH CUBE or WITH ROLLUP
HAVING
SELECT
DISTINCT
ORDER BY
TOP
這里得知砚尽,Mysql 是先執(zhí)行關(guān)聯(lián)表然后再進(jìn)行條件查詢的最后再分組,那么想想這SQL的條件查詢和分組都只是一個(gè)表的,關(guān)聯(lián)后數(shù)據(jù)就變得多了辉词,這時(shí)候再進(jìn)行條件查詢和分組是不是有點(diǎn)沒必要必孤,我們可以嘗試一下提前進(jìn)行分組和條件查詢,實(shí)現(xiàn)方法就是子查詢聯(lián)合關(guān)聯(lián)查詢
SELECT
A.store_id ,
A.goods_id ,
A.sale_price
FROM
(
SELECT
store_id ,
goods_id ,
sale_price
FROM
brand_store_goods
WHERE
del_flag = 0
AND supplier_added_flag = 1
GROUP BY
store_id ,
goods_id
) A
LEFT JOIN goods g ON
A.goods_id = g.goods_id AND g.del_flag = 0
AND g.audit_status = 1
AND(g.added_flag = 1 OR g.added_flag = 2)
LIMIT 0,10
explain再來看下
看起來是優(yōu)化了不少较屿,但是其實(shí)數(shù)據(jù)量目前還沒有很大隧魄,是不是可以繼續(xù)從其他地方下手優(yōu)化呢卓练,比如left join,left join優(yōu)化比較重要的兩點(diǎn)是:1购啄、小表驅(qū)動(dòng)大表 2襟企、右表的條件列一定要加上索引(主鍵、唯一索引狮含、前綴索引等)顽悼,最好能夠使type達(dá)到range及以上(ref,eq_ref,const,system)
現(xiàn)在我們在原始sql的基礎(chǔ)上,對右表(brand_store_goods)條件列g(shù)oods_id上加上索引
看到這波分析心里踏實(shí)了一些几迄,看下耗時(shí)
這個(gè)速度基本比較滿意了蔚龙,不過像剛才說的,目前的數(shù)據(jù)量其實(shí)還沒有達(dá)到幾十萬甚至百萬級映胁,后續(xù)肯定還需要進(jìn)一步優(yōu)化木羹,不過我認(rèn)為其實(shí)一開始完全可以在數(shù)據(jù)庫表設(shè)計(jì)層面規(guī)避掉group by的使用,拆成兩張表去存儲解孙,不過這也是后話了