[pymongo]ドキュメント数を取得(カウント)する最速の方法を検証。cursor.count()とcount_documents()ってどっちが早い?
はじめに
pymongoで検索結果のドキュメント数を知る方法に次の2通りのやり方がある。
- cursor型の
count()
で件数を取得する方法
ret = collection.find(filter={検索条件}).count()
- コレクションの
count_documents()
関数で取得する方法
ret = collection.count_documents(filter={検索条件})
どっちを使っても、条件に一致するドキュメント数が取得できます。
この記事では、上の2つの方法の内、どちらの方が高速に動くのかを検証してみます。
テストデータ
今回、実行時間の比較で使用するデータ(コレクション)は、次のような「ユーザID」「ユーザ名」と「点数」を持つ一般的な成績表データを使用します。なお、「点数」には1〜1000までのランダムな値を設定しておく。
id | name | score (ランダム値) |
---|---|---|
1 | ユーザ1 | 100 |
2 | ユーザ2 | 950 |
3 | ユーザ3 | 550 |
… | … | … |
Round1. 1000ドキュメント、filterなし(全件)
1回戦目は、簡単な条件で実行時間を測定してみたいと思います。以下の条件で実行時間を3回計測し、その平均値を比較しています。
- ドキュメント数: 1000
- 検索条件: なし
実行結果
この程度の件数であれは、どちらの関数を使用しても同じ時間で結果が返ってきます。
使用関数 | 実行時間 |
---|---|
corsor.count | 2.28ms |
collection.count_documents | 2.85ms |
Round2. 10万ドキュメント、filterなし(全件)
2回戦目は、ドキュメント数を一気に増やして10万件で実行時間を比較してみます。
- ドキュメント数: 10万
- 検索条件: なし
実行結果
corsor.count
の方が50倍近い速さで結果が返ってきています。この結果を見る限りだと、ドキュメント数の取得は、corsor.count
を使った方がよさそうですね。
使用関数 | 実行時間 |
---|---|
corsor.count | 2.00ms |
collection.count_documents | 55.34ms |
Round3. 10万ドキュメント、filterあり
次のは、検索条件を指定した時の実行時間を比較してみます。
- ドキュメント数: 10万
- 検索条件: 全体の「1%」のデータを抽出する検索条件を指定
※ この時の、検索条件を指定する列(score)のカーディナリティは**1%**です。
実行結果
今度は打って変わって、検索条件を指定した場合は、ほんの少しだけcount_documents()
が早くなりました。ただ、誤差の範囲なので実行時間は同じと見てよいでしょう。
使用関数 | 実行時間 |
---|---|
corsor.count | 71.48ms |
collection.count_documents | 64.50ms |
Round4. 100万ドキュメント、filter・skip・limitあり
ここまでの結論
ここまでの結果から、collection.find(filter={検索条件}).count()
でカウントを取得する方が、総合的に早いと言う見解が得られました。
ここでの結果は、あくまで私の環境での実行結果から推測される私的な見解であり、実際は違うかもしれません。そのときはごめんなさい。
単純にコレクションのドキュメント数を知りたい場合
検索条件なしで、 単純にコレクション内の、ドキュメント数を知りたい場合 は、estimated_document_count
を使うのが最速です。
pymongoのドキュメントにも、次のように書かれていす
.. note:: For a fast count of the total documents in a collection see
:meth:`estimated_document_count`.
実際に測定してみました。
- 10万ドキュメント
使用関数 | 実行時間 |
---|---|
corsor.count | 2.09ms |
collection.count_documents | 61.10ms |
collection.estimated_document_count | 2.09ms |
- 1000万ドキュメント
使用関数 | 実行時間 |
---|---|
corsor.count | 8.97ms |
collection.count_documents | 5174.81ms |
collection.estimated_document_count | 2.05ms |
上の結果の通り、estimated_document_count()
関数を使った、カウントが最も早いです。
制限事項として、estimated_document_count()
はセッションをサポートしていないので、セッションを指定したい時は使用できません。
0 件のコメント:
コメントを投稿