約 170 万行、合計 1 GB のスプレッドシートがあり、さまざまなクエリを実行する必要があります。Python に最も慣れている私の最初のアプローチは、作成しようとしていたクエリを容易にする方法でキーを設定した一連の辞書をハックすることでした。たとえば、特定の市外局番と年齢を持つすべての人にアクセスできるようにする必要がある場合、areacode_age 2 次元辞書を作成します。最終的にかなりの数のこれらが必要になり、メモリ フットプリントが倍増しました (約 10GB のオーダーまで)。これをサポートするのに十分な RAM があったにもかかわらず、プロセスは依然として非常に低速でした。
この時点で、私はカモのゲームをしているように見えました。「まあ、これがリレーショナル データベースの目的ですよね?」と私は思いました。sqlite3 をインポートし、データをインメモリ データベースにインポートしました。データベースは速度を重視して構築されており、これで問題が解決すると思います。
ただし、「SELECT (a, b, c) FROM foo WHERE date1<=d AND date2>e AND name=f」のようなクエリを実行すると、0.05 秒かかることがわかります。170 万行でこれを行うと、24 時間の計算時間がかかります。辞書を使った私のハッキーなアプローチは、この特定のタスクで約 3 桁高速でした (そして、この例では明らかに date1 と date2 をキーにすることができなかったため、名前に一致するすべての行を取得し、日付でフィルタリングしていました)。
それで、私の質問は、なぜこれがそんなに遅いのか、どうすれば速くできるのかということです. Pythonic アプローチとは何ですか? 私が検討してきた可能性:
- sqlite3 は遅すぎるので、もっと重いものが必要です
- 何らかの方法でスキーマまたはクエリを変更して、より最適化する必要がありますか?
- これまでに試したアプローチは完全に間違っており、まったく新しいツールが必要です
- sqlite 3 で、cursor.execute を繰り返し呼び出すと、cursor.executemany を使用するよりもはるかに遅いことをどこかで読みました。ただし、executemany は select ステートメントとさえ互換性がないことが判明したため、これはニシンだったと思います。
ありがとう。