Member 14857708 Ответов: 2

Как оптимизировать следующий тип запроса?


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

UPDATE table_name
SET
	column_name =(SELECT DISTINCT
			COUNT(column1)
		FROM 
			table1 
				LEFT JOIN table2 on some_condition
				INNER JOIN table3 on some_condition
				INNER JOIN table4 on some condition
		WHERE 

			( column1 in ('A', 'B','C') or column1 is NULL )

			AND table1.columnname  < getDate()
			AND  anothercolumnname = 0

			AND	anotherCName1 <> 'blah blah'
			AND	anotherCName2 not in ('blah blah') 

			AND table2.anotherCName3 = 'blah')


Пожалуйста, помогите мне оптимизировать этот запрос.

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

Любая помощь будет оценена по достоинству.

Richard MacCutchan

По-моему, это решение проблемы.

Member 14857708

Не могли бы вы оптимизировать вышеприведенный запрос, чтобы я лучше его понимал. Я новичок и не очень хорошо разбираюсь в SQL.

Richard MacCutchan

Затем идите и потратьте некоторое время на изучение SQL.

Member 14857708

О! Мне очень жаль.. Я не проверил всю почту.. Я только что видел ссылки.

2 Ответов

Рейтинг:
20

CHill60

Начать здесь..
Топ-10 шагов по оптимизации доступа к данным в SQL Server: Часть I (использование индексации)[^]
Советы и рекомендации по производительности SQL Server[^]
Часто задаваемые вопросы по оптимизации SQL-запросов Часть 1 (с видео-объяснением)[^]
Повышение производительности запросов с помощью SQL Server: Часть 1[^]

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

"on some_condition" не помогает - возможно, проблема заключается в том, как вы определили свои соединения

table1.columnname < getDate()Попробуйте использовать

declare @ddate Date = getDate()
. . .
table1.columnname < @ddate
Результаты могут быть незаметны в зависимости от объемов данных - опять же неизвестных нам

Попробуйте избавиться от DISTINCT - количество записей уже отчетливо видно

EDIT - еще одна полезная статья о том, как узнать, куда уходит время .. Как анализировать производительность SQL Server[^]


Maciej Los

5ed!

CHill60

Спасибо!

0x01AA

Разве это не так COUNT(DISTINCT Column1)?

CHill60

Если это то, что ОП пытается определить - хотя я бы, вероятно, сам использовал группу по столбцу 1. Использование именованного столбца в функции COUNT() может повлиять на производительность некоторых баз данных, поскольку СУБД потенциально должна обслуживать NULL в этом столбце

Рейтинг:
1

Patrice T

LEFT JOIN table2 on some_condition

Условия-это то, что делает запрос быстрым или медленным. Таким образом, точное состояние имеет значение, структуры таблиц и индексы тоже имеют значение.
AND table1.columnname  < getDate()

getDate () - это волатильная функция, то есть она предотвращает любую оптимизацию. если запрос выполняется около полуночи, дата может измениться во время запроса.
При использовании волатильной функции время выполнения запроса зависит от количества записей в таблице.
При использовании промежуточной переменной время выполнения зависит от количества записей, соответствующих условию (если оно индексировано).
Читать это: GETDATE (Transact-SQL) - SQL Server | Microsoft Docs[^]


Jörgen Andersson

GetDate () - это не Летучая функция, а недетерминированная константа времени выполнения.

Patrice T

Английский не является моим основным языком, я могу злоупотреблять словом "изменчивый", но проблема, которую я описываю, остается той же самой.
Читать это: GETDATE (Transact-SQL) - SQL Server | Microsoft Docs[^]

Jörgen Andersson

Нет, значение GetDate() не может измениться во время выполнения запроса. Он устанавливается как константа в начале запроса.
Это можно легко проверить с помощью : SELECT somecolumn,GetDate() As MyDateTime INTO MyTestTable FROM MyVeryLargeTable, значение MyDateTime будет постоянным, даже если запрос выполняется в течение нескольких минут.

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