DB SQL

大量のデータを小分けに取得すると後半遅くなるので要注意|SQL

SQLで大量のデータを取得する際に、ページングが進められますが大体悪手です。

オプティマイザに従ってsqlが正しく動作する場合、プログラムよりコストが低いので、リソースが許す限りデータ量を大きく取った方がいいです。

「大量のデータ」と言っている想定件数が異なるせいでしょうが、私の場合大体200万件以上のデータを想定しています。

DBによりますが、このくらいの件数以上になるとDBの性能閾値を超える可能性があるため、極端に小分けで取得すると後半速度劣化を起こします。

検索後半で遅くなる原因はいくつか考えられるので、以下にいくつかの主要な原因を示します。

ページングの問題

ページングは大量のデータを小分けに取得する方法で、初めのページでは問題ない場合でも、後半のページでパフォーマンスが低下することがあります。

ページが進むにつれて、データベースエンジンは毎回新しいページのデータを計算し、前のページからのオフセットを処理する必要があります。

このため、後半のページで遅くなることがあります。

オフセットとリミット

ページングは通常、オフセットとリミットを使用して実装されます。

初めのページではオフセットがゼロで、一定のリミット(例: 100行または1000行)でデータを取得します。

しかし、後半のページではオフセットが増加していき、データベースはそのオフセットまでスキップしてデータを取得する必要があります。

このオフセットが増えるにつれて、クエリの実行時間が増加し速度が遅くなっていき、ある閾値以降から急減に減速し始めます。

インデックスの不足

ページングにおいて、後半のページは初めのページよりも多くのデータをスキップする必要があります。

データベースがスキップする行数が多い場合、インデックスが存在しない場合や適切でない場合、クエリの実行時間が増加します。

インデックスはオフセットを使ったクエリのパフォーマンス向上に役立ちますが、件数が多すぎる場合限界があります。

キャッシングの問題

データベースは一度に多くのデータを処理する必要があるため、キャッシングメカニズムが効果的でない場合、後半のページでデータベースからデータを取得する際にキャッシングミスが発生する可能性があります。

これにより、データベースからのデータのフェッチが遅くなります。

データベースエンジンの最適化

データベースエンジンは、初めのページのクエリと後半のページのクエリを異なる方法で最適化します。

オフセットとリミットによって後半のページでは、スキップする行数が多くなるため、クエリの最適化が難しく、遅くなる可能性があります。

リソースの枯渇

小分けにデータを取得する場合、実行速度の長さから、メモリやCPUなどのリソースが長時間上限値に貼り付いてしまい、後半のリクエストがリソース不足に陥ることで遅くなることがあります。

データベースやサーバーのリソースを適切にスケーリングすることが解決策の一つです。

最後に

これらの問題を解決するためには、データベース設計、クエリ最適化、リソース管理、ネットワークの最適化など、多くの側面を考慮する必要があります。

具体的な件数や状況に応じて、適切な対策を講じることが大切です。

データベースやアプリケーションのモニタリングを行い、問題を特定し最適な対策を選択することが重要です。

Zennで間違った内容とページングが進められていたので注意してください。

  • この記事を書いた人

朝倉卍丸

シングルモルトスコッチなどのお土産を持ってきた人を助けるのが好きです。サービスの分割が重要ですが、まあ昔ながらの方法でやりたいこともありますよね。

よく読まれている記事

条件の0=0は全てが正であるを意味するSQL 1

SQLの条件に0=0のような記述を見かけます。 変わった書き方の条件ですが、これは「全てが正である」事を意味しており、結合条件の場合はCROSS JOINと同じです。 下記の例で言えば、結合するsub ...

DISTINCTを使わないで重複排除を考えるSQL 2

SQLのDISTINCTはEXISTSとかGROUP BYでなんとかする事もできます。 DISTINCTは暗黙的なソートがされますが、何のDBを使うにせよ過去のバージョンならともかく、最近のバージョン ...

RFC 5322に準拠させた正規表現言語別 3

RFC5322で定義されている正規表現を、各言語の正規表現に変化させた形になります。 完全な電子メール正規表現は存在しないので、結局のところ何かの公式基準に従っていたとしても、自分が携わるサービスのル ...

-DB, SQL