假设houses
表包含许多字段,相关图像表和其他3个相关表。我有一个昂贵的查询,它检索所有houses
数据,包含相关表中的所有数据。在分页的情况下,我是否需要运行相同的昂贵的MySql查询两次:一次用于当前结果页面,一次用于获取记录总数?
我正在使用Limit 0,10
的服务器端分页,并且需要返回房屋总数以及数据。使用count(*)
函数运行相同的昂贵查询对我来说没有意义,因为我限制了分页的结果集。
是否有另一种方法可以指示MySQL计算整个查询,但只返回当前的分页数据?
我希望我的问题很明确...... 谢谢
答案 0 :(得分:1)
我不知道MySql但是对于很多dbs,我认为你会发现运行它两次的成本没有你想象的那么高 - 如果你这样做就是db的优化引擎认为这两个查询有很多共同之处。
运行
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个用于获取总计数。
正如旁注,您可以做的最佳优化是确保每次都向db发送完全相同的查询。换句话说,如果用户可以更改排序或更改他们可以查询的字段,请将其全部烘焙到同一查询中。 E.g:
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)
答案 1 :(得分:0)
cfquery有一个可能有用的记录计数变量。您还可以使用cfoutput的startrow和maxrows属性来控制显示的记录数。最后,您可以将查询结果缓存在coldfusion中,这样您就不必每次都对数据库运行它。