SQL Server 2008 и ключевые слова "with" и "unpivot" - PullRequest
1 голос
/ 01 сентября 2011

Мы работаем с некоторыми очень большими базами данных (300Gb - 1Tb). Таблицы могут содержать от 10M до 5B записей. Мы выполняем не очень сложное преобразование данных с использованием операторов with и unpivot. Проблема в том, что файл журнала данных и база данных tempdb увеличиваются в размере, и в итоге сервер перестает работать.

Теперь я склоняюсь к мысли, что конструкции with и даже unpivot стоят дорого с точки зрения использования ресурсов, и здесь мы должны рассмотреть некоторые упрощения:

  • разбиение на несколько шагов с временными таблицами вместо использования with
  • с использованием union вместо unpivot

У кого-нибудь есть такой опыт?

Ответы [ 2 ]

0 голосов
/ 08 января 2012

Искреннее спасибо всем.Теперь для меня совершенно очевидно, что это было злоупотребление UNPIVOT.В самом деле, CTE - это просто представления, поэтому они не причинят особого вреда, если вы не используете их ненадлежащим образом.

Итак, основной нашей проблемой было то, что наш сервер (32 ГБ ОЗУ, 8 ЦП, 2 ТБ HDD) был простоне в состоянии управлять большим количеством записей, созданных UNPIVOT.

Допустим, у нас есть HugeTable с полями (F1, F2, F3, F4, F5, F6).RecordCount = 1 000 000 000

Мы используем его следующим образом (псевдокод):

with tmp as (select unpivot HugeTable)
select * from tmp
join ...
where FX is not null
and ...

План запроса оценивает, что наш UNPIVOT создает 6 000 000 000 записей для обработки нашим предложением where.Еще хуже становится то, что в действительности мы объединяем некоторые дополнительные таблицы и выполняем дополнительную фильтрацию.Все это происходит 6 миллиардов раз.Журнал транзакций и база данных tempdb были все еще нетронуты - довольно маленькие.Я не нашел никакой информации о том, что UNPIVOT / JOINS (хеш-соединения, которые нужно прецизировать) использует оперативную память только для управления своими операциями, но из того, что мы поняли, я понимаю, что наш SQL Server 2008 R2 Enterprise просто пытался разместить этот объемный набор записей в оперативной памяти, нопоскольку у нас не было 1 ТБ ОЗУ, операционная система выполняла огромные операции подкачки.

Интересно то, что она может запускаться очень быстро и обрабатывать около 1 800 000 000 записей в течение первых 6 часов, но затем зависает (хорошо, он генерирует 100 тыс. записей в сутки, что совершенно неприемлемо)

Если мы превратим его в руководство UNION ALL, вот так:

with tmp as (
  select F1 from HugeTable where F1 is not null
  union all select F2 from HugeTable where F2 is not null
  union all select F3 from HugeTable where F3 is not null
  union all select F4 from HugeTable where F4 is not null
  union all select F5 from HugeTable where F5 is not null
  union all select F6 from HugeTable where F6 is not null
)
select ... from tmp
join ...
where ...

план запроса показал, что CTE выдал около2 миллиарда записей.Таким образом, все дальнейшие объединения должны были выполняться с гораздо меньшим набором записей, чем в первом случае.На выполнение этой работы ушло менее 10 часов (против дней в первом случае).

Кстати, мы используем среду SSIS / VS2008 для обработки наших загрузок данных.

0 голосов
/ 26 ноября 2011

UNION намного быстрее, чем UNPivot, также вы можете периодически удалять файл журнала программно, если вам это не нужно часто. Производительность PIVOT также увеличится, если вы не используете соединение (в критериях выбора), вместо этого вы можете использовать объединение. эти ссылки помогут (особенно вторая ссылка: http://www.sql -server-performance.com / 2007 / SSIS-поворотный UNPIVOT / http://www.cs.toronto.edu/vldb04/protected/eProceedings/contents/pdf/IND1P2.PDF http://www.fotia.co.uk/fotia/DY.17.TheUnpivotOperator.aspx береги себя:)

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