簡體   English   中英

SQL會計算多對多的值,還是每次添加新行時都計算它?

[英]SQL count many-to-many values or have it counted every time new row is added?

我正在使用MySQL(MyISAM)5.0.41,我有這個查詢:

SELECT `x`.`items`.id, `x`.`items`.name, COUNT(*) AS count
    FROM `x`.`items` INNER JOIN `x`.`user_items`
    ON `x`.`items`.id = `x`.`user_items`.item_id
    GROUP BY name HAVING count > 2 ORDER BY count DESC

我有大約36,000個用戶,175,000個user_items和60,000個不斷添加的項目。 所以這個查詢變得有點慢......

是否更好:

  • items有一個count字段並定期更新(比如每次用戶添加項目時)
  • 或者像這樣運行查詢(慢慢地)..

或者是否有任何SQL將為我填充計數字段?

謝謝

您可以使用中間解決方案:

  • ts DATETIME列添加到user_items表,該表將描述用戶添加項目的時間

  • 將一個ts DATETIME列添加到users表中,該表將描述實際情況,只要cnt ,緩存計數列

  • 使用新計數和時間戳定期更新users表:

     INSERT INTO users (id, ts, cnt) SELECT * FROM ( SELECT user_id, NOW() AS nts, COUNT(*) AS ncnt FROM user_items ui WHERE ui.timestamp <= NOW() ) ON DUPLICATE KEY UPDATE ts = nnow, cnt = ncnt 
  • 刪除user_items條目時,用戶的時間戳無效

  • 發出此查詢以計算項目:

     SELECT u.id, u.cnt + ( SELECT COUNT(*) FROM user_items ui WHERE ui.ts > u.ts AND ui.user_id = u.id ) FROM users 

這樣,只有新添加的項目才會在user_items表中計算得更快,並且您不會經常更新記錄時出現並發問題。

您應該首先索引user_items.item_id並對其進行分組而不是名稱。 字符串分組要慢得多(自己試試),索引應該加快速度。 如果仍然太慢,您可以首先運行GROUP BY查詢,然后如果您的DBMS執行計划默認情況下沒有這樣做,則可以加入項目表。

該查詢幾乎每次都進行全表掃描。 沒有辦法解決這個問題。 索引會加快我加速連接的速度,但隨着數據的增長,查詢會變得越來越慢。

存儲摘要數據,如“計數”和“項目”將是要走的路。 您可以使用存儲過程或代碼執行此操作。 作為雙重檢查,您可以定期(即每天一次)更新所有計數,以便您知道它們是准確的。

我的沖動是將數據保留為正常形式(換句話說,不增加“計數”字段),然后在應用程序級別緩存慢查詢的結果。

如果緩存無效,因為許多人正在進行查詢,而且很少有人進行兩次,那么,是的,您可以設置一個存儲過程來自動更新某些表中的某些行。 詳細信息因數據庫供應商而異。 這是在Postgresql中如何做到這一點 由於競爭條件,這是唯一安全的方法(即在DB內,而不是從應用程序層)。

每次運行查詢時,您真的獲得了36,000名用戶嗎? 如果您正在尋找性能問題的根源,那么它可能就在那里。

根據您的RDBMS,您可以查看索引或物化視圖等內容。 將計數作為表的一部分並嘗試維護它幾乎肯定是一個錯誤,特別是對於數據庫的小尺寸。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM