2016-10-04 52 views
0

我有幾百萬的記錄高事務表與下面的結構:如何有效地查詢表,而不會影響現場交易

transaction 
-------------- 
id    int 
txn_status  varchar 
amount   bigint 
name   varchar 
txn_time  datetime --Date and time of the transaction 

txn_status字段值可以是completedPending。我需要運行一個查詢,將具有以下特徵檢索的記錄數:與Pending txn_status

  1. 事務與Pending txn_status,因爲最後15分鐘即(current_time - txn_time) <= 15 minutes
  2. 交易在過去的16,25分鐘即(current_time - txn_time) >= 16 minutes and (current_time - txn_time) <= 25 minutes
  3. 之間
  4. 事務與過去26至30分鐘之間,即Pending txn_status(current_time - txn_time) >= 26 minutes and (current_time - txn_time) <= 30 minutes
  5. 事務與Pending txn_status超過30分鐘即(current_time - txn_time) > 30 minutes

目前有兩種解決方案,目前我的頭:

  1. 查詢生產數據庫使用case語句(case語句基於上述時間差將過濾和組記錄)每分鐘的查詢的where子句。

  2. 爲了避免使對生產數據庫大的負荷,有一個類似表一個單獨的數據庫和具有updateinsert觸發器更新表和數據庫上在1號執行上述事後查詢。

如有是達到這一不把數據庫上大的負荷任何最優或更好的解決方案,請分享。

+0

我不是一個足夠的專家來寫這個作爲一個完整的答案,但我會嘗試加快速度的第一件事是使txn_status一個整數字段,並添加一個索引。您通常不希望對數百萬條記錄進行字符串比較。 – Dave

+0

@Dave這是正確的,我會做同樣的事情,但這是一個遺留數據庫,你知道它是如何。 –

回答

2

如果你有形式

CREATE INDEX txn_status_time ON transaction (txn_status, txn_time DESC) 

和寫入的方式,比較沒有算術txn_time查詢的索引,那麼您的查詢就會令人吃驚的快速

喜歡的東西:

SELECT 
    COUNT(*), 
    CASE WHEN txn_time >= current_time - 15 mins THEN "last 15" ... END 
FROM transaction 
GROUP BY CASE WHEN txn_time >= current_time - 15 mins THEN "last 15" ... END 
2

第一個解決方案不應該把大的負荷,如果你有正確的索引,即一個綜合指數INDEX(txn_status, txn_time)

如果大部分在表中的行都沒有掛起,像這樣的查詢應該是非常快的數據庫: SELECT * FROM transaction WHERE txn_status = 'pending' AND txn_time < NOW() - INTERVAL 30 MINUTE作爲非掛起行的數量不應該真的影響查詢的速度。

+0

比我快了一分鐘,正是我所建議的+1 – Caleth

0

首先 - 最好的解決方案往往是最簡單的。查看您是否可以在生產數據庫上執行您的查詢,而不會有過度的性能問題;通過添加索引來調整這些查詢。只要有好的索引和查詢觸發這些索引,「數百萬條記錄」就沒有什麼大不了的。

我建議針對選項2.我通常反對以這種方式使用觸發器,因爲它們可能導致不可預知的行爲,包括不可預知的性能問題。如果您的「更新」觸發器開始緩慢運行,它也會影響您的生產數據庫;所有這一切都需要開發人員意外刪除報告數據庫中的索引,並且您的生產系統可能會變慢並變得無法使用。

取而代之的是,考慮replication--它整理了移動數據的管道,並且通常對性能更友好。