Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/82.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在SQL Server中缓存联接表_Sql_Sql Server 2005 - Fatal编程技术网

在SQL Server中缓存联接表

在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

我的网站有一个搜索过程,运行非常缓慢。减慢速度的一件事是它必须执行的8表联接(它还有一个关于~6个搜索参数的
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;