#sql-server
#sql-сервер
Вопрос:
Не мог бы кто-нибудь из вас сообщить мне, почему функция подкачки row_number имеет проблемы с производительностью при использовании "HERE results.ROWNUMBER BETWEEN 1 AND 50
предложения (занимает более 2 минут), но запускается через 5 секунд, когда я комментирую предложение where, которое вернет весь результирующий набор, который возвращает около 623 записей.
Я вижу, что запрос использует одни и те же индексы, но некоторые, как при использовании предложения where, логические чтения экспоненциально увеличиваются для 2 таблиц, как показано ниже, я пытался исправить это довольно давно, любая помощь с благодарностью.
Спасибо
при использовании предложения where
Таблица ‘INTERCHANGEJDO’. Количество сканирований 15416, логическое чтение 144336865, физическое чтение 0, чтение с опережением 0, логическое чтение lob 0, физическое чтение lob 0, чтение с опережением lob 0.
Таблица «Рабочая таблица». Количество сканирований 16, логические чтения 70965478, физические чтения 0, чтение с опережением 0, lob логические чтения 0, lob физические чтения 0, lob чтение с опережением
Когда предложение where прокомментировано
Таблица ‘INTERCHANGEJDO’. Количество сканирований 16, логическое чтение 18501, физическое чтение 0, чтение с опережением 0, логическое чтение lob 0, физическое чтение lob 0, чтение с опережением lob 0.
Таблица «Рабочая таблица». Количество сканирований 0, логическое чтение 0, физическое чтение 0, чтение с опережением 0, логическое чтение lob 0, физическое чтение lob 0, чтение с опережением lob 0.
SET STATISTICS IO ON
GO
WITH ALLRESULTS AS
(
SELECT
t5.*, ROW_NUMBER() OVER (ORDER BY FUNCTIONALGROUPNAME DESC) ROWNUMBER
FROM
(SELECT
t0.JDOID, t0.ACCEPTCODE, t0.ACCEPTCODE824,t0.ACKDATE, t0.UTILITY,
t0.DIRECTION, t0.DOCUMENTREFERENCENUMBER, t3.DESCRIPTION FUNCTIONALGROUPNAME,
t0.INTERCHANGE_JDOID, t0.MODIFIEDBY, t0.MODIFYDATE, t0.PROCESSDATE,
t0.SENTDATE, t0.SETID, t0.STATUS, t0.TURNED,
t0.PARTNER, t0.NETWORKID, t1.INTERCHANGECONTROLNUMBER, t1.TRADINGPARTNERPAIR_JDOID,
TRANSLATIONJOBID = CASE
WHEN (t0.TRANSLATIONJOBID IS NULL OR t0.TRANSLATIONJOBID = '')
THEN t1.TRANSLATIONJOBID
ELSE t0.TRANSLATIONJOBID
END
FROM
DOCUMENTJDO AS t0 WITH (NOLOCK)
INNER JOIN
INTERCHANGEJDO t1 ON t0.INTERCHANGE_JDOID = t1.JDOID
INNER JOIN
TRADINGPARTNERPAIRJDO t3 ON t1.TRADINGPARTNERPAIR_JDOID = t3.JDOID
WHERE
t0.direction = 'I'
AND t0.processDate >= '2019-07-18 00:00:00'
AND t0.processDate <= '2020-09-18 23:59:59'
AND (t1.TRADINGPARTNERPAIR_JDOID IN (SELECT DISTINCT vw.TPPDS_JDOID
FROM vwEDXMain vw WITH (NOLOCK)
WHERE (vw.levelCode LIKE '32,J4Q%')
AND vw.TPPDS_JDOID IS NOT NULL))) AS t5
),
RESULT AS
(
SELECT
results.*,
(SELECT COUNT(*) FROM ALLRESULTS) AS TOTAL
FROM
ALLRESULTS AS results
WHERE
results.ROWNUMBER BETWEEN 1 AND 50
),
DOCUMENTVIEWED AS
(
SELECT DISTINCT DOCUMENTID
FROM DOCUMENTUSERJDO WITH (NOLOCK)
WHERE VIEWED = 1
),
DOCUMENTVIEWEDBYUSER AS
(
SELECT DISTINCT DOCUMENTID AS DOCUMENTID_USER, USERID, VIEWED
FROM DOCUMENTUSERJDO
WHERE USERID = 'com.-19422' AND VIEWED = 1
)
SELECT
t5.*,
VIEWED = CASE
WHEN t5.DOCUMENTID_VIEWED IS NULL
THEN 0
WHEN t6.USERID IS NULL
THEN 2
ELSE T6.VIEWED
END
FROM
(SELECT
t3.*,
t4.DOCUMENTID AS DOCUMENTID_VIEWED
FROM
RESULT AS t3
LEFT JOIN
DOCUMENTVIEWED AS t4 ON t4.DOCUMENTID = 'com.-' ltrim(t3.JDOID)) AS t5
LEFT JOIN
DOCUMENTVIEWEDBYUSER AS t6 ON t6.DOCUMENTID_USER = t5.DOCUMENTID_VIEWED
ORDER BY
T5.ROWNUMBER
GO
SET STATISTICS IO OFF
Комментарии:
1. Я настоятельно рекомендую узнать о пробелах и разрывах строк; что SQL невозможно прочитать. Тот факт, что псевдонимы не имеют смысла, тоже не помогает: вредные привычки: использование псевдонимов таблиц, таких как (a, b, c) или (t1, t2, t3) . Вам также нужны все эти
NOLOCK
подсказки (особенно в отношении одного объекта, который являетсяVIEW
? Понимаете ли вы ее последствия? Вредные привычки: везде ставить NOLOCK2. Я подозреваю, что существует проблема с вложенным циклом. Возможно, вы можете удалить все, кроме полей и таблиц, необходимых для получения требуемых записей. Я обнаружил, что иногда, сосредоточившись сначала на «ключах», легче эффективно получать только нужные записи. Уточнение по одному шагу за раз может показать, на каком этапе находится проблема. Этот запрос сложный. Оптимизатор пытается дать вам именно то, о чем вы просите, но, возможно, вы можете попросить то же самое менее сложным способом.