web-dev-qa-db-ja.com

オフセット+制限付きのmySQLクエリで結果の総数を見つける

私はCodeigniterを使用してページネーション機能を実行していますが、これは一般的にPHP/mySQLコーディングに適用されると思います。

ページごとに必要な結果の数に応じて、オフセットと制限を使用してディレクトリ一覧を取得しています。ただし、必要なページの総数を知るには、(結果の総数)/(制限)を知る必要があります。現在、SQLクエリをもう一度実行してから、LIMITを使用せずに必要な行数をカウントすることを考えています。しかし、これは計算リソースの浪費のように思えます。

もっと良い方法はありますか?ありがとう!

編集:私のSQLクエリはWHEREも使用して、特定の 'category_id'を持つすべての行を選択します

45
Nyxynyx

SQL_CALC_FOUND_ROWS を見てください。

32
Dr.Molle

SELECT COUNT(*) FROM table_name WHERE column = 'value'は、その条件に非常に迅速に一致するテーブル内のレコードの総数を返します。

データベースのSELECT操作は通常「安価」(リソースの観点から)なので、合理的な方法でそれらを使用することにあまり気を悪くしないでください。

編集:OPがその機能が必要であると述べた後、WHEREを追加しました。

6
Austin

結果の合計数withをフェッチしたい場合、 SQL_CALC_FOUND_ROWS は後でFOUND_ROWS()を呼び出す必要があることを考慮してください2番目のSELECTを呼び出さずに制限から返された場合、 [〜#〜] join [〜#〜]subquery からの結果を使用します:

SELECT * FROM `table` JOIN (SELECT COUNT(*) FROM `table` WHERE `category_id` = 9) t2 WHERE `category_id` = 9 LIMIT 50

注:すべての派生テーブルには独自のエイリアスが必要なので、結合したテーブルに名前を付けてください。私の例ではt2

3
Daerik

SQL_CALC_FOUND_ROWSクエリ修飾子と付随するFOUND_ROWS()関数は、MySQL 8.0.17で非推奨になり、将来のMySQLバージョンで削除される予定です。代わりに、LIMITを使用してクエリを実行し、次にCOUNT(*)を使用してLIMITを使用しない2番目のクエリを実行して、追加の行があるかどうかを確認することを検討してください。たとえば、次のクエリの代わりに:

SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name WHERE id > 100 LIMIT 10;
SELECT FOUND_ROWS();

代わりに次のクエリを使用してください。

SELECT * FROM tbl_name WHERE id > 100 LIMIT 10;
SELECT COUNT(*) WHERE id > 100;

COUNT(*)は特定の最適化の対象です。 SQL_CALC_FOUND_ROWSは、一部の最適化を無効にします。

1
Tamil