MySQL有关Group By的优化
? ? 昨天我寫(xiě)了有關(guān)MySQL的loose index scan的相關(guān)博文(http://www.cnblogs.com/wingsless/p/5037625.html),后來(lái)我發(fā)現(xiàn)上次提到的那個(gè)優(yōu)化方法中主要的目的就是實(shí)現(xiàn)loose index scan,而在執(zhí)行計(jì)劃的層面上看,Extra信息中應(yīng)該是“Using index for group-by”。這樣看來(lái),可能MySQL在處理distinct時(shí)和group by用了同樣的優(yōu)化手段,即走索引,進(jìn)行l(wèi)oose index scan。那么今天我研究了一下官方文檔,發(fā)現(xiàn)確實(shí)如此。
? ? 其實(shí)對(duì)于group by來(lái)講,最一般的實(shí)現(xiàn)方法就是進(jìn)行一次全表掃描,將所有的group by的行按照順序存放在一個(gè)temporary table中,然后在進(jìn)行分組識(shí)別或者進(jìn)行聚合操作。這樣問(wèn)題就是太復(fù)雜,時(shí)間上要好久,空間上的消耗也不小。這時(shí),MySQL可以利用索引來(lái)優(yōu)化group by。
? ? 這里就可以講講什么叫做loose index scan了,根據(jù)官方的定義,這種方法只需要掃描索引中的少部分?jǐn)?shù)據(jù),而不是所有滿(mǎn)足where條件的數(shù)據(jù),所以這個(gè)方法叫做loose index scan。
? ? 下面是什么情況下可以使用loose index scan的情況:
? ? 1 單一表查詢(xún)
? ? 2 Group by中只有最左前綴列,沒(méi)有其他列
? ? 3 只支持max和min聚合,而且,要聚合的列必須是group by中列所在的索引。
? ? 4 未被group by引用的索引其他部分必須是常量(這句我不是很理解)
? ? 5 不支持前綴索引。
? ? 假設(shè)t1(c1, c2, c3, c4)表有一個(gè)索引包括c1, c2, c3列,以下這些查詢(xún)都是可以進(jìn)行l(wèi)oose index scan的:
? ??
SELECT c1, c2 FROM t1 GROUP BY c1, c2; SELECT DISTINCT c1, c2 FROM t1; SELECT c1, MIN(c2) FROM t1 GROUP BY c1; SELECT c1, c2 FROM t1 WHERE c1 < const GROUP BY c1, c2; SELECT MAX(c3), MIN(c3), c1, c2 FROM t1 WHERE c2 > const GROUP BY c1, c2; SELECT c2 FROM t1 WHERE c1 < const GROUP BY c1, c2; SELECT c1, c2 FROM t1 WHERE c3 = const GROUP BY c1, c2;? ? 這些都是抄的官方文檔,正確性未完全驗(yàn)證。 ?
? ? 下面這些SQL都沒(méi)有辦法使用loose index scan:
? ??
-- 因?yàn)榫酆虾瘮?shù)不是max或者min SELECT c1, SUM(c2) FROM t1 GROUP BY c1;-- 因?yàn)椴环献钭笄熬Y原則 SELECT c1, c2 FROM t1 GROUP BY c2, c3;-- 查詢(xún)涉及到了索引的一部分,緊跟group by中的列,但是沒(méi)有常量等值語(yǔ)句,加上?WHERE c3 =?const就好了 SELECT c1, c3 FROM t1 GROUP BY c1, c2;? ? ?另外一些聚合函數(shù)也是可以用到loose index scan的,比如:AVG(DISTINCT), SUM(DISTINCT), 和COUNT(DISTINCT)
? ? ?以下這些語(yǔ)句也可以:
? ? ?
SELECT COUNT(DISTINCT c1), SUM(DISTINCT c1) FROM t1;SELECT COUNT(DISTINCT c1, c2), COUNT(DISTINCT c2, c1) FROM t1;? ? ? 很多語(yǔ)句都是從5.7的文檔上摘抄下來(lái)的,正確性沒(méi)有得到驗(yàn)證,雖說(shuō)官方文檔是權(quán)威,但是盡信書(shū)不如無(wú)書(shū),以及紙上得來(lái)終覺(jué)淺,絕知此事須躬行,明天周末,我逐條測(cè)試,然后再更。
?
總結(jié)
以上是生活随笔為你收集整理的MySQL有关Group By的优化的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 输入和学生成绩的输出
- 下一篇: Python总结:Python基础(一)