Каков наилучший способ обновления накопительной таблицы под нагрузкой? - PullRequest
2 голосов
/ 31 января 2009

Я создал таблицу в своей базе данных SQL Server 2005 и заполнил ее сводными и расчетными значениями. Цель состоит в том, чтобы избежать обширных объединений и группировок при каждом обращении к базе данных. Я бы хотел, чтобы эта таблица обновлялась каждый час, но я не уверен, что это лучший способ сделать это, пока сайт загружен. Если я удалю каждую запись и повторно заполню таблицу в одной транзакции, это сработает или будут тупики и другие скрывающиеся проблемы?

Ответы [ 4 ]

5 голосов
/ 02 февраля 2009

Способ, которым я сделал это в нескольких проектах, состоит в том, чтобы использовать две копии таблицы в разных схемах. Так что-то вроде:

CREATE SCHEMA fake WITH AUTHORIZATION dbo;
CREATE SCHEMA standby WITH AUTHORIZATION dbo;
GO

CREATE TABLE dbo.mySummary(<...columns...>);

CREATE TABLE fake.mySummary(<...columns...>);
GO

Теперь создайте хранимую процедуру, которая усекает и повторно заполняет поддельную таблицу, а затем в транзакции перемещает объекты между схемами.

CREATE PROCEDURE dbo.SwapInSummary
AS
BEGIN
    SET NOCOUNT ON;

    TRUNCATE TABLE fake.mySummary;

    INSERT fake.mySummary(<...columns...>)
        SELECT <expensive query>;

    BEGIN TRANSACTION;
        ALTER SCHEMA standby TRANSFER dbo.mySummary;
        ALTER SCHEMA dbo     TRANSFER fake.mySummary;
        ALTER SCHEMA fake    TRANSFER standby.mySummary;
    COMMIT TRANSACTION;
END
GO

Это, вероятно, самый короткий промежуток времени, в течение которого вы можете заставить пользователей ждать обновления новых данных и не прерывать их во время чтения. (Есть много проблем, связанных с NOLOCK, которые делают его менее желательной альтернативой, хотя по общему признанию, это легко кодировать.) Для краткости / ясности я упустил обработку ошибок и т. Д., И я должен также отметить, что если вы используете скрипты для синхронизации ваших баз данных, убедитесь, что вы называете ограничения, индексы и т. д. одинаковыми для обеих таблиц, иначе вы будете не синхронизированы половину времени. В конце процедуры вы можете TRUNCATE новой таблицы fake.MySummary, но если у вас есть место, я бы хотел оставить данные там, чтобы я всегда мог сравнить их с предыдущей версией.

До SQL Server 2005 я использовал sp_rename внутри транзакции, чтобы выполнить то же самое, однако, так как я делаю это в работе, я был рад переключиться на схемы, потому что, когда я делал, предупреждение о невозможности подавления от sp_rename перестал заполнять мои журналы истории агента SQL Server.

1 голос
/ 01 февраля 2009

Вы также можете создать индексированное представление в зависимости от того, насколько велика ваша нагрузка, это может быть хорошим выбором.

0 голосов
/ 31 января 2009

Я решил собрать данные в табличной переменной @temp. Затем я скопирую идентификаторы накопления во временную таблицу, где они совпадают. Наконец, я буду добавлять, обновлять и удалять строки в сводной таблице на основе таблицы @temp.

0 голосов
/ 31 января 2009

Это зависит от отношений в вашей базе данных и запросов, которые вы выполняете к ней.

Если это сводная таблица, которая может переносить устаревшие данные, вы можете заполнить ее, используя запросы, которые выполняют свои SELECT без блокировок, используя подсказку соединения NOLOCK. ПРИМЕЧАНИЕ : использовать подсказку NOLOCK следует только тогда, когда вы уверены в последствиях.

Часто есть возможности для перенастройки индексов, чтобы уменьшить нагрузку.

...