Вопрос

Я хочу как можно лучше переключиться на таблицы.
У меня есть таблица IpToCountry, и я создаю новую еженедельно в соответствии с внешним файлом CSV, который я импортирую.

Самый быстрый способ, который я нашел для переключения, заключался в следующем:

sp_rename IpToCountry IpToCountryOld
go
sp_rename IpToCountryNew IpToCountry
go

Проблема в том, что между ними все еще может быть доступен доступ к таблице.
Как мне подойти к этой проблеме в SQL?
Рассматривается возможность использования sp_getapplock и sp_releaseapplock, но я хочу, чтобы чтение из функции таблицы выполнялось как можно быстрее.

Это было полезно?

Решение

Предполагая, что вы не можете обновить/вставить существующую таблицу, почему бы вам не обернуть весь доступ к таблице с помощью вид?

Например, вы можете изначально хранить свои данные в таблице с именем IPToCountry20090303, и ваше представление будет примерно таким:

CREATE VIEW IpToCountry
AS
SELECT * FROM IpToCountry20090303

Когда поступают новые данные, вы можете создать и заполнить IPToCountry20090310 стол.Как только таблица будет заполнена, просто обновите свое представление:

ALTER VIEW IpToCountry
AS
SELECT * FROM IpToCountry20090310

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

Другие советы

Другим методом реализации того, чего вы хотите достичь, является использование секционирования таблиц — метода, доступного в Enterprise Edition SQL Server.

Имя таблицы может остаться прежним.После завершения импорта таблицы вы просто выключаете раздел, содержащий ваши старые данные, и включаете новый раздел.

Следующий технический документ содержит всю информацию, необходимую для начала работы.

http://msdn.microsoft.com/en-us/library/ms345146.aspx

Приветствую, Джон

У меня были проблемы с работой функций секционирования в большом масштабе.CREATE и DROP PARTITION являются блокирующими операциями, и у вас мало контроля над блокировкой, и если он не может получить блокировку, он завершится сбоем с уровнем серьезности 16 и разорвет ваше соединение, которое вы не можете перехватить и повторить без повторного установления. связь.Но это может сработать для вас.Кроме того, требуется MSS Enterprise Edition, вы не можете использовать SE - это может быть слишком много для некоторых небольших или более экономичных магазинов.

Я также обнаружил, что переопределение представления блокируется в крупном масштабе (= объем транзакции + чистый объем постоянно вставляемых данных, в моем случае) для системных таблиц и объектов, поэтому эти операции могут зайти в тупик в таких вещах, как переиндексация и DTCC - и в одном случае, в частности, с пользователем в SSMS (из всех вещей), пытающимся просмотреть представления в обозревателе объектов (кто-то должен рассказать этим ребятам о READPAST).Опять же, ваш пробег может отличаться.

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

DECLARE @dummylock bit 
BEGIN TRANSACTION 
BEGIN TRY
   -- necessary to obtain exclusive lock on the table prior to swapping
   SELECT @dummylock = 1 WHERE EXISTS (SELECT 1 FROM A WITH (TABLOCKX))
   -- may or may not be necessary in your case
   SELECT @dummylock = 1 WHERE EXISTS (SELECT 1 FROM B WITH (TABLOCKX))
   exec sp_rename 'A', 'TEMP'
   exec sp_rename 'B', 'A'
   exec sp_rename 'TEMP', 'B'
   COMMIT TRANSACTION
END TRY
BEGIN CATCH
   -- other error handling here if needed
   ROLLBACK TRANSACTION 
END CATCH

Что происходит с IpToCountryOld?Вы его выбрасываете?В этом случае почему бы не обрезать IpToCountry и не импортировать мои новые данные.

Если вам нужно сохранить данные, как насчет сохранения даты загрузки в таблице и сохранения «текущей» даты загрузки где-нибудь для использования в предложении WHERE?Затем вы переключаете текущую дату, когда данные успешно загружены.

Вы не говорите, какую БД вы используете, поэтому я не знаю, насколько это полезно, но есть ли у вас какие-либо хранимые процедуры, ссылающиеся на таблицу?Имейте в виду, что на некоторых платформах SP компилируются с использованием внутренних ссылок на таблицы, которые не изменяются при переименовании, поэтому существует риск, что SP не воспользуется вашими новыми данными без перекомпиляции.То же самое может быть справедливо для представлений и сохраненных анализируемых запросов.

Нельзя ли сделать импорт в один стол в нерабочее время?

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

Какова структура импортируемых данных, дизайн таблицы, формат, ПК и т. д.?Благодаря этому мы сможем дать вам лучший ответ.

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

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

Хранимая процедура может дополнительно создать новую таблицу(и) или вернуть старые таблицы в зависимости от предоставленных параметров.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top