2013-04-10 7 views
0

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

операции являются:

  • Фильтр из повторяющихся данных.
  • Соедините несколько таблиц, чтобы получить дополнительные данные
  • Вставьте в таблицу темп.

Вот запрос.

-- Get all Orders that aren't in the system 
WITH Orders AS 
(
    SELECT * 
    FROM [Staging].Orders o 
    WHERE NOT EXISTS 
    (
     SELECT 1 
     FROM Maps.VendorBOrders vbo 
     JOIN OrderFact of 
     ON of.Id = vbo.OrderFactId 
     AND InternalOrderId = o.InternalOrderId 
     AND of.DataSetId = o.DataSetId 
     AND of.IsDelete = 0 
    ) 
) 
INSERT INTO #VendorBOrders 
    (
     CustomerId 
    ,OrderId 
    ,OrderTypeId 
    ,TypeCode 
    ,LineNumber 
    ,FromDate 
    ,ThruDate 
    ,LineFromDate 
    ,LineThruDate 
    ,PlaceOfService 
    ,RevenueCode 
    ,BillingProviderId 
    ,Cost 
    ,AdjustmentTypeCode 
    ,PaymentDenialCode 
    ,EffectiveDate 
    ,IDRLoadDate 
    ,RelatedOrderId 
    ,DataSetId 
    ) 
SELECT 
    vc.CustomerId 
    ,OrderId 
    ,OrderTypeId 
    ,TypeCode 
    ,LineNumber 
    ,FromDate 
    ,ThruDate 
    ,LineFromDate 
    ,LineThruDate 
    ,PlaceOfService 
    ,RevenueCode 
    ,bp.Id 
    ,Cost 
    ,AdjustmentTypeCode 
    ,PaymentDenialCode 
    ,EffectiveDate 
    ,IDRLoadDate 
    ,ro.Id 
    ,o.DataSetId 
FROM 
Orders o 
-- Join related orders to match orders sharing same instance 
JOIN Maps.VendorBRelatedOrder ro 
ON ro.OrderControlNumber = o.OrderControlNumber 
AND ro.EquitableCustomerId = o.EquitableCustomerId 
AND ro.DataSetId = o.DataSetId 
JOIN BillingProvider bp 
ON bp.ProviderNPI = o.ProviderNPI 
-- Join on customers and fail if the customer doesn't exist 
LEFT OUTER JOIN [Maps].VendorBCustomer vc 
ON vc.ExtenalCustomerId = o.ExtenalCustomerId 
AND vc.VendorId = o.VendorId; 

Мне интересно, есть ли что-нибудь, что я могу сделать, чтобы оптимизировать его для времени. Я попытался использовать Tuner DB Engine, но этот запрос занимает 100 раз больше времени процессора, чем другие запросы, которые я запускаю. Есть ли что-нибудь еще, что я могу изучить, или может ли запрос не быть улучшен дальше?

+0

попробовать используя вложенный «CTE» для вычисления окончательных данных, которые необходимо вставить, и, наконец, сохранить простой «INSERT» –

ответ

1

КТР только синтаксис

что КТР оценивается (бег) на том, что присоединиться к

Сначала просто запустить его в качестве оператора выбора (без вставки)

Если выбрать медленно, то:
Move, что КТР к #TEMP поэтому вычисляется один раз и овеществленного
Put индекс (PK, если это применимо) на три колонки присоединиться

Если выбрать не замедлят то время вставки на #VendorBOrders
Кулака создать только PK и сортировку вставки на ПК, чтобы не распадаться, что кластерным индекс
Затем, после вставки завершения сборки любых других необходимых показателей

1

Обычно, когда я выполняю тестирование скорости, я выполняю проверки по части SQL, чтобы увидеть, где находится проблема. Включите «План выполнения» и посмотрите, куда идет много времени. Также, если вы хотите просто сделать быстрый и грязный, выделите CTE и запустите именно это. Это быстро, да, двигаться дальше.

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

Другая идея заключается в том, что если у вас есть быстрый tempdb в производственной среде или т. П., Сбросьте свой CTE в таблицу temp. Индекс на это и посмотреть, ускорит ли это что-то. Иногда CTE, табличные переменные и временные таблицы теряют некоторую производительность при подключении. Я обнаружил, что создание индекса на частичном объекте будет увеличивать производительность в разы, но вы также ставите большую нагрузку на tempdb для этого, поэтому имейте это в виду.

+0

Существуют ли какие-либо статьи по созданию оптимальных индексов? Я использую механизм настройки, чтобы предлагать индексы, но я начинаю думать, что это могло бы принести больше вреда, чем пользы. – Romoku

+0

Я слаб на знание TSQL индексов, если честно. Я считаю, что индексы замедляют производительность вставок, поэтому вы хотите использовать их экономно. Однако иногда с temp-таблицами я сделал это успешно: Вставить в #Object Выбрать * из объекта или Выбрать * в #Object из вещи THEN создать индекс.Таким образом, вы получаете скорость вставки без добавления индексов, а затем вы создаете полный индекс для всего в одном поле int. Я знаю, что много раз, когда у вас есть несколько секторов, соединяющихся там, часто может быть одна точка прерывания, которая является точкой затухания. – djangojazz

+0

Я не уверен, что это используется в дикой природе, но могу ли я просто отбросить индексы перед вставкой и добавить их обратно? Опять же, если эта вещь превратится в ТБ данных, которые, вероятно, не сработают. – Romoku

Смежные вопросы