【问题标题】:Paginated searching... does performance degrade heavily after N records?分页搜索...在 N 条记录后性能是否会严重下降?
【发布时间】:2018-12-06 13:34:31
【问题描述】:

我刚刚在 YouTube 上尝试了以下查询:

http://www.youtube.com/results?search_query=test&search=tag&page=100

并收到错误消息:

抱歉,YouTube 不会为任何查询提供超过 1000 个结果。 (您要求从 2000 年开始的结果。)

我也试过谷歌搜索“测试”,虽然它说有大约 34.4 亿个结果,但我只能找到第 82 页(或大约 820 个结果)。

这让我想知道,N 条记录后的分页搜索是否会导致性能开始下降(特别想知道 SQL Server 中的 ROW_NUMBER() 或其他数据库系统中的类似功能),还是 YouTube/Google 出于其他原因这样做?当然,大多数人不太可能需要超过前 1000 个查询结果,但我想这个限制是出于某种技术原因而专门设置的。

然后 Stack Overflow 再次让您翻阅 47k 个结果:https://stackoverflow.com/questions/tagged/c?page=955&sort=newest&pagesize=50

【问题讨论】:

标签: sql-server performance full-text-search


【解决方案1】:

是的。高偏移量缓慢且效率低下。

找到偏移记录的唯一方法是计算之前的所有记录,然后丢弃它们。

(我不知道 ROW_NUMBER(),但在标准 SQL 中会是 LIMIT。所以

SELECT * FROM table LIMIT 1999,20

)

.. 在上面的示例中,必须先获取前 2000 条记录,然后丢弃。通常它不能向前跳过,或者使用索引直接跳转到数据中的正确位置,因为通常会有一个“WHERE”子句过滤结果。

可以缓存结果,这可能是 SO 所做的。所以它实际上不必每次都计算大偏移量。 (大多数 SO 的搜索是一组“小”已知标签,因此缓存非常可行。任意搜索查询将有很多版本要捕获,因此不切实际) (或者,它可能正在使用其他允许任意偏移的实现)

其他地方也有类似的事情 http://sphinxsearch.com/docs/current.html#conf-max-matches

信封测试背面:

mysql> select gridimage_id from gridimage_search where moderation_status = "geograph" order by imagetaken limit 100999,3;
...
3 rows in set (11.32 sec)

mysql> select gridimage_id from gridimage_search where moderation_status = "geograph" order by imagetaken limit 3;
...
3 rows in set (4.59 sec)

(选择任意查询,以免很好地使用索引,如果可以使用索引,则差异不太明显,更难看到。但是在运行大量查询的生产系统中,1 或 2ms 的差异是巨大的)

更新:(显示索引查询)

mysql> select gridimage_id from gridimage_search order by imagetaken limit 10;
...
10 rows in set (0.00 sec)

mysql> select gridimage_id from gridimage_search order by imagetaken limit 100000,10;
...
10 rows in set (1.70 sec)

【讨论】:

  • 所以即使按索引列排序,高偏移量也会有很大的性能损失?
  • 更新添加了一个使用索引的查询示例。
【解决方案2】:

这是一个 TOP 子句,旨在限制数据库必须执行的物理读取量,从而限制查询所花费的时间。想象一下,您的数据库中有 820 亿个指向“日本”故事的链接。如果有人查询“日本”怎么办? 820亿条结果真的都会被点击吗?不,用户需要前 1000 个最相关的结果。当搜索是通用搜索时,例如“测试”,则无法确定相关性。在这种情况下,YouTube/Google 必须限制返回的数量,这样其他用户就不会受到一般搜索的影响。返回 1,000 个结果或 82,000,000,000 个结果哪个更快?

【讨论】:

  • 是的,但您不会退回全部金额,而是退回其中的一部分。我的问题是,在一组大小为 N 的情况下,从第 50 位开始返回 50 条记录是否会比从第 100 位开始时产生更大的性能损失?
猜你喜欢
  • 2021-12-17
  • 1970-01-01
  • 2011-12-13
  • 2021-12-03
  • 2018-07-02
  • 1970-01-01
  • 2014-08-31
  • 1970-01-01
  • 2020-12-20
相关资源
最近更新 更多