Какой самый быстрый способ выбрать всю таблицу в SQL Server? - PullRequest
6 голосов
/ 10 марта 2011

Я пишу приложение, которое читает всю таблицу, выполняет некоторую обработку, а затем записывает полученные данные в другую таблицу. Я использую класс SqlBulkCopy (версия .net "bcp in"), который делает вставку очень быстро. Но я не могу найти какой-либо эффективный способ выбора данных в первую очередь. нет .net, эквивалентного «bcp out», что мне кажется странным.

В настоящее время я использую select * from table_name. Для предварительного просмотра требуется 6000 секунд, чтобы выбрать 6000 строк ... и только 600 мс для массовой вставки того же количества строк.

Я ожидаю, что выбор данных всегда должен быть быстрее, чем вставка. Какой самый быстрый способ выбрать все строки и столбцы из таблицы?


Ответы на вопросы:

  • Я рассчитал, что мой выбор займет 2,5 секунды 2 способами. Первый был во время работы моего приложения и трассировки SQL. второй выполнял тот же запрос в SSMS. Оба восстановили примерно одинаковый результат.
  • Я читаю данные, используя SqlDataReader.
  • Другие приложения не используют эту базу данных.
  • Моя текущая обработка занимает менее 1 секунды, поэтому время чтения более 2 секунд относительно велико. Но в основном меня беспокоит производительность при масштабировании до 100 000 строк и миллионов строк.
  • Sql Server 08r2 и мое приложение работают на моем компьютере разработчика.
  • Часть обработки данных основана на базе, поэтому мне нужно иметь всю таблицу в памяти (для поддержки гораздо больших наборов данных, я знаю, что этот шаг, вероятно, нужно будет перенести в SQL, поэтому мне нужно работать только с каждой строкой в память)

Вот мой код:

DataTable staging = new DataTable();
using (SqlConnection dwConn = (SqlConnection)SqlConnectionManager.Instance.GetDefaultConnection())
{
    dwConn.Open();
    SqlCommand cmd = dwConn.CreateCommand();
    cmd.CommandText = "select * from staging_table";

    SqlDataReader reader = cmd.ExecuteReader();
    staging.Load(reader);
}

Ответы [ 3 ]

11 голосов
/ 10 марта 2011

select * from table_name - это самый простой, простой и быстрый способ чтения всей таблицы.

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

  1. Копирование всей таблицы - это оптимизированная операция, которая просто требует клонирования старых двоичных данных в новые (в большинстве случаев вы можете выполнить операцию копирования файла в соответствии с механизмом хранения).
  2. Запись буферизована .СУБД говорит, что запись была написана, но на самом деле это еще не сделано, если вы не работаете с транзакциями.Дисковые операции обычно задерживаются.
  3. Для запроса таблицы также требуется (в отличие от клонирования) адаптация данных из макета / формата, хранящегося в двоичном формате, в формат, зависящий от драйвера, который в конечном итоге читается вашим клиентом.Это требует времени.
2 голосов
/ 10 марта 2011

Все зависит от вашего оборудования, но, скорее всего, ваша сеть является узким местом.

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

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

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

Если логика, которую вы пишете, не может быть реализована в T-SQL, вы также можете взглянуть на SQL CLR.

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

ГДж

1 голос
/ 10 марта 2011

Обычно рекомендуется включать имена столбцов в список выбора, но с современными СУБД это не будет иметь большого значения. Вы увидите разницу в этом отношении, только если ограничите количество выбранных столбцов. Вообще говоря, хорошей практикой является включение имен столбцов. Но для ответа кажется, что выбор действительно медленнее, чем вставка в сценарий, который вы описываете и да, select * from table_name действительно самый быстрый способ прочитать все строки и столбцы из таблицы

...