🌟
FirestoreのCOUNT()のパフォーマンスを計測してみた
Firebase Summitでもいろいろ発表されていますね!
COUNTはコレクション数に応じて遅くなるのか
巨大なコレクションに対してのクエリがどの程度スピードが変わるのかを簡単に検証してみました
検証に使ったコードはこちら
const measurement = async <T>(f: () => Promise<T>, tag: string) => {
const r: number[] = [];
for await (const _ of [...new Array(200).keys()]) {
const m = await withMetric(f, { showLog: false });
r.push(m.elapse);
}
const min = r.reduce((a, b) => Math.min(a, b));
const max = r.reduce((a, b) => Math.max(a, b));
const average = r.reduce((prev, curr) => prev + curr) / r.length;
console.log(`[${tag}] min: ${min} max: ${max} average: ${average}`);
};
const withMetric = async <T>(
f: () => Promise<T>,
option: {
showLog: boolean;
} = { showLog: true }
) => {
const startTime = performance.now(); // 開始時間
const r = await f();
const endTime = performance.now(); // 終了時間
const elapse = endTime - startTime;
option.showLog && console.log(`millis: ${elapse} `);
return {
result: r,
elapse,
};
};
測定結果
- 別のコレクションに対してテストデータを作成し、全件を取得するクエリを発行する
- 同じクエリを200回ずつ発行して、最小値、最大値、平均値を出力
測定は全て東京リージョンで行っています。単位はms
さすがにコレクションサイズが大きいとクエリのパフォーマンスも影響がありそうですね。
1万件に対して全件カウントした場合、Whereをつけた場合でも大きな差はなさそうです。
ドキュメントカウント | 最小値(ms) | 最大値(ms) | 平均値(ms) |
---|---|---|---|
200件 | 16.13766622543335 | 383.27662467956543 | 48.986748945713046 |
1000件 | 21.502166748046875 | 145.2618751525879 | 32.469205820560454 |
10000件 | 52.992416858673096 | 178.3753752708435 | 74.26382768392563 |
50000件 | 141.8333339691162 | 485.1029577255249 | 228.72841580867768 |
100000件 | 267.9079155921936 | 1257.633542060852 | 426.1588483285904 |
10000件から3333件取得 | 27.292333126068115 | 157.46166706085205 | 37.517049396038054 |
50000件から16667件取得 | 53.39187526702881 | 348.72037506103516 | 75.77325768470764 |
コストに関して
前回記事では1Readしかかからなさそうと書いていたのですが、Firebase summitでは「1000件に対して1Read」と発表されていました。
ですので、100万件にカウントする場合は1000Read発生する計算になりそうです。
公式ドキュメントはこちら
Discussion