Каковы "лучшие практики" для удаления "неуникальных" значений из таблицы HUGE? - PullRequest
2 голосов
/ 09 сентября 2010

Шаг 1: Загрузка данных через «массовую вставку» из файла .txt (с разделителями) в таблицу 1 (без индексов и т. Д.)

bulk insert Table_1
from '\\path\to_some_file.txt'
with ( tablock, FORMATFILE ='format_file_path.xml') 

Через файл формата я сопоставляю выходные данные типов столбцов, чтобы избежать дальнейшегопреобразования (например, из Char в Int)

Шаг 2: ВЫВОД результата (возможно, НЕ все столбцы из таблицы 1) в другую таблицу 2, но только значения DISTINCT из таблицы 1.

NB!Таблица_1 - это примерно 20 миллионов записей (на нагрузку).

то, что мы имеем сейчас (пример упрощен):

select distinct convert(int, col1), convert(int, col2), col3, ... 
into Table_2
from Table_1

Требуется около3,5 минуты для обработки.Не могли бы вы порекомендовать некоторые передовые методы, которые могут помочь сократить время обработки и поместить в таблицу только UNIQUE записи?

Заранее спасибо!

UPD 1 : извините за недоразумение - я имел в виду, что выберите отдельный запрос занимает 3,5 минуты.«массовая вставка» довольно оптимизирована - она ​​загружается через 8 потоков (8 отдельных файлов .txt), «массовая вставка» в 1 таблицу с помощью (TABLOCK) и импортирует 20 миллионов записей за 1 мин.

UPD 2: Я тестировал разные подходы (не тестировал на SSIS - в нашем приложении этот подход не сработает): лучший результат - это подход, когда данные "массово вставлены" в формат TABLE_2 (типы столбцов совпадают, типы данных)- также) поэтому мы исключаем тип данных Converts.И просто «простой» отчетливый:

select distinct * into Table_2 from Table_1

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

Спасибо всем за участие!

Ответы [ 5 ]

2 голосов
/ 09 сентября 2010

Вы должны знать, является ли ваша SELECT DISTINCT причиной проблемы или ваша INSERT INTO вызывает проблему.

Вам придется запускать SELECT DISTINCT один раз с, а один раз безINSERT INTO и измерьте длительность, чтобы определить, какой из них вам нужно настроить.

Если это ваш SELECT DISTINCT, вы можете попытаться настроить этот запрос, чтобы сделать его более эффективным.

Если этоэто ваш INSERT INTO, затем рассмотрите следующее:

С INSERT INTO создается новая таблица, и все страницы распределяются по мере необходимости.

Вы удаляете старую таблицу и создаетеновенький?Если это так, вы должны изменить это на просто УДАЛИТЬ из старой таблицы - УДАЛИТЬ, не Усечение - это потому, что усечение отпустит все страницы, полученные таблицей, и они должны быть повторновыделенный.

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

  1. Попросите вашего клиента о неповторяющихся данных
    • Индекс по всемСтолбцы с повторяющимися критериями.Сканирование индекса должно выполняться намного быстрее, чем сканирование таблицы.
    • Разделение вашей промежуточной таблицы для повышения производительности
    • Создайте представление, которое выбирает различные значения, и используйте BCP для быстрой загрузки данных.
1 голос
/ 09 сентября 2010

найти дубликаты, затем удалить, затем скопировать в таблицу2.

Найдите дубликаты вот так

SELECT col1, 
COUNT(col1) AS NumOccurrences
FROM table1
GROUP BY col1
HAVING ( COUNT(col1) > 1 )
0 голосов
/ 10 сентября 2010

Ваши операторы CONVERT могут быть причиной задержки.

0 голосов
/ 09 сентября 2010

Вот что такое SSIS, чувак.:)

[Обновить]

Попробуйте это в SSIS, чтобы увидеть, как быстро вы можете прожевать эти данные:

Источник плоского файла ->Компонент сортировки с удалением дубликатов -> Назначение плоских файлов (или назначение Ole Db с табло и прочее)

0 голосов
/ 09 сентября 2010

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

...