在SQL Server中缓存联接表
我的网站有一个搜索过程,运行非常缓慢。减慢速度的一件事是它必须执行的8表联接(它还有一个关于~6个搜索参数的在SQL Server中缓存联接表,sql,sql-server-2005,Sql,Sql Server 2005,我的网站有一个搜索过程,运行非常缓慢。减慢速度的一件事是它必须执行的8表联接(它还有一个关于~6个搜索参数的WHERE子句)。我曾尝试使用各种方法(如添加索引)加快查询速度,但这些方法都没有帮助 我的一个想法是缓存8表联接的结果。我可以创建联接的临时表,并使搜索过程查询该表。我可以每10分钟左右更新一次表 使用伪代码,我会将我的过程更改为如下所示: IF CachedTable is NULL or CachedTable is older than 10 minutes DROP TA
WHERE
子句)。我曾尝试使用各种方法(如添加索引)加快查询速度,但这些方法都没有帮助
我的一个想法是缓存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或可用选项了解不多。您可以使用多个模式(您应该始终指定模式!)并使用switch-a-roo,如中所示。基本上,您需要两个额外的模式(一个临时保存表的副本,另一个保存缓存的副本) 现在,在缓存模式中创建表的模拟:
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;
您需要为索引、约束等编写脚本。当您使用
SELECT-INTO
等时,它们不会免费随新表提供。谢谢,这看起来非常漂亮。目前我似乎没有使用模式(一切都只是dbo。[tableName])。您仍然应该在查询中指定dbo.CachedTable
,而不是CachedTable
——我现在已经可以使用了,非常好用,谢谢您的帮助。+1从未想过模式切换(我经常使用模式)。有关我建议使用同义词或ALTER TABLE开关的位置,请参见
-- 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;