2011年4月19日 星期二

(mysql) 透過建 index 加速 group by

剛才遇到一個情況, 下 SQL 配合一些 where condition 過濾資料 (有 range query), 再 group by GROUP_COLUMN。資料量有些多, 但也沒多到會塞爆記憶體, 於是用 MEMORY engine, 全存在記憶體方便後續處理。

一開始試著對 where condition 用到的欄位建 index, 結果不夠快。看 profiling 的結果, 時間花在 "Copying to tmp table"。轉念一想, 若先建 index 排好 GROUP_COLUMN, 就能確保 mysql 只做一次 table scan, 別搬資料到 tmp table, 應該可以省下不少時間。於是對 GROUP_COLUMN 和 where condition 中用到的欄位建 covering index, 讓 GROUP_COLUMN 排第一個, 確保 mysql 不需用到 filesort 和 tmp table。

這個作法的特點在於, 不管 where condition 為何, 都是一次 table scan, 不用擔心不同輸入資料造成的變化, 可明確測出 worst case 的速度。實測結果, 果然快上不少, 到可以接受的速度。了解 mysql 運作方式後, 做這類設計並配合實測, 順手不少。

btw, 之前也遇過相反的情況, 不見得這樣做較好。招式是活的, 重點還是要看需求 (如是否看重 worst case, 以及 worst case 發生頻率, worst case 有無其它配套解法), 跑 profiling 實測, 再選適合的作法。

沒有留言:

張貼留言

在 Fedora 下裝 id-utils

Fedora 似乎因為執行檔撞名,而沒有提供 id-utils 的套件 ,但這是使用 gj 的必要套件,只好自己編。從官網抓好 tarball ,解開來編譯 (./configure && make)就是了。 但編譯後會遇到錯誤: ./stdio.h:10...