mysql - 如何有效地聚合 View 中的相关对象计数?

标签 mysql sql query-optimization

想象一下这个场景:

我的数据库中有三个表:产品用户喜欢,后者表示产品<之间的关系/em> 和一个用户。现在我有一个查询,它将 ProductsLikes 表连接起来,计算 Product 获得了多少个 Likes。

事实上,我比实际用户更频繁地需要有关计数的信息,并且我希望将上面的查询用作 View 中更大查询的一部分。是否可以优化查询或 View ,以便 MySQL 以某种方式缓存上面计数查询的结果?

最佳答案

我不知道有什么方法可以用 mysql 做到这一点(但我主要使用 postgres,所以这可能是可能的,但我只是不知道)。我建议两个选择:

  • 如果您需要缓存尽可能保持最新,请添加 likes_count专栏到您的Products表,创建AFTER INSERTAFTER DELETELikes 上触发表(假设您从未更新该表),当将新行插入 Likes 时,该表会增加产品的相似计数表并在删除行时减少它。然后,添加一个执行 UPDATE Products SET likes_count=(SELECT COUNT(1) FROM Likes WHERE product_id = Products.id) 的 cronjob偶尔要确保这些值确实是最新的 - 使用触发器维护计数永远不会 100% 准确。
  • 另一个选项是创建一个 View 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这会将缓存表与 View 中的最新信息同步。那么,如果您需要准确的结果,您可以直接从 View 中获取数据。否则,使用缓存表。

如果你选择第一个选项,触发器应该看起来像这样(我的 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;

关于mysql - 如何有效地聚合 View 中的相关对象计数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7087029/

相关文章:

sql - 如何在oracle中为非空值分配等级

php - 如何在mysql中复制列时插入数据?

mysql - 为什么 MIN() 查询比 ORDER BY X LIMIT 1 慢?

MySQL:自动将数据从常规 txt/csv 文件提取到数据库

mysql - 查看/分析 Django 中的所有数据库访问

mysql - 全新 mysql-server 安装不要求输入密码

sql - 将所有与不存在的并入并插入

sql - 如果 IN 子句中的表为空,则 Postgresql 查询速度慢

php - Laravel - 从模型动态构建路线

PHP 和 MySQL - 更改代码 ORDER BY