2010-09-22 101 views
1

當涉及到提高count(1)查詢的性能時,數據庫設計的常見/最佳實踐是什麼? (我目前正在使用SQLiteSQL數據庫設計 - 緩存表?

我已經規範化了我的數據,它存在於多個表中,並且我想對具有良好索引的單個表執行簡單的事情 - 查詢可接受的快我的目的。

如:

SELECT count(1) from actions where type='3' and area='5' and employee='2533'; 

但是當我開始進入多表查詢,事情變得太慢(> 1秒)。

SELECT count(1) 
    from 
    (SELECT SID from actions 
     where type='3' and employee='2533' 
    INTERSECT 
    SELECT SID from transactions where currency='USD') x; 

我該如何緩存我的結果?什麼是好設計? 我的自然反應是添加一個表,僅用於存儲每位員工的緩存結果行?

回答

1

編輯

Command Query Responsibility Segregation (CQRS)設計模式專門着眼於提高數據訪問的性能read side,經常在分佈式系統和企業規模。

  • 發出命令,以指示「交易」或「改變/更新」到數據
  • 當系統處理這些命令(例如,通過更新數據庫表),則受影響的對象的新狀態是「廣播」
  • 感興趣的系統(例如用戶界面或可查詢的REST API)將訂閱這些數據更改,然後將更新後的數據「整形」爲其特定需求
  • 然後將更新的數據緩存稱爲「讀取商店」)

通常與CQRS相關的另一種模式是"Event Sourcing",它存儲並允許各種用例的「重放」命令。

以上可能是矯枉過正的情況,但在內部應用水平非常簡單的實現緩存,可通過Sqllite Trigger

假設有更多的「讀」比寫入您actionstransactions表,

  • 你可以創建一個特定的緩存表的「SID的行動按類型的員工,一個針對‘SID通過貨幣交易’,甚至將兩者結合起來(取決於你有什麼其他場景用於查詢)
  • 然後,每次更新底層的actiontransactions表時,您都需要更新這些緩存表。一種便宜(並且令人討厭)的方式是在actiontransactions表上提供INSERT,UPDATE和DELETE觸發器,然後該表將更新適當的緩存表。
  • 您的「查詢」接口現在主要使用「派生」數據(如計數)與緩存表進行交互。
  • 但是,您仍然需要處理緩存未命中情況,例如這些緩存表的初始「種子」,或者是否需要重新生成緩存表。

除了像SqlLite本地關係數據庫,NoSQL數據庫一樣MongoDb, Cassandra and Redis經常被用作替代品讀重環境(取決於你需要緩存中的數據的類型和格式)來讀取端緩存。但是,您需要處理替代方法,以將來自「主」(例如SQLLite)數據庫的數據同步到這些緩存讀取存儲 - 觸發器顯然不會在此處將其切斷。

原來的答案

如果你是100%肯定,你總是重複一模一樣的查詢相同的客戶,當然,堅持的結果。

但是,在大多數其他情況下,RDBMS通常會很好地處理緩存。如果有大量的與美元的交易記錄

與查詢

SELECT SID from transactions where currency='USD' 

相交可能是有問題的。

可能你可以用連接代替它?

SELECT count(1) from 
(
    SELECT t.[SID] 
    from 
     transactions as t 
     inner join 
     (
      SELECT SID from actions where type='3' and employee='2533' 
     ) as a 
     on t.SID = a.SID 
    where t.currency= 'USD' 
) as a 

你可能只是檢查但是您的索引:

對於

  • SELECT COUNT(1)動作,其中 類型= '3' 和麪積= '5' 和 員工= '2533'
  • SELECT SID從動作,其中 類型= '3' 和僱員= '2533'

Actions(Employee, Type)Actions(Employee, Type, Area)上的索引是合理的(假定Employee具有最高的選擇性,並且取決於Type和Area的選擇性)。

您也可以將它與Actions(Employee,Type,Area,SID)上的索引作爲第二個查詢的覆蓋索引進行比較。

而對於以上加入,您需要索引Transactions(SID, Currency)