2017-07-27 37 views
0

我正在一個電子商務網站上,用戶可以顯示對可用產品的興趣,並將其作爲潛在客戶存儲在mysql表中。這個Leads表由數百萬條記錄組成,每秒鐘增長8條記錄。表結構如下:Mysql:索引計數查詢與維護彙總表

LeadId | ProductId | UserId | RequestDate(DateTime) 

表模式:現在

`id` int(11) NOT NULL AUTO_INCREMENT, 
`ProductId` int(11) DEFAULT NULL, 
`UserID` int(11) NOT NULL, 
`RequestDateTime` datetime(3) NOT NULL, 
PRIMARY KEY (`id`), 
KEY `ix_leads_requestdatetime` (`RequestDateTime`) USING BTREE, 
KEY `ix_leads_productid` (`ProductId`) USING BTREE, 
KEY `ix_leads_userid` (`UserID`) USING BTREE 

的要求是,讓一個用戶提供最大10根引線一天。我有如下的方法來實現這一點:

  1. 選擇查詢到Leads表計數的記錄數爲一天,插入前檢查是否< 20。

  2. 維護DailyLeadCount表,其中包含特定日期的每個userId的導聯計數。表結構:

    UserId | Date | Count 
    

    表模式:

    `RequestDate` date NOT NULL, 
    `UserId` int(11) NOT NULL, 
    `LeadCount` smallint(6) NOT NULL, 
    PRIMARY KEY (`RequestDate`,`UserId`) 
    

    我將在這個表來檢查計數Leads表中插入之前並相應地更新插入後此計數。另外,由於在此表中只有一天數據有用,我將創建一份工作,以便每天對其進行歸檔。

哪種方法更好?正在運行Leads表上的select查詢得到的計數比插入/更新更重,並在DailyLeadCount表上選擇查詢?

是否值得每天維護和存檔表格?

有沒有其他辦法可以解決這個問題?

+0

第三種選擇是構造插入語句,以便將檢查包含在具有子查詢的where子句中。你能顯示錶格模式,包括索引嗎? –

+0

@SloanThrasher添加了表格模式。並且,如果在存儲過程中,在where子句中添加子查詢在性能方面等於approach-1。不是嗎? – ctor

+0

不完全相同。 #1,你有兩個單獨的查詢,選擇和插入。找出最好的方法是編寫兩個查詢並使用Explain來查看服務器如何感知要完成的工作。 –

回答

0

變化

KEY `ix_leads_userid` (`UserID`) USING BTREE 

INDEX(UserID, RequestDateTime) 

然後在用戶吐時

(SELECT COUNT(*) FROM Leads WHERE UserID = 1234 
     AND RequestDateTime > NOW() - INTERVAL 24 HOUR 
) >= 10 

查詢將足夠快,實時地做。

計數是在這段時間之間的昨天和現在 - 這可能不完全是你想要的。相反,如果你希望時鐘在午夜今天上午開始:

 AND RequestDateTime > CURDATE() 

如果「自昨天午夜」:

 AND RequestDateTime > CURDATE() - INTERVAL 1 DAY 

如果你想使用時區的午夜,它會混亂。

潛在問題:如果他能以某種方式批量處理他的潛在客戶,他可以在同一毫秒內插入多個潛在客戶。 (我注意到DATETIME(3)。)

如果您需要檢查「昨天」,對於「最後的86400000毫秒」不太滿意,您對摘要表的想法效果最佳。

+0

當總結表更好時,我有點困惑。我需要檢查「當前日期」的計數(即時鐘在今天午夜重置),而不是最近24小時。如果您表示總結不適用於最後的「x」單位時間,但會更好地適用於「上次日期」。在我的情況下(當前日期)它不會有用嗎? – ctor

+0

如果你只看「今天」,那麼你不需要總結前幾天。總結「今天」最好在今晚午夜之後完成。 –