0

多数のフィールドを持つhousesテーブル、関連する画像テーブル、およびその他の 3 つの関連テーブルがあるとします。houses関連するテーブルのすべてのデータを使用して、すべてのデータを取得する高価なクエリがあります。ページネーションの場合、同じ高価な MySql クエリを 2 回実行する必要がありますか? 現在の結果ページに対して 1 回、レコードの総数を取得するために 1 回です。

でサーバー側のページネーションを使用してLimit 0,10おり、家の総数とデータを返す必要があります。count(*)ページネーションの結果セットを制限しているという理由だけで、関数で同じ高価なクエリを実行することは意味がありません。MySQL にクエリ全体をカウントするように指示するが、現在のページネーション データのみを戻す別の方法はありますか?

私の質問が明確であることを願っています...ありがとう

4

2 に答える 2

1

MySql についてはわかりませんが、多くのデータベースでは、データベースの最適化エンジンが2 つのクエリには多くの共通点があります。

ランニング

select count(1) from (
  select some_fields, row_number over (order by field) as rownum
  from some_table
)

その後

select * from (
  select some_fields, row_number over (order by field) as rownum
  from some_table
)
where rownum between :startRow and :endRow
order by row_number

これには、2 つの異なるラッパー (1 つはページング用、もう 1 つは合計カウントの取得用) を使用して、クエリを 1 か所だけで維持できるという利点もあります。

補足として、実行できる最善の最適化は、毎回まったく同じクエリをデータベースに送信することです。つまり、ユーザーが並べ替えを変更したり、クエリを実行できるフィールドを変更したりできる場合は、すべてを同じクエリに焼き付けます。例えば:

select some_fields,
   case 
     when :sortField = 'ID' and :sortType = 'asc' 
       then row_number over (order by id)
     when :sortField = 'ID' and :sortType = 'desc' 
       then row_number over (order by id desc)
   end as rownum
from some_table
where (:searchType = 'name' 
  and last_name like :lastName and first_name like :firstName)
or  (:searchType = 'customerType' 
  and customer_type = :customer_type)
于 2013-05-03T10:08:26.613 に答える
0

cfquery には、便利な recordcount 変数があります。cfoutput の startrow および maxrows 属性を使用して、表示されるレコード数を制御することもできます。最後に、coldfusion でクエリ結果をキャッシュできるため、毎回データベースに対して実行する必要がありません。

于 2013-05-03T09:31:17.303 に答える