MySQLは非推奨になりました SQL_CALC_FOUND_ROWS
バージョン8.0.17以降で機能を。
だから、され、常に優先してクエリを実行し検討することLIMIT
、及びその後で2番目のクエリCOUNT(*)
とせずにLIMIT
、追加の行があるかどうかを判断します。
ドキュメントから:
SQL_CALC_FOUND_ROWSクエリ修飾子と付随するFOUND_ROWS()関数は、MySQL 8.0.17で非推奨になり、将来のMySQLバージョンで削除される予定です。
COUNT(*)は特定の最適化の対象です。SQL_CALC_FOUND_ROWSは、一部の最適化を無効にします。
代わりに次のクエリを使用してください。
SELECT * FROM tbl_name WHERE id > 100 LIMIT 10;
SELECT COUNT(*) WHERE id > 100;
また、MySQL WL#12615でSQL_CALC_FOUND_ROWS
説明されているように、一般により多くの問題があることが確認されています。
SQL_CALC_FOUND_ROWSには多くの問題があります。まず第一に、それは遅いです。多くの場合、COUNT()のため、クエリをLIMITで実行してから、同じクエリに対して個別のSELECT COUNT()を実行する方が安価です。)は結果セット全体を検索するときに実行できない最適化(filesortなど)を利用できるためです。 COUNT(*)の場合はスキップできますが、CALC_FOUND_ROWSでは、正しい結果を保証するために一部のファイルソート最適化を無効にする必要があります)
さらに重要なことに、多くの状況でセマンティクスが非常に不明確です。特に、クエリに複数のクエリブロックがある場合(UNIONなど)、有効なクエリを生成すると同時に「would-have-been」行の数を計算する方法はありません。イテレーターエグゼキューターがこれらの種類のクエリに向かって進んでいるため、同じセマンティクスを維持しようとすることは本当に困難です。さらに、クエリに複数のLIMITがある場合(派生テーブルなど)、SQL_CALC_FOUND_ROWSが参照する必要があるのは必ずしも明確ではありません。したがって、そのような自明ではないクエリは、イテレータエグゼキュータで以前とは異なるセマンティクスを取得する必要があります。
最後に、SQL_CALC_FOUND_ROWSが役立つと思われるほとんどの使用例は、LIMIT / OFFSET以外のメカニズムで解決する必要があります。たとえば、電話帳は、レコード番号ではなく、文字(UXの観点とインデックスの使用の両方)でページ番号を付ける必要があります。ディスカッションは、投稿番号によるページ番号順ではなく、日付順(インデックスの使用を許可する順)で、無限スクロールの順序になっています。等々。
SQL_CALC_FOUND_ROWS
20秒以上かかりました。別のCOUNT(*)
クエリを使用すると、5秒未満かかりました(カウント+結果クエリの両方)。