sql >> データベース >  >> RDS >> PostgreSQL

LIMITが適用される前に結果カウントを取得するための最良の方法

    純粋なSQL

    2008年以降、状況が変わりました。ウィンドウ関数を使用して、フルカウントを取得できますおよび 1つのクエリで限られた結果。 2009年にPostgreSQL8.4で導入されました。

    SELECT foo
         , count(*) OVER() AS full_count
    FROM   bar
    WHERE  <some condition>
    ORDER  BY <some col>
    LIMIT  <pagesize>
    OFFSET <offset>;

    これは合計数がない場合よりもかなり高くなる可能性があることに注意してください 。すべての行をカウントする必要があり、一致するインデックスから一番上の行だけを取得する可能性のあるショートカットは、もはや役に立たない場合があります。
    小さなテーブルや full_countではそれほど重要ではありません。 <=オフセット + LIMIT 。大幅に大きいfull_countの問題 。

    コーナーケース OFFSETの場合 少なくとも基本クエリの行数と同じです。行なし が返されます。したがって、 full_countも取得されません 。考えられる代替案:

    • LIMIT / OFFSETを使用してクエリを実行し、行の総数も取得します

    SELECTのイベントのシーケンス クエリ

    (0. CTEは個別に評価され、具体化されます。Postgres12以降では、プランナーは作業に行く前にサブクエリなどをインライン化する場合があります。)ここではありません。

    1. 場所 句(および JOIN 条件(ただし、この例ではありません)は、ベーステーブルから修飾行をフィルタリングします。 残りはフィルタリングされたサブセットに基づいています。

    (2. GROUP BY 集計関数はここにあります。)ここではありません。

    (3.その他の SELECT リスト式は、グループ化/集約された列に基づいて評価されます。)ここではありません。

    1. OVERに応じてウィンドウ関数が適用されます 節と関数のフレーム仕様。単純なcount(*)OVER() 対象となるすべての行に基づいています。

    2. ORDER BY

    (6. DISTINCT またはDISTINCTON ここに行きます。)ここではありません。

    1. LIMIT /オフセット 確立された順序に基づいて適用され、返される行が選択されます。

    LIMIT /オフセット テーブル内の行数が増えると、非効率になります。より良いパフォーマンスが必要な場合は、別のアプローチを検討してください。

    • 大きなテーブルでOFFSETを使用してクエリを最適化する

    最終カウントを取得するための代替案

    影響を受ける行の数を取得するには、まったく異なるアプローチがあります(ない OFFSETの前のフルカウント & LIMIT 適用されました)。 Postgresには、最後のSQLコマンドの影響を受ける行数を内部で記録しています。一部のクライアントは、その情報にアクセスしたり、行自体をカウントしたりできます(psqlなど)。

    たとえば、影響を受ける行の数を plpgsqlで取得できます。 次のコマンドを使用してSQLコマンドを実行した直後:

    GET DIAGNOSTICS integer_var = ROW_COUNT;
    

    マニュアルの詳細。

    または、 pg_num_rowsを使用できます PHP 。または他のクライアントの同様の機能。

    関連:

    • PostgreSQLでバッチクエリの影響を受ける行数を計算する


    1. WindowsでMySQLのルートパスワードをリセットする

    2. MySQLのテーブル名では大文字と小文字が区別されますか?

    3. phpMyAdminをインストールする方法

    4. 初心者向けのSQLGROUPBY句