【问题标题】:how to pull and display range (min-max) data for each page in pagination?如何在分页中为每个页面提取和显示范围(最小-最大)数据?
【发布时间】:2010-03-16 01:15:11
【问题描述】:

我有一个可搜索和可排序的数据表,但可能会产生成百上千的广泛搜索结果。假设用户搜索“foo”并按价格降序对 foo 进行排序,我想显示一个快速跳转选择菜单,如下所示:

<option value="1">Page 1 ($25,000,000 - $1,625,000)</option>
<option value="2">Page 2 ($1,600,000 - $1,095,000)</option>
<option value="3">Page 3 ($1,095,000 - $815,000)</option>
<option value="4">Page 4 ($799,900 - $699,000)</option>
...

是否有直接从数据库查询此信息的有效方法?我一直在抓取所有匹配的记录并使用 PHP 计算每个页面的最小值和最大值,这似乎效率低下并且可能导致缩放问题。

我能够想出的唯一可能的技术是某种计算变量的方法,该变量会增加每 X 条记录(X 条记录到一个页面),按此进行分组,并为每个页面分组选择 MIN/MAX ...不幸的是,我无法想出一种方法来生成该变量。

【问题讨论】:

    标签: php sql mysql pagination


    【解决方案1】:

    虽然技术上可能,但我建议您不要在此功能上浪费时间,并寻找其他方法。

    首先,关于分页的一些背景信息。分页通常使用ORDER BY ... LIMIT [offset], [rows] 完成。为了让 MySQL 为您提供给定偏移量的行,它必须读取 all 之前的行,然后将它们丢弃。这是昂贵的并且成本随着偏移量的增加而增加。 (例如 LIMIT 1000, 20 必须读取 1020 行然后扔掉 1000)。当 ORDER BY 不能使用索引完成时,情况会更糟。这可能会导致读取整个无限的结果集,然后对其进行文件排序,然后然后丢弃前 1000 行以满足LIMIT 1000, 20

    现在,让我们解决您的具体问题。如图所示,分页并不是什么“神奇”的东西。这是对结果集进行分页的一种相当蛮力的方式。具体来说,如果不对整个结果集进行排序,您将无法提前知道某页落在了哪个页面上。要计算出每页的最小值和最大值,您需要使用临时表,然后从此临时表中计算整个结果集的每页最小值/最大值。如果您的数据完全不稳定,那么您需要在基础数据发生变化时重新计算。

    如果存储引擎以某种方式存储了给定排序的每一行所在的“页面”,那么您可以相对轻松地完成此操作。不幸的是,事实并非如此。

    此外,我会质疑您的方法对用户的有用性。您的示例显示了价格的良好分布。你能确定你不会得到像下面这样的范围吗?

    <option value="1">Page 1 ($1,005,000 - $1,004,000)</option>
    <option value="2">Page 2 ($1,004,000 - $1,003,450)</option>
    <option value="3">Page 3 ($1,003,450 - $1,003,387)</option>
    <option value="4">Page 4 ($1,003,387 - $1,003,342)</option>
    

    我会质疑这是否对用户有任何好处。

    建议

    • 保持分页简单
    • 如果您希望用户能够选择价格范围,请将其构建为过滤器 - 不要将其与分页结合使用。

    示例

    在亚马逊上搜索一些东西并注意他们的结果页面。您将获得简单的分页搜索结果。在左侧,您将有各种过滤器应用于您的搜索以进一步优化它。

    【讨论】:

    • 是的,这基本上也是我得出的结论......只是不知道我是否错过了一些可以让它很好地工作的聪明东西。 FWIW 我对查询中的 LIMIT/OFFSET 很熟悉,目前没有使用它的唯一原因是因为我们必须查看 php 中结果中的每一行来构建每页的最小/最大值。但是又提出了另一个问题……如果 MySQL 必须查看前 X 个匹配项以抵消它们,那么每次都返回所有内容并逐步遍历 PHP 中的集合会更糟糕吗?
    • @Ty:是的。 PHP 所做的任何事情,MySQL (C) 都快 10-100 倍。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-12
    相关资源
    最近更新 更多