したがって、500 万行を少し超えるテーブルがあります。SQL_CALC_FOUND_ROWS を使用すると、クエリが永久にハングします。私がそれを取り出すと、クエリは LIMIT ,25 で 1 秒以内に実行されます。私の質問は、ページネーションの理由から、合計行数を取得する代替手段はありますか?
3 に答える
SQL_CALC_FOUND_ROWS は、MySQL がフェッチされない場合でも、一致するすべての行をスキャンするように強制します。内部的には、LIMIT 句なしで同じクエリが実行されることになります。
WHERE を介して実行しているフィルタリングがそれほど狂っていない場合は、さまざまなタイプのフィルターを計算してキャッシュし、calc_found_rows によって課されるフルスキャンの負荷を節約できます。基本的に、考えられるほとんどの where 句に対して「select count(*) from ... where ....」を実行します。
そうしないと、Google のように、現実とはまったく関係のないページ番号を吐き出すこともできます (「Goooooooooooogle」と表示され、3 ページに到達すると、突然結果がなくなります)。
MySQL を使用した Google スタイルのページネーションの実装に関する詳細な説明
状況に応じて、COUNT(*) と SQL_CALC_FOUND_ROWS のいずれかを選択する必要があります。クエリ検索条件でインデックス内の行を使用する場合は、COUNT(*) を使用します。この場合、Mysql はテーブル内の実際のデータに触れることなくインデックスからのみ「読み取り」ますが、SQL_CALC_FOUND_ROWS メソッドはディスクから行をロードしますが、大規模なテーブルではコストと時間がかかる可能性があります。
このトピックの詳細については、この記事 @mysqlperformanceblogを参照してください。