Подтвердить что ты не робот

Обмен таблицами ms-sql

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

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

sp_rename IpToCountry IpToCountryOld
go
sp_rename IpToCountryNew IpToCountry
go

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

4b9b3361

Ответ 1

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

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

CREATE VIEW IpToCountry
AS
SELECT * FROM IpToCountry20090303

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

ALTER VIEW IpToCountry
AS
SELECT * FROM IpToCountry20090310

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

Ответ 2

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

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

В следующей Белой книге содержится вся информация, которую вам нужно будет приступить к работе.

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

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

Ответ 3

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

Я также обнаружил, что redef для просмотра блокируется на высоком уровне (= объем транзакции + чистый объем постоянно вставленных данных, в моем случае) на sys-таблицы и объекты, поэтому эти операции могут заходить в тупик по таким вещам, как переиндексация и 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

Ответ 4

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

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

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

Ответ 5

Можете ли вы не выполнять импорт в одну таблицу в нерабочее время?

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

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

Ответ 6

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

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

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