Кэширование объединенных таблиц в SQL Server - PullRequest
2 голосов
/ 13 февраля 2012

Мой сайт имеет процедуру поиска, которая работает очень медленно. Одна вещь, которая замедляет его, это объединение 8 таблиц, которое оно должно сделать (у него также есть предложение WHERE для ~ 6 параметров поиска). Я пытался ускорить запрос, используя различные методы, такие как добавление индексов, но они не помогли.

Одна идея, которая у меня есть, - кэшировать результат соединения 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 или опциях, которые у меня есть.

1 Ответ

5 голосов
/ 13 февраля 2012

Вы можете использовать несколько схем (вы всегда должны указывать схему!) И играть в switch-a-roo, как я продемонстрировал в этот вопрос .В основном вам нужны две дополнительные схемы (одна для временного хранения копии таблицы, а другая для хранения кэшированной копии).

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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...