1

いくつかの CouchDB データベースがあります。最大のものは約 60 万ドキュメントで、クエリが法外に長い (数時間以上) ことがわかりました。DB の更新頻度は低く (1 か月に 1 回程度)、新しいドキュメントを追加するだけで、既存のドキュメントを更新することはありません。

クエリのタイプは次のとおりです: Find all documents where key1='a'or multiple keys: key1='a', key2='b'...

ここでは永続的なビューが実用的であるとは思わないので、CouchDB-Python の「クエリ」メソッドを使用しています。

いくつかのアプローチを試しましたが、何が最も効率的か、またはその理由がわかりません。

方法 1: map 関数は次のとおりです。

    map_fun = '''function(doc){
        if(doc.key1=='a'){
            emit(doc.A, [doc.B, doc.C,doc.D,doc.E]);
        }
    }'''

Python クエリは次のとおりです。 results = ui.db.query(map_fun, key2=user)

次に、results.rows を使用した操作。これが一番時間がかかります。

「results.rows」が戻ってくるまでに約 1 時間かかります。key2 を別のものに変更すると、約 5 秒で元に戻ります。元のユーザーを繰り返すと、それも高速です。

ただし、より多くのキーを照会する必要がある場合があるため、次のことを試します。

    map_fun = '''function(doc){
        if(doc.key1=='a' && doc.key2=user && doc.key3='something else' && etc.){
            emit(doc.A, [doc.B, doc.C,doc.D,doc.E]);
        }
    }'''

Pythonクエリを使用します:

results = ui.db.query(map_fun) 次に、results.rows を使用した操作

最初のクエリに時間がかかります。key2 を変更すると、また時間がかかります。key2 を元のデータに戻すと、同じ時間がかかります。(つまり、何もキャッシュされたり、B ツリー化されたりしていないようです)。

私の質問は次のとおりです。クエリがアドホックで、検索条件に複数のキーが含まれる場合、couchdb-python でクエリを実行する最も効率的な方法は何ですか?

UI は QT ベースで、その下に PyQt を使用しています。

4

2 に答える 2

3

couchdb-python db.query()メソッドには2つの注意点があります。

  1. 一時ビューを実行します。これは、このすべてのドキュメントがこのビューによって処理されるまで、コードフロー処理がブロックされることを意味します。そして、これは呼び出しごとに何度も何度も起こりました。ビューを保存し、代わりにdb.view()メソッドを使用して、オンデマンドで結果を取得し、インデックスを段階的に更新してください。

  2. どんなに大きくても結果全体を読み取ります。db.query()メソッドもdb.view()メソッドも遅延しないため、ビューの結果が100 MBのJSONオブジェクトである場合は、何らかの方法で使用する前に、このすべてのデータをフェッチする必要があります。よりメモリを最適化した方法でデータをクエリするには、パッチを適用してdb.iterview()メソッドを使用してみてください。これにより、ページネーションスタイルでデータをフェッチできます。

于 2012-08-22T20:22:58.633 に答える
1

問題の解決策は、検索しているキーのインデックスを作成することだと思います。それはあなたが永久ビューと呼んだものです。

B ツリー ベースのテーブルでの map/reduce クエリと SQL クエリの違いに注意してください。

  • キーを検索する単純な SQL クエリ (インデックスがある場合) は、ルートからリーフまで B+ ツリー内の単一のパスをトラバースし、
  • map 関数は、小さな結果を出力する場合、すべての要素、イベントを読み取ります。

あなたがしていることは、クエリごとです

  1. すべてのドキュメントを読む(ほとんどのコスト) および
  2. 出力された結果でキーを検索します (B ツリーでのクイック検索)。

設計上、ソリューションは遅くなければならないと思います。

パーマネント ビューを実用的にするためにデータベース構造を再設計すると、(1.) は 1 回実行され、クエリごとに (2.) のみが実行されます。各ドキュメントは、DB に追加された後にビューによって読み取られ、クエリは発行された結果を格納する B ツリーで検索されます。発行されたセットが合計ドキュメント数よりも小さい場合、クエリはより小さな構造を検索し、SQL データベースよりも利点があります。

一時的なビューは、永続的なビューよりもはるかに効率が悪く、開発のみに使用されることを意図しています。CouchDB は、永続的なビューで動作するように設計されています。map/reduce を効率的にするには、キャッシュを実装するか、ビューを永続的にする必要があります。私は CouchDB 実装の詳細に精通していません。おそらく、別のキーを使用した 2 番目のクエリは、キャッシングのために高速です。何らかの理由で一時ビューを使用する必要がある場合、おそらく CouchDB は間違いであり、MongoDB などのオンライン クエリ用に作成および最適化された DBMS を検討する必要があります。

于 2012-08-24T08:25:10.640 に答える