0

在处理许多电子商务网站上的分页和过滤产品时,我遇到了性能问题,这是 Zappos 的一个示例

标准类型:
显示 132 个结果中的 1-10 个。[上一个] 1 2 [3] 4 ... 13 [下一个]
[10] 每页结果

对我来说,问题的很大一部分似乎是查询运行了两次,一次是为了计算结果的数量,一次是为了实际填充数组。以下是“过滤器”查询:

SELECT product_id, product_title, orderable
FROM table_view
WHERE (family_title = 'Shirts' OR category_title = 'Shirts')
AND ((detail_value = 'Blue' AND detail_title = 'Color')
OR (detail_value = 'XL' AND detail_title = 'Size'))
GROUP BY product_id, product_title, orderable
HAVING COUNT(detail_title)=2
ORDER BY product_id
LIMIT 10 OFFSET 0

查询单独运行大约需要 20 毫秒。它从中选择的表是一个视图,它是大约五个不同表的连接。用户传入的参数是“detail_value”和“detail_title”,它们是过滤条件。“家庭”和“类别”然后限制由“每页结果”设置。因此,如果他们想查看所有结果,则限制设置为 2000。每次他们通过分页转到新页面时,都会再次运行整个查询。下面是 PHP 的一个片段,$products 是一个查询结果的数组。然后 $number_of_results 是具有最大限制的同一事物的计数。

$products = filter($value, $category_title, $number_per_page, $subcategory, $start_number);

$number_of_results = count(filter($value, $category_title, 2000, $subcategory, 0));

$pages = ceil($number_of_results / $number_per_page);

在我的本地机器上运行时,加载结果页面大约需要 600-800 毫秒,当部署到 Heroku 时,加载页面需要 13-16 秒。我遗漏了很多 PHP 代码,但我使用 PHP 的 PDO 类将查询结果变成一个对象以在 PHP 中显示。被连接的表是产品表、类别表、明细表以及通过外键链接它们的两个表。

谷歌结果显示这是一个非常常见/复杂的问题,但我还没有遇到任何适合我的真正解决方案。

4

1 回答 1

0

许多分页查询通常需要运行多次:一次确定将显示多少条记录,然后再次获取记录屏幕。然后后续查询抓取下一个记录屏幕,等等。

慢分页查询的两种解决方案是:

  1. 使用游标从打开的查询结果集中提取 n 条记录
  2. 加快查询速度

解决方案 1 在内存方面对于服务器资源来说可能是昂贵的,并且如果您有许多并发用户生成这样的查询,则可能无法很好地扩展。使用您正在使用的 PDO 类实现游标也可能很困难。

解决方案 2 可以通过改进视图查询、添加索引等来完成。但这可能还不够。如果表的读取频率远高于写入频率,您可以尝试使用 UPDATE/INSERT/DELETE 触发器技巧。与其对 VIEW 运行查询,不如创建一个与 VIEW 具有相同列结构和数据的表。每当基础表之一发生更改时,请手动修改此新表以遵循更改。这会减慢写入速度,但会大大提高阅读速度。

于 2012-08-15T21:05:50.483 回答