繁体   English   中英

如何避免在分页中运行相同的昂贵的MySql查询两次?

[英]How to avoid running the same expensive MySql query twice in pagination?

假设一个带有大量字段的houses表,相关图像表和其他3个相关表。 我有一个昂贵的查询,它检索所有houses数据以及相关表中的所有数据。 在分页的情况下,我是否需要运行相同的昂贵的MySql查询两次:一次用于当前结果页面,一次用于获取记录总数?

我正在使用Limit 0,10服务器端分页,并且需要返回房屋总数以及数据。 对我来说,使用count(*)函数运行相同的昂贵查询没有任何意义,只是因为我限制了分页的结果集。 还有另一种方法可以指示MySQL计算整个查询,但只带回当前的分页数据吗?

我希望我的问题很清楚...谢谢

我不了解MySql,但是对于许多数据库,我认为您会发现两次运行它的成本并不像您怀疑的那样高-如果您这样做的方式使数据库的优化引擎能够看到两个查询有很多共同点。

跑步

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

这还具有一个优点,即您可以在一个地方维护查询,并在其周围使用两个不同的包装,其中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)

cfquery具有一个也许有用的recordcount变量。 您还可以使用cfoutput的startrow和maxrows属性来控制显示多少条记录。 最后,您可以将查询结果缓存在Coldfusion中,这样就不必每次都对数据库运行它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM