2016-03-02 3 views
0

У меня странная проблема с некоторыми внутренними соединениями на моем SQL-сервере. Это очень медленно, хотя все столбцы, которые используются во внутренних соединениях и в предложении where, имеют индексы.SQL-запрос очень медленный, хотя индекс индексирован

Вот мой запрос SQL:

SELECT p.VORNA AS firstName, 
     p.NACHN AS lastName, 
     p.USRID AS [user], 
     o.ORGEH AS OUID, 
     o.STEXT AS OU, 
     a.HolidayDate AS absentFrom, 
     a.HolidayDate AS absentUntil, 
     k.MessageDate AS actionDate, 
     'holiday' AS reason 
FROM Kondor_User_Activities AS k 
INNER JOIN dbo.SAP_Personaldaten AS p ON p.USRID = k.Code 
INNER JOIN Kondor_Users u ON u.Users_Id = k.Users_Id 
INNER JOIN SAP_OE AS o ON p.ORGEH = o.ORGEH 
INNER JOIN Kondor_UsersGrp AS g ON g.UsersGrp_Id = u.UsersGrp_Id 
INNER JOIN Kondor_Cities AS c ON c.Cities_Id = u.Cities_Id OR (u.Cities_Id IS NULL AND c.Cities_Id = g.Cities_Id) 
INNER JOIN Kondor_FixedHolidays AS a ON k.MessageDate >= a.HolidayDate 
    AND k.MessageDate < a.HolidayDateEnd 
    AND a.Cities_Id = c.Cities_Id 
--WHERE g.UsersGrp_ShortName NOT LIKE 'UA_%' 
WHERE (g.UsersGrp_ShortName < 'UA_' OR g.UsersGrp_ShortName >= 'UA`') 

А вот мой план выполнения:

|--Compute Scalar(DEFINE:([Expr1018]='holiday')) 
    |--Nested Loops(Inner Join, WHERE:([RevisionReport].[dbo].[Kondor_FixedHolidays].[Cities_Id] as [a].[Cities_Id]=[RevisionReport].[dbo].[Kondor_Cities].[Cities_Id] as [c].[Cities_Id] AND [RevisionReport].[dbo].[Kondor_User_Activities].[MessageDate] as [k].[MessageDate]>=[RevisionReport].[dbo].[Kondor_FixedHolidays].[HolidayDate] as [a].[HolidayDate] AND [RevisionReport].[dbo].[Kondor_User_Activities].[MessageDate] as [k].[MessageDate]<[RevisionReport].[dbo].[Kondor_FixedHolidays].[HolidayDateEnd] as [a].[HolidayDateEnd])) 
     |--Parallelism(Gather Streams) 
     | |--Hash Match(Inner Join, HASH:([o].[ORGEH])=([p].[ORGEH]), RESIDUAL:([RevisionReport].[dbo].[SAP_Personaldaten].[ORGEH] as [p].[ORGEH]=[RevisionReport].[dbo].[SAP_OE].[ORGEH] as [o].[ORGEH])) 
     |   |--Bitmap(HASH:([o].[ORGEH]), DEFINE:([Bitmap1025])) 
     |   | |--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([o].[ORGEH])) 
     |   |   |--Table Scan(OBJECT:([RevisionReport].[dbo].[SAP_OE] AS [o])) 
     |   |--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([p].[ORGEH]), WHERE:(PROBE([Bitmap1025])=TRUE)) 
     |    |--Hash Match(Inner Join, HASH:([Expr1019])=([p].[USRID]), RESIDUAL:([RevisionReport].[dbo].[SAP_Personaldaten].[USRID] as [p].[USRID]=[Expr1019])) 
     |     |--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([Expr1019])) 
     |     | |--Compute Scalar(DEFINE:([Expr1019]=CONVERT_IMPLICIT(nvarchar(25),[RevisionReport].[dbo].[Kondor_User_Activities].[Code] as [k].[Code],0))) 
     |     |   |--Nested Loops(Inner Join, OUTER REFERENCES:([Bmk1000], [Expr1024]) WITH UNORDERED PREFETCH) 
     |     |    |--Nested Loops(Inner Join, OUTER REFERENCES:([u].[Users_Id]) OPTIMIZED) 
     |     |    | |--Nested Loops(Inner Join, WHERE:([RevisionReport].[dbo].[Kondor_Cities].[Cities_Id] as [c].[Cities_Id]=[RevisionReport].[dbo].[Kondor_Users].[Cities_Id] as [u].[Cities_Id] OR [RevisionReport].[dbo].[Kondor_Users].[Cities_Id] as [u].[Cities_Id] IS NULL AND [RevisionReport].[dbo].[Kondor_Cities].[Cities_Id] as [c].[Cities_Id]=[RevisionReport].[dbo].[Kondor_UsersGrp].[Cities_Id] as [g].[Cities_Id])) 
     |     |    | | |--Nested Loops(Inner Join, OUTER REFERENCES:([u].[UsersGrp_Id])) 
     |     |    | | | |--Clustered Index Scan(OBJECT:([RevisionReport].[dbo].[Kondor_Users].[PK_Kondor_Users] AS [u]), ORDERED FORWARD) 
     |     |    | | | |--Clustered Index Seek(OBJECT:([RevisionReport].[dbo].[Kondor_UsersGrp].[PK_Kondor_UsersGrp] AS [g]), SEEK:([g].[UsersGrp_Id]=[RevisionReport].[dbo].[Kondor_Users].[UsersGrp_Id] as [u].[UsersGrp_Id]), WHERE:([RevisionReport].[dbo].[Kondor_UsersGrp].[UsersGrp_ShortName] as [g].[UsersGrp_ShortName]<'UA_' OR [RevisionReport].[dbo].[Kondor_UsersGrp].[UsersGrp_ShortName] as [g].[UsersGrp_ShortName]>='UA`') ORDERED FORWARD) 
     |     |    | | |--Table Spool 
     |     |    | |   |--Index Scan(OBJECT:([RevisionReport].[dbo].[Kondor_Cities].[IX_Kondor_Cities_Countries_Id] AS [c])) 
     |     |    | |--Index Seek(OBJECT:([RevisionReport].[dbo].[Kondor_User_Activities].[IX_Kondor_User_Activities_Users_Id] AS [k]), SEEK:([k].[Users_Id]=[RevisionReport].[dbo].[Kondor_Users].[Users_Id] as [u].[Users_Id]) ORDERED FORWARD) 
     |     |    |--RID Lookup(OBJECT:([RevisionReport].[dbo].[Kondor_User_Activities] AS [k]), SEEK:([Bmk1000]=[Bmk1000]) LOOKUP ORDERED FORWARD) 
     |     |--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([p].[USRID])) 
     |      |--Table Scan(OBJECT:([RevisionReport].[dbo].[SAP_Personaldaten] AS [p])) 
     |--Table Scan(OBJECT:([RevisionReport].[dbo].[Kondor_FixedHolidays] AS [a])) 

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

Большое спасибо!

Таблица размеров:

Kondor_FixedHolidays:   14,416 rows 
SAP_Personaldaten:   13,001 rows 
Kondor_User_Activities: 7,247,086 rows 

Вот мой план выполнения, тоже, и я думаю, что ошибка в Kondor_Users_Activities таблице, хотя у меня есть два индекса там. Может быть, кластеризованный индекс будет полезен там вместо некластеризованного индекса?

Query Plan

RID Lookup Properties

+1

Используемый индекс, вы можете вставить план выполнения – TheGameiswar

+1

Не могли бы вы добавить визуальный план? Легче читать. –

+0

У вас есть индексы на kondor_fixedholidays messagedate? – BugFinder

ответ

0

Попробуйте один -

CREATE NONCLUSTERED INDEX ix1 
ON dbo.Kondor_User_Activities (Code, Users_Id, MessageDate) 
GO 

SELECT p.VORNA AS firstName, 
     p.NACHN AS lastName, 
     p.USRID AS [USER], 
     o.ORGEH AS OUID, 
     o.STEXT AS OU, 
     a.HolidayDate AS absentFrom, 
     a.HolidayDateEnd AS absentUntil, 
     k.MessageDate AS actionDate, 
     'holiday' as reason 
FROM dbo.Kondor_User_Activities k 
JOIN dbo.SAP_Personaldaten p ON p.USRID = k.Code 
JOIN dbo.SAP_OE o ON p.ORGEH = o.ORGEH 
JOIN dbo.Kondor_Users u ON u.Users_Id = k.Users_Id 
JOIN dbo.Kondor_UsersGrp g ON g.UsersGrp_Id = u.UsersGrp_Id 
JOIN dbo.Kondor_FixedHolidays a ON k.MessageDate >= a.HolidayDate AND k.MessageDate < a.HolidayDateEnd AND a.Cities_Id = g.Cities_Id 
WHERE (g.UsersGrp_ShortName < 'UA_' OR g.UsersGrp_ShortName >= 'UA`') 
    AND EXISTS(
     SELECT 1 
     FROM Kondor_Cities c 
     WHERE c.Cities_Id IN (u.Cities_Id, g.Cities_Id) 
     --WHERE c.Cities_Id = ISNULL(u.Cities_Id, g.Cities_Id) 
    ) 
+0

Спасибо за все ваши подсказки и выбор, но он по-прежнему выводит строки. Как только у меня будет план выполнения, я отправлю его. Мой SELECT по-прежнему работает, поэтому он может занять немного больше времени. – user3003944

+0

@ user3003944 просто добавьте 'ix1', чтобы избежать' RID Lookup' – Devart

0

Я подозреваю, что большая часть замедления происходит от этого соединения INNER JOIN Kondor_Cities AS c ON c.Cities_Id = u.Cities_Id OR (u.Cities_Id IS NULL AND c.Cities_Id = g.Cities_Id). SqlServer не подходит для оптимизации предикатов OR.

Попробуйте вместо этого:

SELECT p.VORNA AS firstName, 
     p.NACHN AS lastName, 
     p.USRID AS [USER], 
     o.ORGEH AS OUID, 
     o.STEXT AS OU, 
     x.HolidayDate AS absentFrom, 
     x.HolidayDate AS absentUntil, 
     k.MessageDate AS actionDate, 
     'holiday' as reason 
FROM  Kondor_User_Activities AS k 
     INNER JOIN dbo.SAP_Personaldaten AS p ON p.USRID = k.Code 
     INNER JOIN Kondor_Users u ON u.Users_Id = k.Users_Id 
      INNER JOIN SAP_OE AS o ON p.ORGEH = o.ORGEH 
      INNER JOIN Kondor_UsersGrp AS g ON g.UsersGrp_Id = u.UsersGrp_Id 
       INNER JOIN (
        SELECT DISTINCT a.HolidayDate, a.HolidayDateEnd, a.Cities_Id 
        FROM Kondor_FixedHolidays AS a 
      ) x ON k.MessageDate >= x.HolidayDate and k.MessageDate < x.HolidayDateEnd AND x.Cities_Id IN (u.Cities_Id,g.Cities_Id) 
WHERE (g.UsersGrp_ShortName < 'UA_' OR g.UsersGrp_ShortName >= 'UA`') 
+0

Привет, я не могу выполнить ваш sql из-за некоторого псевдонима, который не работает: Msg 4104, Level 16, State 1, Line 1 Идентификатор с несколькими частями "x .Cities_Id "не может быть привязан. Msg 4104, уровень 16, состояние 1, строка 1 Идентификатор с несколькими частями "u.Cities_Id" не может быть связан. Msg 4104, уровень 16, состояние 1, строка 1 Идентификатор с несколькими частями «a.HolidayDate» не может быть связан. Msg 4104, уровень 16, состояние 1, строка 1 Идентификатор с несколькими частями «a.HolidayDate» не может быть связан. – user3003944

+0

Повторите запрос ... –

+0

Всего 2 ошибки. Msg 4104, уровень 16, состояние 1, строка 1 Идентификатор с несколькими частями "g.Cities_Id" не может быть связан. Msg 4104, уровень 16, состояние 1, строка 1 Идентификатор с несколькими частями "u.Cities_Id" не может быть связан. – user3003944

0

присоединяется не нравится или
вы можете избавиться от одного или с ISNULL

SELECT p.VORNA AS firstName, 
     p.NACHN AS lastName, 
     p.USRID AS [USER], 
     o.ORGEH AS OUID, 
     o.STEXT AS OU, 
     a.HolidayDate AS absentFrom, 
     a.HolidayDate AS absentUntil, 
     k.MessageDate AS actionDate, 
     'holiday' as reason 
    FROM Kondor_User_Activities AS k  
    JOIN Kondor_Users AS u 
     ON u.Users_Id = k.Users_Id 
    JOIN Kondor_UsersGrp AS g 
     ON g.UsersGrp_Id = u.UsersGrp_Id 
     and ( g.UsersGrp_ShortName < 'UA_' 
      OR g.UsersGrp_ShortName >= 'UA`') 
    JOIN Kondor_Cities AS c 
     ON c.Cities_Id = isnull(u.Cities_Id, g.Cities_Id) 
    JOIN Kondor_FixedHolidays AS a 
     ON a.Cities_Id = c.Cities_Id 
     AND k.MessageDate >= a.HolidayDate 
     and k.MessageDate < a.HolidayDateEnd 

    JOIN dbo.SAP_Personaldaten AS p 
     ON p.USRID = k.Code 
    JOIN SAP_OE AS o 
     ON p.ORGEH = o.ORGEH 
+0

Спасибо за ваше решение, но оно кажется намного медленнее, чем раньше. Тем временем я обнаружил, что есть проблемы с таблицей Kondor_Users_Activities, расходы составляют 91%, хотя у меня есть все необходимые индексы. План выполнения находится ниже сайта. – user3003944

+0

Кажется? Вы позволили этому запустить? Вы сказали, что это занимает больше часа, и вы отправили комментарий через 20 минут после публикации ответа. – Paparazzi

+0

Я остановил его через некоторое время, это правда. Это не займет больше 1 - 2 минут, так как у нас нет миллионов и миллионов строк. – user3003944

0

Как слепой Longshot - никаких таблиц, отношений, индексов или ничего полезного, попробуйте следующее:

SELECT 
     UActivities.firstName, 
     UActivities.lastName, 
     UActivities.[USER], 
     UActivities.OUID, 
     UActivities.OU, 
     UserHoliday.HolidayDate AS absentFrom, 
     UserHoliday.HolidayDate AS absentUntil, 
     UActivities.actionDate, 
     'holiday' as reason 
    FROM (
      SELECT 
       k.MessageDate AS actionDate, 
       k.Users_Id, 
       k.Code, 
       p.VORNA AS firstName, 
       p.NACHN AS lastName, 
       p.USRID AS [USER], 
       o.ORGEH AS OUID, 
       o.STEXT AS OU 
      FROM Kondor_User_Activities AS k 
       INNER JOIN dbo.SAP_Personaldaten AS p ON k.Code = p.USRID 
        INNER JOIN SAP_OE AS o ON p.ORGEH = o.ORGEH 
      ) AS UActivities 
     INNER JOIN (
      SELECT 
       UserCities.Users_Id, 
       a.HolidayDate 
      FROM (
        SELECT 
         u.Users_Id, 
         ISNULL(u.Cities_Id, g.Cities_Id) AS CityId 
        FROM 
         Kondor_Users u 
         INNER JOIN Kondor_UsersGrp AS g ON g.UsersGrp_Id = u.UsersGrp_Id AND (g.UsersGrp_ShortName NOT LIKE 'UA_%') 
        ) AS UserCities 
       INNER JOIN Kondor_FixedHolidays AS a ON a.Cities_Id = UserCities.CityId 
      ) AS UserHoliday ON UActivities.Users_Id = UserHoliday.Users_Id AND UActivities.actionDate >= UserHoliday.HolidayDate and UActivities.actionDate < UserHoliday.HolidayDateEnd 

Не знаю, ударил ли я ll имена столбцов должным образом, но то, что я вижу в качестве проблемы здесь, заключается в том, что оптимизатор стал неистовым и из-за сложности ваших условий сказал: «Я собираюсь идти по одной строке одновременно, проверяя каждую активность пользователя, чтобы увидеть, соответствует ли она все остальные критерии ».

мое усилие было отделить логические части запроса - в таком порядке:
1. создать все города, которые могут быть пользователи - либо непосредственно поименованные или унаследованы от группы (ISNULL(u.Cities_Id, g.Cities_Id))
2. создать все праздники на основе городов полученные от # 1
3. Соедините те, у которых необходимые данные пользователя из остальной таблицы.

Глядя на этот результат - возможно, даже лучше не создавать внутренний запрос UActivities, а присоединяться к этим таблицам от результата до UserCities. Чтобы определить это, мне действительно нужен доступ, но вы могли бы это сделать.

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

+0

Большое спасибо за ваши усилия! Я тоже попробую. Я также подумал о том, чтобы изменить мой запрос или лучше сказать, я уже сделал это (но не так, как вы его мне предоставляете), но всегда говорят, что переупорядочение может помочь, но не нужно помогать, потому что компилятор (?) делает все с собственной логикой - я получил эти сообщения об ошибках, но я попытаюсь их решить: Msg 4104, Level 16, State 1, Line 1 Идентификатор многочастности «k.MessageDate», «a.HolidayDate», , «k.MessageDate», a.HolidayDateEnd »не удалось связать. – user3003944

+0

В последней строке были ошибки - я их исправил. Попробуйте сейчас. –

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