我正在尝试对列表查询进行一些优化。其中一些具有4个以上的联接(某些OUTER JOIN),需要使用GROUP BY的聚合函数(COUNT,AVG),有时还需要根据这些计算出的值进行排序。我看到同时使用了“临时”和“文件排序”。
我确实具有用于初始查询的缓存,但是我不打算缓存“更多加载”的缓存。我担心这些查询可能无法很好地扩展。
现在,我很想通过将计算出的值添加到主表中来进行非规范化。
假设我们目前已规范化:
SELECT p.id, p.product_name, p.time_created, COALESCE(AVG(r.rating),0) AS rating, COUNT(r.rating) AS review_count
FROM product AS p LEFT JOIN review AS r ON p.id = r.product_id
GROUP BY p.id HAVING (rating, time_created) < (?, ?)
ORDER BY rating DESC, time_created DESC
LIMIT ?
非正规化,可能是:
SELECT id, product_name, time_created, rating, review_count
FROM product WHERE (rating, time_created) < (?, ?)
ORDER BY rating DESC, time_created DESC
LIMIT ?
在两个字段上都有索引。
归一化的阅读肯定更快。但是写起来肯定慢一些。我的问题是:这值得吗?
如果我这样做,应该吗?>
编辑:
我实现了它,并在源代码上添加了一些触发器,以在每次更改视图时计算视图。读取速度可能会快40%(使用50行测试数据,由于未使用“临时”表,希望可以更好地扩展)。这可能是实现它的最简单方法。插入速度较慢。我保留两个版本,并会监视真实数据。
我添加的触发器之一是这样的:
CREATE TRIGGER review_insert AFTER INSERT ON product_review FOR EACH ROW
UPDATE product AS p
SET p.rating =
(SELECT COALESCE(AVG(r.rating),0) FROM product_review AS r WHERE r.product_id = p.id);
我正在尝试对列表查询进行一些优化。它们中的一些具有4个以上的联接(某些OUTER JOIN),需要使用GROUP BY的聚合函数(COUNT,AVG),有时还需要按...
此评论太长了。