代码之家  ›  专栏  ›  技术社区  ›  Ty W

如何在分页中拉取和显示每页的范围(最小-最大)数据?

  •  1
  • Ty W  · 技术社区  · 14 年前

    我有一个数据表,可以搜索和排序,但可能会产生数百或数千个广泛的搜索结果。假设用户搜索“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…不幸的是,我还没有想出一种方法来生成这个变量。

    1 回复  |  直到 14 年前
        1
  •  2
  •   hobodave    14 年前

    从技术上讲 可能的 ,我建议您不要浪费时间使用此功能,并寻找其他方法。

    首先,一些关于分页的背景信息。分页通常使用 ORDER BY ... LIMIT [offset], [rows] . 为了让mysql以给定的偏移量向您提供行,它必须读取 全部的 前面的那一排就扔掉了。这是昂贵的,成本随着抵消的增加而增加。(例如,限制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>
    

    我怀疑这对用户是否有好处。

    建议

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

    例子

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