2009-07-15 48 views
0

鉴于任何查询(分组,联接和子查询都可以任何组合),我想尽可能高效地将其分页。现在我只需运行查询,然后计算返回到PHP的行数,找出有多少页数据,显示当前页面上的数据,并将正确的链接输出到其他页面。以编程方式替换SQL查询中的SELECT字段以确定结果的数量

但是,似乎我认为查询中潜在的非常大的结果集大部分都浪费了。有没有办法在第一次选择COUNT(*)的时候运行查询,以获得一个包含待分页行的单个数字,并且第二次根据当前正在查看的页面使用适当限制运行原始查询?这会对数据库服务器征税吗?

对于一个简单的查询,这是没有问题的......在SELECT和WHERE之前用count(*)替换所有的东西。但是,如果查询中存在分组,则这不起作用,因为您将在每个组中获得计数,而不是总行数。如果你在列a,b和c上分组,选择count(distinct a,b,c)是否正确?有什么特别的事情需要处理子查询吗?

回答

3

你也许可以用下一:

select count(*) 
from (<original select query>) 
2

这可能会帮助:MySQL有限制特点:

select * 
from mytable 
limit 10,40 

极限10,40手段给我40周的结果与结果10起(其中0为基础)。

您可以在此功能上构建分页。在上面的例子中,40代表40个结果/页面。

+0

我明白,但是你必须以某种方式获得匹配记录的总数,以建立适当的分页。 – 2009-07-15 13:45:45

+0

没错,我的答案中没有涉及这部分内容。这只是一个起点。 – 2009-07-15 13:48:02

4

您可以使用SQL_CALC_FOUND_ROWS来给你小的结果集,但也有MySQL的计算不受限制的结果集的大小:

SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name LIMIT 10; 

SELECT FOUND_ROWS(); 
+0

之前从来不知道SQL_CALC_FOUND_ROWS。由于我们必须使用查询数据库的方法,但不能确定我能够使用它,但它在命令行上运行良好。另一个工具总是一件好事! – 2009-07-15 14:10:12

2

你可以问MySQL来计算出本来的行数通过使用SQL_CALC_FOUND_ROWS返回没有限制子句。

这会给你20的第1页:

然后,你可以要求将已返还而不SQL_CALC_FOUND_ROWS行数:

SELECT FOUND_ROWS() AS numrows 

这将是回答从驱动程序内部没有另一个请求到数据库服务器。它也应该处理更复杂的查询。

0

我会尝试在你的开发环境一点,看看是否有任何性能优势。

您可以根据MercerTraieste的建议,使用LIMIT子句基于每页记录限制返回结果,但是,您现在正在每页访问数据库,这通常是要避免的。我假设你的PHP脚本使用游标从MySQL服务器获取数据,并且我想光标保持打开状态以检索你的其他页面的数据。 通过执行LIMIT查询,您实际上可能会对数据库服务器征税更多。当然,我会通过使用MySQL性能监视器工具监视数据库负载来进行测试/实验,如果存在的话。

您可能甚至不必为COUNT(*)进行分页,只需确定每页有多少条记录,然后从不同的结果点开始返回即可。

即,做(伪代码如下)

SELECT <columns> FROM <table> LIMIT <records-per-page>; 
while (More data available for future pages) 
{ 
    records-shown += records-per-page; 
    SELECT <columns> FROM <table> LIMIT <records-per-page>,<records-shown>; 
} 

诚然,这样做的其他方式可能会更清洁。