#tsql #sql-server-2008-r2 #query-optimization #query-performance
#tsql #sql-server-2008-r2 #оптимизация запросов #запрос-производительность
Вопрос:
У нас проблема с выполнением запроса в SQL Server 2008 R2. Запрос объединяет таблицы из 2 баз данных, одна из которых является нашим хранилищем данных, получающим данные из системы iSeries, а другая — нашей основной системой отчетности.
В приведенном ниже запросе мы должны получить 90939 записей менее чем за 30 секунд. Если мы удалим столбец PO.POwner, результаты возвращаются примерно через 10 секунд.
Но когда мы добавляем po.Столбец POwner это убивает его.
SELECT cu.* ,C4.C4IND, cu.CUS_Citizenship as [Country of Incorporation],
cu.CUS_Nationality as [Residence Country],[FirstParticipantID]=ISNULL(po.POwner,cu.CUS_No)
-- , cu.CUS_No COLLATE Latin1_General_CS_AS, po.POwner COLLATE Latin1_General_CS_AS
FROM dbo.CustomerData cu
left outer join Hermes_Import.dbo.KFILDTO_C4PF C4
on cu.CUS_Type COLLATE Latin1_General_CS_AS =C4.C4CTP COLLATE Latin1_General_CS_AS
OUTER APPLY (
SELECT TOP 1
CASE WHEN GFCTP = 'GG' AND LEN(Y41SCV) > 5 THEN Y41SCV ELSE Y41CUS END AS 'POwner',
GFCTP
FROM Hermes_Import.dbo.KFILDTO_Y41PF
INNER JOIN Hermes_Import.dbo.KFILDTO_GFPF ON GFCUS = Y41CUS
WHERE Y41TYP IN ('BN', 'BB', 'CO') AND Y41DEL = 0 AND Y41DEC = 0
AND Y41CUS COLLATE Latin1_General_CS_AS = cu.CUS_No COLLATE Latin1_General_CS_AS
) po
WHERE Left(Cu.[Cus_No],1)< '8' AND (cu.[CUS_Type])<>'ZA' AND DataDate='2014-04-30' ORDER BY CUS_No
Вот план выполнения для этого (только ВЕРХНИЕ 3000 записей):
Когда мы извлекаем столбец основного владельца, мы получаем все результаты примерно за 11 секунд, и вот план выполнения:
Что мы можем сделать по-другому, чтобы получить основного владельца, учитывая, что нам нужна первая запись из 6 возможных участников в учетной записи клиента
Ответ №1:
Причина, по которой вы не получаете низкой производительности при комментировании po
полей, заключается в том, что OUTER APPLY / TOP 1
гарантированно будет получена ровно одна запись, несмотря ни на что.
Если вас не волнует содержимое этой записи, SQL Server
с тем же успехом можно оптимизировать все предложение, что оно и делает.
Создайте следующие индексы:
Hermes_Import.dbo.KFILDTO_Y41PF (Y41CUS, Y41DEL, Y41DEC, Y41TYP)
Hermes_Import.dbo.KFILDTO_GFPF (GFCUS)
Кроме того, вы используете TOP 1 без ORDER BY
вашего OUTER APPLY
. Вы уверены, что вам все равно, какую именно запись вы выбираете?
Комментарии:
1. Привет, спасибо, что посмотрели, но мы не можем создавать индексы для этих таблиц, поскольку это повлияло бы на ночной процесс обновления в Hermes_Import — мы помним о влиянии индексации таблицы на другие функции, которые могут использовать таблицы
2. кроме того, да, вы правы, мы добавим
ORDER BY
OUTER APPLY
предложение in после того, как найдем нашу проблему — мы склоняемся к тому, чтобы включить подмножество ссылочных таблиц в нашу систему отчетности, поскольку мы запускаем это только один раз в месяц для создания файлов отчетов BASEL.3. @Philip: как именно вы боитесь, что это повлияет на таблицы? Они такие большие и написаны так сильно? Без индекса вы не получите достойной производительности по этому запросу.
4. мы думаем о том, чтобы перенести нужное нам подмножество в базу данных отчетов с той же сортировкой, что и в базе данных отчетов, и в этой таблице мы будем использовать индексы — мы можем выполнить эту задачу с сохраненным процессом как часть обновления данных на конец месяца, чтобы сделать его доступным, когда нам нужноподготовьте файлы отчетов BASDEL…
5. мы также тестируем временную таблицу, индексы которой дают наилучшее улучшение производительности