Есть ли проблемы с производительностью при вставке в большую таблицу SQL Server, которая запрашивается? - PullRequest
1 голос
/ 06 марта 2012

Я использую SQL Server. Я получил большую таблицу - миллионы строк. И я перебираю их (SELECT .. WHERE ..). Это длинная операция (и я полагаю, она не может быть короче).

Итак, что я спрашиваю: возникнут ли какие-либо проблемы с insert данными into в этой таблице в процессе select ing? Если да, что я должен сделать, чтобы уменьшить это? Тот же квест для команды update (с индексированными параметрами, конечно).

Ответы [ 6 ]

2 голосов
/ 06 марта 2012

Да, у вас будут проблемы с производительностью, а точнее, с блокировками и блокировками. Если ваши операторы SELECT используют индексы, какими они и должны быть, эти индексы будут блокироваться каждый раз, когда вы INSERT данные добавляете в таблицу. Поскольку таблица относительно велика, блокировка, вероятно, будет достаточно длинной, чтобы блокировать ваши операторы SELECT, и вероятны также взаимные блокировки.

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

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

1 голос
/ 13 марта 2012

Ответ - да, абсолютно. Простое решение (если это приемлемый компромисс в вашем приложении) состоит в том, чтобы указать подсказку блокировки NOLOCK. IE:

выберите * из таблицы с NOLOCK

Компромисс в том, что вы не получите последовательное чтение, но во многих случаях это не проблема.

1 голос
/ 12 марта 2012

ПРОБЛЕМ нет.SQL Serve создан для решения подобных ситуаций, вам просто нужно установить правильный уровень изоляции для транзакций.

Существует несколько возможных сценариев, например, если вы не возражаете против чтения данных, которыевставляется, установите уровень изоляции для чтения незафиксированным в вашей транзакции чтения.Если вы вставляете значения в диапазон и считываете значения в другом диапазоне, вы можете использовать SERIALIZABLE.

Посмотрите на возможные уровни изоляции:

http://msdn.microsoft.com/en-us/library/ms173763.aspx
1 голос
/ 12 марта 2012

Складирование, согласно @Gisli, является хорошим вариантом: создайте копию данных в другом месте и выполняйте там свои долгосрочные запросы, освобождая «основную» базу данных для обработки OLTP.

Если это не вариант, вы можете возиться с изоляцией моментального снимка (что-то, о чем я знаю, но никогда не работал лично). По сути, это сделает «моментальный снимок» базы данных в тот момент, когда вы запускаете запрос, и выполнит запрос, как если бы в базу данных не было внесено никаких последующих изменений, , даже если изменения были внесены в базу данных во время запрос выполняется. Что еще более важно, любые такие изменения являются "реальными" и постоянными. Думайте об этом как о кратковременном ветвлении вашей базы данных.

Длительность ветви (снимок) - это то, где я становлюсь слабым. Я полагаю, что у вас может быть моментальный снимок последним на протяжении всего запроса, что означает, что вы (возможно) никогда не сможете получить одинаковые результаты для данного запроса дважды (если данные изменяются во время его выполнения); или вы можете создать «сохраненный» снимок, который можно использовать снова и снова, пока вы не сможете его удалить. Будьте осторожны с этим, вы не хотите, чтобы ваша система была загромождена старыми забытыми ветвями прошлых данных!

1 голос
/ 12 марта 2012

Не думайте, что время выполнения не может быть короче. Если вы запрашиваете диапазон дат, индекс по дате: must!
Решите вашу проблему с индексацией в поле date :

-- please use correct names for your_table and date_field --
CREATE INDEX index_name ON your_table date_field    
1 голос
/ 12 марта 2012

Как правило, не рекомендуется выполнять длительные запросы к базе данных с частыми обновлениями. Это значительно снижает производительность из-за блокировки.

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...