Получение миллиардов строк с удаленного сервера? - PullRequest
7 голосов
/ 29 июля 2011

Я пытаюсь получить около 200 миллиардов строк с удаленного сервера SQL. Чтобы оптимизировать это, я ограничил свой запрос использованием только индексированного столбца в качестве фильтра и выбираю только подмножество столбцов, чтобы запрос выглядел следующим образом:

SELECT ColA, ColB, ColC FROM <Database> WHERE RecordDate BETWEEN '' AND ''

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

OLE DB provider "SQLNCLI10" for linked server "<>" returned message "Query timeout expired".
Msg 7399, Level 16, State 1, Server M<, Line 1
The OLE DB provider "SQLNCLI10" for linked server "<>" reported an error. Execution terminated by the provider because a resource limit was reached.
Msg 7421, Level 16, State 2, Server <>, Line 1
Cannot fetch the rowset from OLE DB provider "SQLNCLI10" for linked server "<>". 

Время ожидания, вероятно, является проблемой из-за времени, которое требуется для выполнения плана запроса. Поскольку у меня нет контроля над сервером, мне было интересно, есть ли хороший способ получения этих данных помимо простого SELECT, который я использую. Существуют ли какие-либо специальные приемы SQL Server, которые можно использовать? Возможно, сказать удаленному серверу разбивать данные на страницы вместо того, чтобы выдавать несколько запросов или что-то еще? Любые предложения о том, как я могу улучшить это?

Ответы [ 7 ]

13 голосов
/ 29 июля 2011

Это больше похоже на работу SSIS подходит для.Даже простой поток, такой как ReadFromOleDbSource-> WriteToOleDbSource, справится с этим, создав необходимую для вас пакетную обработку.

5 голосов
/ 29 июля 2011

Зачем читать сразу 200 миллиардов строк?

Вы должны их пейджировать, читая, скажем, несколько тысяч строк одновременно.

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

См. эффективный способ реализации подкачки дляпо крайней мере один метод реализации подкачки с использованием ROW_NUMBER

Если вы выполняете анализ данных, то я подозреваю, что вы используете не то хранилище (SQL Server на самом деле не предназначен для обработки больших наборов данных), иливам нужно изменить свои запросы, чтобы анализ выполнялся на сервере с использованием SQL.

Обновление: Я думаю, что последний абзац был несколько неверно истолкован.

Хранение в SQLСервер в первую очередь предназначен для онлайновой обработки транзакций (OLTP) - эффективного запроса больших массивов данных в среде с массовым параллелизмомNTS (например, чтение / обновление одной записи клиента в базе данных миллиардов, в то же время, что тысячи других пользователей делают то же самое для других записей).Обычно цель состоит в том, чтобы минимизировать количество прочитанных данных, уменьшить количество необходимых операций ввода-вывода и уменьшить количество конфликтов.

Анализ, о котором вы говорите, почти полная противоположность этому - single клиент активно пытается прочитать все записей для выполнения статистического анализа.

Да, SQL Server справится с этим, но вы должны иметь в виду, что он оптимизирован длясовершенно другой сценарий.Например, данные считываются с диска по странице (8 КБ) за раз, несмотря на то, что ваша статистическая обработка, вероятно, основана только на 2 или 3 столбцах.В зависимости от плотности строк и ширины столбца вы можете использовать только небольшую часть данных, хранящихся на странице размером 8 КБ - большинство данных, для которых SQL Server должен был считывать и выделять память, даже не использовалось.(Помните, что SQL Server также пришлось заблокировать эту страницу, чтобы другие пользователи не могли связываться с данными во время их чтения).

Если вы серьезно относитесь к обработке / анализу массивных наборов данных, то существуют форматы хранения, которыеоптимизированы именно для такого рода вещей - в SQL Server также имеется дополнительная служба, называемая Microsoft Analysis Services , которая добавляет дополнительные интерактивная аналитическая обработка (OLAP) и возможности интеллектуального анализа данных с использованием режимов хранения.больше подходит для такого рода обработки.

3 голосов
/ 29 июля 2011

Лично я бы использовал инструмент извлечения данных, такой как BCP, чтобы получить данные в локальный файл, прежде чем пытаться манипулировать им, если я пытался извлечь столько данных одновременно.

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

2 голосов
/ 29 июля 2011

Это не специфичный для SQL Server ответ, но даже когда реляционная СУБД поддерживает серверные курсоры, их использование считается плохой формой. Это означает, что вы потребляете ресурсы на сервере, хотя сервер все еще ожидает от вас запроса дополнительных данных.

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

1 голос
/ 06 декабря 2011

Просто столкнулся с той же проблемой, у меня тоже было сообщение в 10:01 после выполнения запроса.

Проверьте эту ссылку .В Connections есть настройка времени ожидания удаленного запроса, которая по умолчанию настроена на 600 секунд, и вам нужно изменить его на ноль (неограниченный) или другое значение, которое вы считаете правильным.

1 голос
/ 29 июля 2011

Вероятность того, что на удаленном сервере установлено «Тайм-аут удаленного запроса».Сколько времени требуется для сбоя запроса?

0 голосов
/ 12 августа 2015

Попробуйте изменить свойство тайм-аута подключения к удаленному серверу.

Для этого перейдите в SSMS, подключитесь к серверу, щелкните правой кнопкой мыши на имени сервера в проводнике объектов, далее выберите Properties -> Connections и измените значение в текстовом поле Remote query timeout (in seconds, 0 = no timeout).

enter image description here

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