Улучшить медленный запрос, когда количество записей удваивается

У меня есть запрос, который выбирает данные из таблицы.

Количество записей в этой таблице зависит от ввода пользователей.

Когда количество записей составляет около 60 000 или меньше, это довольно быстро (менее 2 минут).

Но когда я удваиваю количество записей около 120 000, это занимает больше часа! и ТОГДА я должен убить процесс.

Я не знаю, почему это очень медленно.

Я добавил много индексов, но это все еще слишком медленно.

Вот запрос

DECLARE @MaxID AS bigint

SELECT @MaxId = MAX(iID) from TagsTemp
    
SELECT 
    RepID, tag, xmiid, ibegin, iend, 
    confidence, polarity, uncertainty, conditional, generic, historyOf,
    codingScheme, code, cui, /*U.tui,*/ preferredText , --ISNULL(tag2, tag3) AS tagValue, 
    ISNULL(ibegin2, ibegin3) AS ibeginValue, ISNULL(iend2, iend3) AS iendValue,
    dbo.RepGetValue(RepID, ibegin, iend, 
    ISNULL(ibegin2, ibegin3), ISNULL(iend2, iend3))
FROM 
    (SELECT DISTINCT 
         T.RepID, dbo.ShortTag(T.tag) AS tag, T.xmiid, 
         CAST(T.ibegin AS bigint) AS ibegin, CAST(T.iend AS bigint) AS iend, 
         T.confidence, T.polarity, T.uncertainty, T.conditional, T.generic, T.historyOf,
         dbo.ShortTag(U.codingScheme) AS codingScheme, U.code, U.cui, /*U.tui, */U.preferredText,
         dbo.ShortTag(L3.tag) AS tag2, L3.ibegin AS ibegin2, L3.iend AS iend2,
         dbo.ShortTag(M1.tag) AS tag3, M1.ibegin AS ibegin3, M1.iend AS iend3, 
         ROW_NUMBER() OVER(PARTITION BY T.RepID, T.tag, T.xmiid,
         CAST(T.ibegin AS bigint), CAST(T.iend AS bigint), 
         T.confidence, T.polarity, T.uncertainty, T.conditional, T.generic, T.historyOf,
         U.codingScheme, U.code, U.cui, /*U.tui,*/ U.preferredText , L3.tag, L3.ibegin, L3.iend 
     ORDER BY 
         T.RepID, T.xmiid, CAST(T.ibegin AS bigint), CAST(T.iend AS bigint), 
         CAST(M1.ibegin AS bigint), CAST(M1.iend AS bigint) DESC, 
         CASE M1.tag 
            WHEN 'textsem:Mandy' THEN 1 
            WHEN 'textsem:Franc' THEN 2 
            WHEN 'textsem:Roger' THEN 3 
            WHEN 'syntax:Numan' THEN 4 
            WHEN 'textsem:Danna' THEN 5 
            WHEN 'textsem:Rami' THEN 6 
         END) AS RowNo
     FROM 
         TagsTemp T 
     INNER JOIN 
         TagsTemp U ON T.RepID = U.RepID 
                    AND T.Tag IN ('textsem:Michael', 'textsem:Simon', 'textsem:Anna','textsem:Evan','textsem:Paul','textsem:Dines','textsem:Larry')
                    AND U.Tag = 'refsem:Usman'
                    AND T.ontologyConceptArr LIKE '%' + CAST(U.xmiid AS varchar(100)) + '%'
     LEFT OUTER JOIN 
         TagsTemp L1 ON T.tag = 'textsem:Larry' 
                     AND L1.tag = 'relation:ResultOfTextRelation'
                     AND T.RepID = L1.RepID 
                     AND T.LabValue = L1.xmiid 
                     AND ISNULL(L1.arg2, '') <> ''
     LEFT OUTER JOIN 
         TagsTemp L2 ON L1.tag = 'relation:ResultOfTextRelation' 
                     AND L2.tag = 'relation:RelationArgument' 
                     AND L1.RepID = L2.RepID 
                     AND L1.arg2 = L2.xmiid 
     LEFT OUTER JOIN 
         TagsTemp L3 ON L2.tag = 'relation:RelationArgument' 
                     AND  L3.tag IN ('syntax:Numan','textsem:Danna','textsem:Roger','textsem:Mandy', 'textsem:Franc','textsem:Rami')
                     AND L2.RepID = L3.RepID 
                     AND L2.argument = L3.xmiid
     LEFT OUTER JOIN 
         TagsTemp M1 ON T.RepID = M1.RepID 
                     AND T.tag IN ('textsem:Michael', 'textsem:Larry') 
                     AND M1.tag IN ('syntax:Numan','textsem:Danna','textsem:Roger', 'textsem:Mandy',/*'textsem:Rami', */ 'textsem:Franc')
                     AND CAST(M1.ibegin AS bigint) > CAST(T.iend AS bigint) 
                     AND CAST(M1.ibegin AS bigint) - CAST(T.iend AS bigint) < 4 
     WHERE 
         T.iID <= @MaxID) X
WHERE
    RowNo =    1
ORDER BY 
    RepID, tag, xmiid, CAST(ibegin AS bigint) , CAST(iend AS bigint) , 
    confidence, polarity, uncertainty, conditional, generic, historyOf,
    codingScheme, code, cui, /*U.tui,*/ preferredText , tag2, ibegin2, iend2,
    tag3,ibegin3, iend3

Вот план выполнения, когда я бегу за 60 000

https://www.brentozar.com/pastetheplan/?id=r1XHRQXpD

iID - это кластерный первичный ключ, наверняка причина не в этом

asmgx 25.12.2020 10:31

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

TT. 25.12.2020 10:32

Что ж, я предлагаю сначала протестировать большой подзапрос изолированно.

Tarik 25.12.2020 10:35

Это некрасиво: CASE M1.tag WHEN 'textsem:Mandy' then 1 WHEN 'textsem:Franc' then 2 WHEN 'textsem:Roger' then 3 WHEN 'syntax:Numan' then 4 WHEN 'textsem:Danna' then 5 WHEN 'textsem:Rami' then 6 END). Имейте небольшую таблицу со строкой и числами, а затем используйте ее в соединении.

Tarik 25.12.2020 10:40

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

Tarik 25.12.2020 10:43

Структура таблицы @Tarik представляет собой копию полученных файлов XML. этот запрос для упрощения данных таблицы

asmgx 25.12.2020 10:49

Ну цель может быть и благородная, но ИМХО метод слишком сложный. Вам нужно разбить все это на управляемые части, которые вы можете тестировать изолированно даже с точки зрения производительности. Смотрите другие мои предложения.

Tarik 25.12.2020 10:53

@Tarik Я думаю, так и надо. Я разобью его на более управляемые части

asmgx 25.12.2020 10:55

Удачи! Кроме того, внимательно документируйте каждый шаг, чтобы не потеряться, когда вернетесь к этому коду через 6 месяцев. Поместите много комментариев, объясняющих, почему вы делаете то или иное.

Tarik 25.12.2020 10:59

Похоже, вы работаете с JSON. Может быть, вы можете разобрать его, а затем использовать в своем запросе. Это должно быть определенно быстрее.

Slava Murygin 25.12.2020 16:21
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
10
172
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

У вас есть поиск ключа с поиском 37K Попробуйте удалить индекс «[NonClusteredIndex-20201223-150141]» и создать вместо него другой:

CREATE INDEX NCI_TagsTemp_1 ON TagsTemp (iID, RepID, tag)
INCLUDE (xmiid, ibegin, iend, ontologyConceptArr, confidence, polarity, uncertainty, conditional, generic, historyOf, labValue)
Ответ принят как подходящий

У меня нет точного ответа, но я могу помочь вам улучшить производительность

перед выполнением этого запроса запустите оба оператора

SET STATISTICS IO ON 
SET STATISTICS TIME ON 

Теперь запустите свой запрос и проанализируйте результат на вкладке сообщений.

Используйте этот сайт для большей читабельности http://statisticsparser.com/

Попробуй найти где больше физического чтения, этот сайт для понимания физического и логического чтения https://vaishaligoilkar3322.medium.com/physical-and-logical-reads-in-sql-server-c6d62e65e359

Теперь вам нужно найти точный блок, который требует времени, и попытаться сломать его.

Попробуйте уменьшить количество физических и логических операций чтения и повторяйте этот шаг, пока не найдете основную причину.

Это лучший способ улучшить производительность этого запроса.

Надеюсь, это поможет вам.

Другие вопросы по теме