2

讓我從描述場景開始。我有一個使用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中)會更好嗎?
  • 有什麼建議嗎?
+1

您使用的是ORM嗎? – pollirrata 2013-04-08 14:30:55

+0

實體框架4 – AndreCruz 2013-04-08 14:32:34

回答

1

我們在前段時間面臨類似的問題,我們正在考慮使用EF緩存以避免延遲取回信息。我們的問題是1 - 2秒。延遲。 Here是一些可能有助於如何緩存擴展EF表的信息。高速緩存的一個缺點是您需要的信息有多新,所以您可以相應地設置高速緩存到期。根據截止日期的不同,用戶可能需要等待以獲取最新信息,但如果用戶能夠接受他們正在遷移的信息,以避免延遲,那麼權衡是值得的。

在我們的場景中,我們決定更好地獲得最新的信息,但如前所述,我們的等待時間並不長。

希望它有幫助

+0

我不知道這一個。它看起來非常強大,我會調查它。儘管我認爲它不會涵蓋我所有的需求,但從價格上看,值得一試.tx – AndreCruz 2013-04-08 14:57:01