2012-02-13 66 views
2

我的網站的搜索過程非常緩慢。減慢它的一件事是它必須做的8表連接(它在〜6個搜索參數上也有一個WHERE子句)。我試圖使用各種方法(如添加索引)來加快查詢速度,但這些都沒有幫助。在SQL Server中緩存連接表

我的一個想法是緩存8表連接的結果。我可以創建一個臨時的連接表,並讓搜索過程查詢這個表。我可以每10分鐘左右更新一次表格。

使用僞代碼,我會改變我的過程是這樣的:

IF CachedTable is NULL or CachedTable is older than 10 minutes 
    DROP TABLE CachedTable 
    CREATE TABLE CachedTable as (select * from .....) 
ENDIF 

Select * from CachedTable Where Name = @SearchName 
          AND EmailAddress = @SearchEmailAddress 

這是一個工作的策略?我真的不知道我需要什麼語法來解決這個問題,或者我需要鎖定什麼,以防止同時發生兩個查詢時發生中斷。

而且,這可能需要相當長的時間,使一個新的CachedTable每一次,所以我想嘗試在計算機圖形類似雙緩衝:

IF CachedTabled is NULL 
    CREATE TABLE CachedTable as (select * from ...) 
ELSE IF CachedTable is older than 10 minutes 
    -- Somehow do this asynchronously, so that the next time a search comes 
    -- through the new table is used? 
    ASYNCHRONOUS (
     CREATE TABLE BufferedCachedTable as (select * from ...) 
     DROP TABLE CachedTable 
     RENAME TABLE BufferedCachedTable as CachedTable 
    ) 

Select * from CachedTable Where Name = @SearchName 
          AND EmailAddress = @SearchEmailAddress 

這是否任何意義?如果是這樣,我將如何實現它?如果不是,我該怎麼做呢?我嘗試使用索引視圖,但這導致了奇怪的錯誤,所以我想要這樣的東西,我可以有更多的控制權(另外,我可能會在未來轉移到另一臺服務器上)。

此外,如何創建像這樣的表的索引等?

這可能是顯而易見的問題,但我不太瞭解SQL或可用選項。

+0

你需要腳本索引,約束等等。當你使用'SELECT INTO'時,它們不會隨着新表的免費提供。 – 2012-02-13 17:23:11

回答

5

您可以使用多個模式(您應該始終指定模式!)並播放switch-a-roo,如我在this question中演示的那樣。基本上你需要兩個額外的模式(一個臨時保存表副本,一個保存緩存副本)。

CREATE SCHEMA cache AUTHORIZATION dbo; 
CREATE SCHEMA hold AUTHORIZATION dbo; 

如今,在高速緩存架構創建一個模擬表:

SELECT * INTO cache.CachedTable FROM dbo.CachedTable WHERE 1 = 0; 
-- then create any indexes etc. 

現在,當談到時間刷新數據:

-- step 1: 
TRUNCATE TABLE cache.CachedTable; 
-- (if you need to maintain FKs you may need to delete) 
INSERT INTO cache.CachedTable SELECT ... 

-- step 2: 
-- this transaction will be almost instantaneous, 
-- since it is a metadata operation only: 

BEGIN TRANSACTION; 
    ALTER SCHEMA hold TRANSFER dbo.Cachedtable; 
    ALTER SCHEMA dbo TRANSFER cache.CachedTable; 
    ALTER SCHEMA cache TRANSFER hold.CachedTable; 
COMMIT TRANSACTION; 
+0

謝謝,這看起來很漂亮。我目前似乎沒有使用模式(一切都只是dbo。[tableName])。 – Oliver 2012-02-13 17:24:16

+0

您應該仍然在查詢中指定'dbo.CachedTable',而不是'CachedTable' - http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/11/bad-habits-to-kick-avoiding- the-schema-prefix.aspx – 2012-02-13 17:25:23

+0

我現在有這個工作,它工作得很好,謝謝你的幫助。 – Oliver 2012-02-15 13:24:06