讓我從描述場景開始。我有一個使用SQL Server 2008的MVC 3應用程序。在其中一個頁面中,我們顯示從數據庫返回的每個登錄用戶的UNIQUE列表。 用於返回產品列表的SQL查詢(實際上是一個VIEW)非常昂貴。在內存或數據庫中緩存昂貴的SQL查詢?
- 它基於非常複雜的業務需求,在現階段無法改變。
- 數據庫架構無法更改或重新設計,因爲它被其他應用程序使用。
- 有50k產品和5k用戶(每個用戶可能有權訪問1到50k產品)。
爲了用於登錄的用戶顯示該產品頁面,我們使用:
SELECT TOP X * FROM [VIEW] WHERE UserID = @UserId -- where 'X' is the size of the page
上述查詢返回的最大的50行(最大頁面大小)。 WHERE子句將行數限制爲最大值50k(用戶有權訪問的產品)。 該頁面需要大約5到7秒的時間才能加載,這正是上面SQL查詢在SQL中運行的時間。 問題:
用戶到產品頁面,並極有可能使用分頁,重新排序結果,進入詳細信息頁面,等等,然後又回到了名單。每次需要5-7秒才能顯示結果。
這是不可接受的,但同時業務團隊已經接受,第一次加載產品頁面可能需要5-7秒。因此,我們想到了CACHING。
我們現在有兩個選項可供選擇,至少對我來說,最「顯而易見」的是使用.Net緩存(在內存中/在proc中)。 (請注意,由於我們的提供商/託管合作伙伴的技術限制,目前不允許使用分佈式緩存)。
但我對此不太舒服。我們最終會在內存中產生大量的產品(當有50或100個用戶同時登錄時),這可能會導致服務器上的其他問題,比如.Net不斷刪除緩存項目以釋放空間,同時我們的代碼插入新項目。
的第二選項:
這裏的主要問題是,它是非常昂貴的生成用戶X產品X訪問視圖,所以我們認爲我們可以創建一個平坦的桌面(或換句話說緩存所有產品x用戶在數據庫中)。該表格完全是該觀點的結果。 但是,如果添加新產品,更改用戶權限等,結果可能會隨時發生變化。因此,我們需要不斷刷新表格(可能需要幾秒鐘),這會變得有點複雜。同樣,我們雖然可以實現某種緩存提供程序,並且根據用戶的請求,我們將運行原始SQL查詢並從視圖中選擇產品(5-7s,只能接受一次)並保存導致SQL中一個名爲ProductUserAccessCache的平坦表。接下來的請求,我們會從這個緩存表中獲取值(因爲我們可以很容易地爲那個特定用戶確定緩存的結果),而不需要SQL中的計算。 每次添加產品或更改權限時,我們都會截斷緩存表,並在新的請求時爲請求的用戶重新填充表。 對我來說這似乎不太複雜,但我們在這裏所做的基本上是創建一個NEW緩存「提供者」。
- 有沒有人有這種問題的經驗?
- 使用.Net緩存(在proc中)會更好嗎?
- 有什麼建議嗎?
您使用的是ORM嗎? – pollirrata 2013-04-08 14:30:55
實體框架4 – AndreCruz 2013-04-08 14:32:34