A certain engineer "COMPLEX"

.NETでNoSQLを試してみる MongoDB編 第7回

前回はデータの読み込みのパフォーマンス測定を実施しました。今回はインデックスの作成を行い、読み込み性能の改善を行いたいと思います。

Introduction


前回は、結果も課程も散々でした。

環境は前回と同じです。

Explanation


インデックスの設定

Indexes with C# Driverによれば、

Indexes can support the efficient execution of queries. MongoDB automatically creates an index on the _id field upon the creation of a collection.


訳:
インデックスは効率的なクエリの実行をサポートすることができます。MongoDBは自動的に _id フィールド上にコレクション作成時にインデックスを作成します。

と言っています。
既にインデックスが張られているといっています。
といっても、_idフィールドなので、これまでの検索には影響しないと思います。

追加で設定する場合は、

var keys = Builders.IndexKeys.Ascending().Ascending();
await collection.Indexes.CreateOneAsync(keys);

と、するようです。

というわけで、前回の3種のオブジェクトの No プロパティ に昇順のインデックスを設定してみます。
こんな感じです。


private static void SetSmallIndex(MongoClient mongoClient)
{
Console.WriteLine("SetSmallIndex");

var database = mongoClient.GetDatabase(DatabaseName);
var collection = database.GetCollection<SmallObjectData>(CollectionName);

var keys = Builders<SmallObjectData>.IndexKeys.Ascending("No");
collection.Indexes.CreateOne(keys);
}

インデックスの設定後

割と時間がかかりました。1,000,000件も登録されていればそうでしょう。

Index

mongo-expressで確認すると、Indexes # が 2 になっています。

そして、前回と同じように、検索を実行します。検索結果の個数は10になります。
その結果が下記になります。

オブジェクトサイズ/オブジェクト数1,000,0001,000,000 (インデックス適用後)
Small (51.0 bytes)420.8 ms610.8 ms
Middle (80.1 kb)221577.1 ms586 ms
Large (100 kb)計測不可588 ms

劇的に改善しました。370倍です。Largeに至っては計測できるようにさえなりました。
Smallが悪化してますが、誤差でしょう。多分。
実行後、mongod.exe のメモリ量は大きく増えていません。

検索結果の個数は影響するか?

前回、メモリ確保が原因なのか、途中で例外を投げて落ちました。
今回は、検索結果の個数が1,000,000から10になるようにしてあります。

では、これを変化させたら、検索速度はどう変化するでしょうか?
1,000,000件のデータを対象に、検索結果の個数が増えていった場合のパフォーマンスを下記に記載します。

オブジェクトサイズ/検索結果数101001,00010,000100,000
Small (51.0 bytes)610.8 ms515.6 ms558.5 ms582.8 ms956.2 ms
Middle (80.1 kb)586 ms512 ms1571.4 ms7171.2 ms計測不可
Large (100 kb)588 ms494.7 ms1870.2 ms11292.6 ms計測不可

増えていくごとに悪化していく傾向です。
ただし、劇的に悪化しているのは、初回のクエリだけ100秒とかで、それ以降はキャッシュが聞いています。それでも、後半は 2,000 ms とかかかっていますが。
それでも、インデックスを設定する前と比べたら、劇的すぎる改善です。

Conclusion


バイナリファイルを扱う際は、必ずインデックスを設定し、検索のパフォーマンスを向上させるのと、検索途中の結果でOutOfMemoryExceptionを発生させないようにする必要があります。
必要なら複数のインデックスを設定して、結果が少なくなるようするべきです。

Source Code


テストに使った最終的なコードは下記になります。

https://github.com/takuya-takeuchi/Demo/tree/master/MongoDB7

コメントを残す

メールアドレスが公開されることはありません。

%d人のブロガーが「いいね」をつけました。