ホーム>source

テーブルtがあり、テーブルtに15000のエントリがあるとします。

クエリを仮定します

<前>ウィズウィズ

1000行を返します

しかし、最初の10行だけが必要なので、LIMITを実行します

<前>ウィズウィズ

上記のLIMIT句で10行の情報を返すだけでなく、WHERE句で設定された条件を満たす行の合計数を返す単一のクエリを作成することは可能ですか?上記の行では、WHERE句を満たす行が合計1000あるため、1000も返されます。また、両方が1つのクエリで返されます。

SELECT * FROM t WHERE t.nid <1000
あなたの答え
  • 解決した方法 # 1

    あなたは SQL_CALC_FOUND_ROWS を試すことができます 、ステートメントを再度実行することなく、合計レコード数を取得できます。

    <前>ウィズウィズ

    リファレンス:http://dev.mysql.com/doc/refman/5.0/en/information-functions.html

  • 解決した方法 # 2

    更新:SQL_CALC_FOUND_ROWSは有害と見なされます

    まず、関数は移植可能ではありません(MySQLの拡張機能です)。削除されます。ユーザー@Zveddochkaが指摘したように、MySQL 8.0.17ではすでに非推奨になっています。

    しかし、それは適切なインデックスを使用する場合、その後2つのクエリを実行する方が実際には高速です。ウィズウィズ  ディレクティブは、追加のリカバリコストが発生する「仮想スキャン」によって実現されます。クエリがインデックス化されていない場合、このコストは SELECT SQL_CALC_FOUND_ROWS * FROM t WHERE t.nid <1000 LIMIT 10; -- get records SELECT FOUND_ROWS(); -- get count と同じになります 、したがって2つのクエリを実行すると、コストが2倍になります。つまり、 SQL_CALC_FOUND_ROWS  物事は50%速く実行されます。

    しかし、クエリがどうなるかです 適切に索引付けされていますか?ペルコナの人たちはそれをチェックしました。そして、それは COUNT() だけでなく、  メタデータとインデックスにのみアクセスし、 SQL_CALC_FOUND_ROWS なしでクエリにアクセスするため、非常に高速です。  追加コストが発生しないため、より高速です。2つのクエリを組み合わせたコストは、拡張された単一のクエリのコストよりも低くなります。

    ウィズウィズ

    じゃあ何をすればいいの?

    <前>ウィズウィズ

    最初のクエリはカウントを返し、2番目のクエリは実際のデータを返します。

    古い答え

    できますが、それはパフォーマンスキラーになると思います。

    あなたの最良のオプションは、 COUNT() を使用することです  それを回復するために2番目のクエリを発行します。

    <前>ウィズウィズ

    たとえば、http://www.arraystudio.com/as-workshop/mysql-get-total-number-of-rows-when-using-limit.htmlを参照してください。

    または、 SQL_CALC_FOUND_ROWS なしでクエリを実行することもできます  句、および最初の10行のみを取得します。次に、必要に応じて1つのクエリを使用し、

    Results with SQL_CALC_FOUND_ROWS are following: for each b value it takes 20-100 sec to execute uncached and 2-5 sec after warmup. Such difference could be explained by the I/O which required for this query – mysql accesses all 10k rows this query could produce without LIMIT clause.

    The results are following: it takes 0.01-0.11 sec to run this query first time and 0.00-0.02 sec for all consecutive runs.

    So, as we can see, total time for SELECT+COUNT (0.00-0.15 sec) is much less than execution time for original query (2-100 sec). Let’s take a look at EXPLAINs...

    を介して行数を取得できます。 。

  • 解決した方法 # 3

    最速の方法は、SQL_CALC_FOUND_ROWSと2つのクエリを使用することです

    <前>ウィズウィズ

  • 解決した方法 # 4

    FOUND_ROWS()のように聞こえます

    <前>ウィズウィズ // Run two queries ensuring they satisfy exactly the same conditions $field1 = "Field1, Field2, blah blah blah"; $field2 = "COUNT(*) AS rows"; $where = "Field5 = 'X' AND Field6 = 'Y' AND blah blah"; $cntQuery = "SELECT {$field2} FROM {$joins} WHERE {$where}"; $rowQuery = "SELECT {$field1} FROM {$joins} WHERE {$where} LIMIT {$limit}";

  • 前へ java - JPAクエリ:サブクエリをグループ化条件に結合する
  • 次へ ember.js - モデルからのデータをフィルタリングするEmber js