2009-07-07 38 views
8

我有一個有趣的分隔符。我有一個非常昂貴的查詢,涉及做幾個全表掃描和昂貴的連接,以及調用一個標量UDF來計算一些地理空間數據。在SQLServer中使用緩存表,我瘋了嗎?

最終結果是包含呈現給用戶的數據的結果集。但是,我不能在一次調用中返回所有我想要顯示用戶的內容,因爲我將原始結果集細分爲多個頁面,並返回指定的頁面,並且還需要獲取原始整個數據集,並應用分組依次和聯接以計算相關的彙總數據。長話短說,爲了將我需要的所有數據綁定到UI,這個昂貴的查詢需要被調用大約5-6次。

因此,我開始考慮如何計算一次昂貴的查詢,然後每次後續的調用都可能以某種方式對抗緩存的結果集。

我想到了將查詢抽象爲存儲過程的想法,該存儲過程將CacheID(Guid)作爲可爲空的參數。

此sproc會使用cacheID將結果集插入到緩存表中以唯一標識此特定結果集。

這允許sprocs需要在此結果集上傳遞來自先前查詢的cacheID,它是一個簡單的SELECT語句來檢索數據(在cacheID上具有單個WHERE子句)。

然後,使用定期SQL作業清除緩存表。

這很好,真正加快零負載測試。但是,我擔心這種技術可能會導致加載時出現大量讀取和寫入緩存表的問題。

因此,長話短說,我瘋了嗎?或者這是一個好主意。

顯然我需要擔心鎖爭用和索引碎片,但還有其他需要關注的東西?

回答

3

我之前就已經這樣做了,特別是當我沒有奢侈的編輯應用程序的時候。我認爲它有時是一種有效的方法,但通常在應用程序中有一個緩存/分佈式緩存是首選,因爲它可以更好地減少數據庫上的負載並更好地擴展。

天真的「只是在應用程序中」這個棘手的事情是,很多時候你有多個應用程序與數據庫進行交互,如果你沒有應用程序消息總線(或者類似的東西) memcached),因爲每個應用程序擁有一個緩存可能很昂貴。

顯然,對於你的問題,理想的解決方案是能夠以更便宜的方式進行分頁,而不需要通過所有的數據來獲取頁面N.但是有時候它是不可能的。請記住,流出數據庫的數據可能比將數據流出數據庫返回到同一數據庫更便宜。您可以引入一個新的服務,負責執行這些長查詢,然後讓主應用程序通過服務與數據庫進行通信。

+0

然後,我不得不把管理數千個結果迴應用程序? – FlySwat 2009-07-07 23:00:07

+0

爲了詳細說明,我對這些數據執行了大量的SQL操作,並將結果發送給應用程序。因此,在應用程序中緩存會適得其反。 – FlySwat 2009-07-07 23:03:03

1

你的tempdb在加載時可能會像瘋了一樣膨脹,所以我會看。將昂貴的連接放入視圖併爲視圖編制索引可能比試圖緩存每個用戶的表更容易。