想象一下这种情况:
我的数据库中有三个表:产品,用户和喜欢,后者表示产品<之间的关系/ em>和用户。现在我有一个查询,它将产品与 Likes 表连接起来,计算产品获得的数量。
事实上,我比实际用户更频繁地需要关于计数的信息,并且我想在视图中使用上面的查询作为更大查询的一部分。是否可以优化查询或视图,以便MySQL以某种方式缓存上面的计数查询的结果?
答案 0 :(得分:1)
我不知道用mysql做这个的方法(但我主要使用postgres,所以它可能是我可能不知道的)。我建议两个选择:
likes_count
表格中添加Products
列,然后创建AFTER INSERT
和AFTER DELETE
个触发器Likes
表(假设您永远不会更新该表),当新行插入Likes
表时会增加产品的相似数,并在删除行时减少它。然后,添加一个偶尔执行UPDATE Products SET likes_count=(SELECT COUNT(1) FROM Likes WHERE product_id = Products.id)
的cronjob,以确保这些值真正是最新的 - 使用触发器维持计数绝不是100%准确。CREATE VIEW Products_Likes_View AS SELECT product_id, COUNT(*) AS likes_count FROM Likes GROUP BY product_id;
,并创建一个缓存表,如CREATE TABLE Products_Likes_Cache (product_id INTEGER PRIMARY KEY, likes_count INTEGER NOT NULL);
。然后,添加一个执行BEGIN; TRUNCATE Products_Likes_Cache; INSERT INTO Products_Likes_Cache SELECT * FROM Products_Likes_View; COMMIT;
的cronjob,它将使缓存表与视图中的最新信息同步。如果您需要准确的结果,则可以直接从视图中获取数据。否则,请使用缓存表。如果你使用第一个选项,触发器应该看起来像这样(我的MySQL技能有点生疏,我可能会使用确切的语法):
CREATE TRIGGER product_increase_likes AFTER INSERT ON Likes
FOR EACH ROW BEGIN
UPDATE Products SET likes_count=likes_count+1 WHERE id=NEW.product_id
END;
CREATE TRIGGER product_decrease_likes AFTER DELETE ON Likes
FOR EACH ROW BEGIN
UPDATE Products SET likes_count=likes_count-1 WHERE id=OLD.product_id
END;
答案 1 :(得分:1)
您不应该需要联接来计算产品的喜好。
SELECT product, count(*)
FROM likes
GROUP BY product;
如果使用WHERE子句,应该快速翻录。