我最终创建了一个基本的通用框架,用于将 SQL 函数或视图的结果缓存到表中。
Public Sub CreateCacheTable(ByVal SourceView As String, ByVal FieldList As String)
Dim CacheTable As String = GetCacheTableName(SourceView)
If Not TableExists(CacheTable) Then
Dim Sql As String = " Select ~FieldList~ Into ~CacheTable~ From ~SourceView~ ". _
Replace("~CacheTable~", CacheTable). _
Replace("~FieldList~", FieldList). _
Replace("~SourceView~", SourceView)
ExecuteNonQuery(cs, CommandType.Text, Sql)
End If
End Sub
Public Function GetCacheTableName(ByVal SourceView As String)
Dim Result As String = "_c_~SourceView~". _
Replace("~SourceView~", SourceView). _
Replace(".", "_"). _
Replace(",", "_"). _
Replace("[", ""). _
Replace("]", ""). _
Replace("(", ""). _
Replace(")", "")
Return Result
End Function
Public Sub CleanupCacheTables()
ExecuteNonQuery(cs, CommandType.StoredProcedure, "CleanupCacheTables")
End Sub
当页面加载时,我会这样做:
CleanupCacheTables()
CreateCacheTable(SourceView, FieldList)
例如,如果 SourceView 是 DirectoryContactsByContact(123),则会创建一个名为 _c_DirectoryContactsByContact_123 的表。
这是CleanupCacheTables 的 SQL:
Create Procedure CleanupCacheTables as
/* Finds all tables starting with _c_ that were created more than 30 minutes ago and drops them */
Declare @TableName nvarchar(255)
Declare CacheTableCursor Cursor for
Select
TableName=name
From SYS.OBJECTS
Where Type_Desc = 'USER_TABLE'
And Left(name,3)= '_c_'
And DateDiff(minute, create_date, GetDate())>30
Open CacheTableCursor
Fetch Next from CacheTableCursor into @TableName
While @@FETCH_STATUS = 0 Begin
Exec ('Drop Table ' + @TableName)
Fetch Next from CacheTableCursor into @TableName
End -- While
Close CacheTableCursor
Deallocate CacheTableCursor
Go
这是粗略的:没有失效,它可能不会扩展到大量并发用户和/或非常大的数据集。尽管如此,在我的情况下,当用户键入或选择搜索条件时,它会产生近乎即时的结果,而且开销很小。