LIMIT適用前の結果カウントを取得する最良の方法
質問
DBから送られてくるデータをページングする場合、ページジャンプコントロールをレンダリングするために何ページあるのかを知る必要があります。
現在、私はクエリを2回実行し、1回は
count()
でラップして全体の結果を決定し、2回目は制限を適用して現在のページに必要な結果だけを取得します。
これは非効率的に思えます。の前に返されたであろう結果の数を決定する、より良い方法はないでしょうか?
LIMIT
が適用される前に返されたであろう結果の数を決定する良い方法はありますか?
PHPとPostgresを使用しています。
どのように解決するのですか?
純粋なSQL
2008年から変わりました。あなたは ウィンドウ機能 を使用して、完全なカウントを取得することができます。 と を取得することができます。で導入された 2009年のPostgreSQL 8.4で導入されました。 .
SELECT foo
, count(*) OVER() AS full_count
FROM bar
WHERE <some condition>
ORDER BY <some col>
LIMIT <pagesize>
OFFSET <offset>;
なお、この
は、総数を指定しない場合よりもかなり高価になる可能性があります。
. 全ての行を数える必要があり、一致するインデックスから上位の行だけを取るというショートカットが可能ですが、これはもう役に立ちません。
小さなテーブルや
full_count
とか。
OFFSET
+
LIMIT
. 実質的に大きな
full_count
.
コーナーケース
: 次のような場合
OFFSET
が少なくともベースクエリからの行の数と同じであるとき。
行なし
が返されます。そのため
full_count
. 可能な代替案
のイベントのシーケンス
SELECT
クエリ
( 0. CTEは別々に評価され、マテリアライズされます。Postgres 12以降では、プランナは作業に入る前にそれらをサブクエリのようにインライン化することができます)。ここではありません。
-
WHERE
節(およびJOIN
条件、ただしあなたの例ではなし) は、ベース・テーブルから修飾された行をフィルタリングします。 残りはフィルタリングされたサブセットに基づいています。
( 2.
GROUP BY
と集計関数がここに入るでしょう) ここはダメです。
( 3.その他
SELECT
リスト式は、グループ化/集約されたカラムに基づいて、評価されます)。ここではありません。
-
に応じてウィンドウの機能が適用されます。
OVER
節と関数のフレーム指定によって適用されます。単純なcount(*) OVER()
は、すべての修飾された行に基づいています。 -
ORDER BY
( 6.
DISTINCT
または
DISTINCT ON
はここに入るだろう) ここはダメです。
-
LIMIT
/OFFSET
は、返すべき行を選択するために確立された順序に基づいて適用されます。
LIMIT
OFFSET
は、テーブルの行数が増えるにつれてますます非効率的になります。より良いパフォーマンスが必要な場合は、別のアプローチを検討してください。
最終的なカウントを取得するための代替手段
影響を受ける行の数を得るには、まったく異なるアプローチがあります (
ではない
前のフルカウント
OFFSET
&です。
LIMIT
が適用されました)。Postgresは、最後のSQLコマンドによって影響を受けた行の数を内部的に記録しています。いくつかのクライアントはその情報にアクセスしたり、(psqlのように)自分自身で行を数えたりすることができます。
例えば、影響を受けた行の数を取得するためには plpgsql でSQLコマンドを実行した直後に取得できます。
GET DIAGNOSTICS integer_var = ROW_COUNT;
または
pg_num_rows
で
PHP
. または他のクライアントの同様の機能。
関連する
関連
-
[解決済み】不明なMySQLサーバーのホスト
-
[解決済み】php, mysql - データベースへの接続数が多すぎるエラー
-
[解決済み】ディレクトリ内のファイル数を数える PHP
-
[解決済み】PHP フェイタルエラー。未定義の関数mssql_connect()をコールしています。
-
[解決済み] * vchiqインスタンスを開くのに失敗しました。
-
phpのAllowed memory size of 134217728 bytes枯渇問題の解決法
-
[解決済み] PHPの配列を別の配列にコピーする関数はありますか?
-
[解決済み] SQL Server - 挿入された行のIDを取得するための最良の方法は?
-
[解決済み] ランダムな行を選択する最適な方法 PostgreSQL
-
[解決済み] リファレンス - このシンボルはPHPで何を意味するのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】stdClassクラスのオブジェクトが文字列に変換されない。
-
[解決済み】XAMPPエラー: www.example.com:443:0 サーバー証明書に、サーバー名と一致するIDが含まれていません。
-
[解決済み】「Fatal error: Class 'MySQLi' not found "を解決するには?
-
[解決済み】Laravel 5.2 Storage::makeDirectory($dir) でディレクトリが作成されない。
-
[解決済み] [Solved] Fatal error: メンバ関数 query() の null への呼び出し。
-
[解決済み】PHPのクラスが見つからないが、インクルードされている
-
[解決済み] mysqli_fetch_assoc() は、パラメータ 1 が mysqli_result であることを期待し、boolean が与えられる [重複] 。
-
[解決済み] Uncaught Error: 未定義の関数 mysql_escape_string() の呼び出し。
-
[解決済み] SQLでmax(count(*))を行うことは可能ですか?
-
[解決済み] LIMIT/OFFSETを指定してクエリを実行し、総行数を取得することも可能