具有随机性的MySQL分页

时间:2017-08-27 09:41:23

标签: mysql random indexing pagination

我试着用随机排序的项目来实现一些分页。 我有一个解决方案,如果可以,我需要专家建议。

我的桌子像:

id | category | product_name | product_description | product_image | filter1 | filter2 | filter 3 .. bla bla bla

我想基于一些过滤器对搜索结果进行分页并随机化结果。

我认为我应该创建另一个表格,其中我只保留产品的ID,类别和带有索引的过滤器,用于过滤的所有可能性。然后,当发生搜索时,我会根据一些特定的索引搜索较小的表,并将ID保存在数组中并在PHP中随机化它们。

编辑:我的桌子有500k - 1百万个条目。

会慢吗?

2 个答案:

答案 0 :(得分:0)

以前曾问过类似的问题。这是一个quick selection of a random row from a large table in mysql

  

我认为我应该创建另一个表格,其中我只保留产品的ID,类别和带有索引的过滤器,用于过滤的所有可能性。然后,当发生搜索时,我会根据一些特定的索引搜索较小的表,并将ID保存在数组中并在PHP中随机化它们。

您无法在真实世界的项目中执行此操作。示例:您有10-15个过滤器,每个过滤器有5-15个选项。

我们来做一些数学。

对于最低版本,您有31 * 31 combinations。数据库能够处理它。 在此示例中,为了达到最大值,您有32767 * 1023 = 33520641组合。这只是没有与这些过滤器匹配的产品的组合数量。

答案 1 :(得分:0)

  1. 过滤1M行以查找100K行 - 1M行的全表扫描
  2. 从100K中挑选10个随机行 - 扫描100K行,除非您使用http://mysql.rjweb.org/doc.php/random中的某种技术。
  3. 留下让你“分页”的东西。如果它不小心重复行,你关心吗?这是基于网络的,意味着“留下一些东西”可能会很混乱 - 例如列出在[下一步]按钮的网址中已经看到的所有项目。
  4. 通过LIMIT和OFFSET的分页是订单(N * N),遍历所有N页。 100K行,一次10行,就像500M。甚至比最初的1M还差。
  5. 现在,让我发明一个解决方案,解决“随机”和“分页”的成本问题。见http://mysql.rjweb.org/doc.php/random#case_extra_float_column_for_randomizing

    1. 准备:添加一个带有随机数的额外列。索引它。这将成为随机发生器和“你离开的地方”,以避免使用昂贵的OFFSET
    2. 请参阅链接,了解获取前10个随机行的方法。
    3. 有关“记住您离开的地方”的更多信息,请参阅http://mysql.rjweb.org/doc.php/pagination
    4. 做所有这些,费用大部分都是原来的第1步,即过滤1M行所需的费用。希望它甚至不会那么昂贵 - 这取决于是否有合适的索引可以一直到LIMIT 10。 (我的直觉说这不切实际。)

      总结:

      SELECT ...
          FROM ...
          WHERE filters...
             AND rnd > $left_off
          ORDER BY rnd
          LIMIT 10;
      

      如果你从0开始$left_off,你会得到一个可重复的,但看似随机的序列。并且[Next]按钮只需要传递从当前页面获取的rnd的最后一个值。

      现在让它不可重复?每晚重新填充rnd。 (这会使任何人在分页过程中一塌糊涂。)