2017-01-31 4 views
0

У меня возникла странная проблема с производительностью. У меня есть представление, основанное на CTE. Это мнение, которое я написал много лет назад, и оно работает без проблем. Внезапно, 4 дня назад, запрос, который выполнялся в течение 1-2 минут, работал несколько часов, прежде чем мы определили длинный запрос и остановили его.SQL Server LEFT OUTER JOIN Производительность запроса

CTE производит список транзакций, промаркированных по времени. Затем я выбираю из CTE, слева присоединяюсь к CTE, используя метку времени последующей транзакции, чтобы определить время, которое агент тратит на каждую транзакцию.

WITH [CTE_TABLE] (COLUMNS) AS 
    (
    SELECT [INDEXED COLUMNS] 
     ,[WINDOWED FUNCTION] AS ROWNUM 
    FROM [DB_TABLE] 
    WHERE [EMPLOYEE_ID] = 111213 
    ) 

    SELECT [T1].[EMPLOYEE_ID] 
     ,[T1].[TRANSACTION_NAME] 
     ,[T1].[TIMESTAMP]   AS [START_TIME] 
     ,[T2].[TIMESTAMP]   AS [END_TIME] 
    FROM [CTE_TABLE] [T1] 
     LEFT OUTER JOIN [CTE_TABLE] [T2] ON 
      (
      [T1].[EMPLOYEE_ID] = [T2].[EMPLOYEE_ID] 
      AND [T1].[ROWNUM] = [T2].[ROWNUM] + 1 
      ) 

При тестировании я фильтрую для конкретного агента. Если он запускает внутреннюю часть CTE, он производит 500 записей менее чем за секунду. (Если не фильтровать для одного агента, он производит 95K записей за 14 секунд. Это нормальный рабочий таймфрейм.) Если я запускаю CTE с помощью простого SELECT * FROM [CTE_TABLE], он также работает менее чем за секунду. Когда я запускаю его, используя INNER JOIN обратно к себе, снова работает менее чем за секунду. Наконец, когда я запускаю его как LEFT OUTER JOIN, он занимает полторы минуты только для 500 записей одного агента. Мне нужна LEFT OUTER JOIN, потому что окончательная запись дня - это выход агента из системы, и у него никогда нет записи для присоединения.

Стол, который я вытягиваю, имеет размер более 22 ГБ и имеет 500 миллионов рядов. Выбор записей из этой таблицы за один день занимает 14 секунд или один агент менее чем за секунду, поэтому я не думаю, что узкое место производительности происходит из исходной таблицы. Узкое место появляется в LEFT OUTER JOIN обратно в CTE, но у меня всегда была LEFT OUTER JOIN. Опять же, очень странный аспект заключается в том, что это началось только 4 дня назад. Я проверил место на сервере, есть много. Процессор всплесков ок. 25% и остается там до тех пор, пока запрос не завершится, либо сам по себе, либо остановлен администратором.

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

+1

Какую версию SQL Server вы используете? Похоже, хороший кандидат на использование LEAD/LAG, если вы в 2012 году вверх. –

ответ

1

Опять же, очень странный аспект в том, что это только началось 4 дня назад

Я рекомендую обновление статистики по таблицам, участвующих, а также попробовать Перестройка индексов

Узким происходит в LEFT OUTER JOIN назад в CTE

CTE не будет иметь статистики, он CTE в таблицу Temp, чтобы узнать, помогает ли это

+0

Восстановление индексов! Спасибо! Если возможно, почему это повлияло на производительность INNER JOIN Vs. LEFT OUTER JOIN в представлении данных в памяти? – UncleJasper75

+0

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

+0

@ UncleJasper75: также отправьте план выполнения, перейдя в – TheGameiswar

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

  • Нет связанных вопросов^_^