想象一下這樣的情景:如何有效地聚合視圖中的相關對象計數?
我在我的數據庫三個表:產品,用戶和喜歡,後者代表產品和用戶之間的關係。現在我有一個查詢,其中加入產品與贊成表,計算有多少喜歡產品了。
事實上,我需要比實際用戶更多的有關計數的信息,並且我希望將上面的查詢用作視圖中更大查詢的一部分。是否有可能優化查詢或視圖,以便MySQL以某種方式緩存上述計數查詢的結果?
想象一下這樣的情景:如何有效地聚合視圖中的相關對象計數?
我在我的數據庫三個表:產品,用戶和喜歡,後者代表產品和用戶之間的關係。現在我有一個查詢,其中加入產品與贊成表,計算有多少喜歡產品了。
事實上,我需要比實際用戶更多的有關計數的信息,並且我希望將上面的查詢用作視圖中更大查詢的一部分。是否有可能優化查詢或視圖,以便MySQL以某種方式緩存上述計數查詢的結果?
我不知道有一種方法來做到這一點與MySQL(但我主要使用Postgres,所以它可能會,我只是不知道)。我建議兩個選項:
likes_count
列添加到您的Products
表,創建AFTER INSERT
和AFTER DELETE
觸發對Likes
表(假設你永遠不更新該表),當一個新行插入到Likes
表中時增加了一個產品的相似計數,並在刪除一行時將其減少。相比之下,添加一個cronjob偶爾執行UPDATE Products SET likes_count=(SELECT COUNT(1) FROM Likes WHERE product_id = Products.id)
以確保值真的是最新的 - 保持與觸發器的計數從來沒有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;
你不應該」 t需要一個加入來計算產品的喜好。
SELECT product, count(*)
FROM likes
GROUP BY product;
如果您使用WHERE子句,應該快速翻錄。
感謝您提供非常詳細的答案和實例! – Thomas