rikidev Ответов: 1

Запросы с несколькими обновлениями очень медленные


Hi then the query I'm running below works correctly but it is very slow to perform the operations as I can to speed it up? Unfortunately it is a very oneorose query and I have to run it on a server sql 2014 some advice? 

UPDATE KilometriCantiereRapportoMobile
    SET IdRapportoMobile = @IdRapporto
    WHERE IdKilometri IN (SELECT
      Kilometri.IdKilometri
    FROM Kilometri
    INNER JOIN KilometriCantiereRapportoMobile
      ON Kilometri.IdKilometri = KilometriCantiereRapportoMobile.IdKilometri
    WHERE KilometriCantiereRapportoMobile.IdRapportoMobile IS NULL
    AND CONVERT(varchar(10), @Data, 105) = CONVERT(varchar(10), Kilometri.Data, 105)
    AND Kilometri.IdCantiere = @IdCantiere
    AND Kilometri.IdUtenteInserimento = @IdUtente);   /*Articoli */
    UPDATE ArticoloCantiereRapportoMobile
    SET IdRapportoMobile = @IdRapporto
    WHERE IdArticoloCantiere IN (SELECT
      ArticoloCantiere.IdArticoloCantiere
    FROM ArticoloCantiere
    INNER JOIN ArticoloCantiereRapportoMobile
      ON ArticoloCantiere.IdArticoloCantiere = ArticoloCantiereRapportoMobile.IdArticoloCantiere
    WHERE ArticoloCantiereRapportoMobile.IdRapportoMobile IS NULL
    AND CONVERT(varchar(10), @Data, 105) = CONVERT(varchar(10), ArticoloCantiere.Data, 105)
    AND ArticoloCantiere.IdCantiere = @IdCantiere
    AND ArticoloCantiere.IdUtente = @IdUtente);  /* risorse */
    UPDATE RisorsaRapportoMobile
    SET IdRapportoMobile = @IdRapporto
    WHERE IdRisorseUmane IN (SELECT
      RisorseUmane.IdRisorseUmane
    FROM RisorsaRapportoMobile
    INNER JOIN RisorseUmane
      ON RisorseUmane.IdRisorseUmane = RisorsaRapportoMobile.IdRisorseUmane
    WHERE RisorsaRapportoMobile.IdRapportoMobile IS NULL
    AND CONVERT(varchar(10), @Data, 105) = CONVERT(varchar(10), RisorseUmane.Data, 105)
    AND RisorseUmane.IdCantiere = @IdCantiere
    AND RisorseUmane.IdUtenteInserimento = @IdUtente)


Что я уже пробовал:

перезапустить SQL Server

Clifford Nelson

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

#realJSOP

Соединения также убивают вашу производительность.

rikidev

как я могу сделать это внутри join?

MadMyche

Добавляя комментарий Клиффорда, я хотел бы использовать инструмент "план выполнения" в Sql Server, чтобы точно определить, что вас замедляет. Функции преобразования там выглядят как простая дата; я бы сначала убедился, что входные данные находятся в этом формате, и пропустил бы их, или, по крайней мере, назначил бы ему переменную varchar(10) и пропустил бы половину преобразований в каждой отдельной строке по сравнению

Gerry Schmitz

Вы когда-нибудь слышали о "временных столах"? "Секционирование" - это проблема?

Samira Radwan

Я не эксперт по SQL, но, как сказал @Gerry, использование временных таблиц-неплохая идея.
Я вижу, что у вас есть 3 'WHERE field IN', а затем большой оператор SELECT. То, что я мог бы сделать, это использовать временные таблицы для этих select специально, у них есть все виды объединения и преобразования, так что вместо WHERE field IN (SELECT...) это будет WHERE field IN (#tempTable). Затем, когда вы закончите с обновлением, просто отбросьте #tempTable.

1 Ответов

Рейтинг:
1

CHill60

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

UPDATE RRM SET IdRapportoMobile = @IdRapporto
FROM RisorsaRapportoMobile RRM
INNER JOIN RisorseUmane RU ON RU.IdRisorseUmane = RRM.IdRisorseUmane
WHERE RRM.IdRapportoMobile IS NULL
    AND CONVERT(varchar(10), @Data, 105) = CONVERT(varchar(10), RU.Data, 105)
    AND RU.IdCantiere = @IdCantiere
    AND RU.IdUtenteInserimento = @IdUtente
Смотрите комментарии об использовании CONVERT - избавьтесь от них. Убедитесь, что @Data - это date (не а datetime. Date существует с момента SQL2008, так что он будет работать с 2014 года). Если Рисорсуман.Данные-это дата и время в базе данных, а затем попробуйте использовать
AND @Data = CAST(RU.Data AS date)
Это должно быть быстрее, чем преобразование в строки.

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

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

Есть некоторые статьи CodeProject, которые также могут помочь вам, когда дело доходит до настройки производительности:
Учебник по настройке SQL - понимание плана выполнения базы данных (1)[^]
SQL Server Profiler шаг за шагом[^]
Как анализировать производительность SQL Server[^]