#sql-server #tsql
#sql-server #tsql
Вопрос:
Я пытаюсь проанализировать производительность запроса. К сожалению, у меня нет прав на выполнение расчетного или фактического плана запроса к базе данных, которую я читаю. ( SHOWPLAN
в разрешении отказано в базе данных)
Я переписал исходный запрос, но хотел бы сравнить время выполнения исходного запроса и моих двух запросов. Для достижения этой цели я подумал, что создам 4 переменные datetime2 и буду записывать SYSDATETIME()
между каждой итерацией, а затем находить разницу.
К сожалению, я обнаружил, что после вызова функция SYSDATETIME()
не обновляется.
В общей сложности мои 3 запроса выполняются 17 секунд. Между каждым выполнением я должен иметь возможность видеть изменение временной метки, но переменные каждый раз записывают одну и ту же временную метку.
declare @a datetime2, @b datetime2, @c datetime2, @d datetime2
set @a = SYSDATETIME()
select bunch of columns from a bunch of joined tables
set @b = SYSDATETIME()
select bunch of columns and sub-queries from a bunch of tables joined a little differently
set @c = SYSDATETIME()
select bunch of columns and sub-queries from a bunch of differently joined tables and sub-queries
set @d = SYSDATETIME()
print @a
print @b
print @c
print @d
Все 4 переменные имеют одинаковое значение.
a 2019-04-05 16:00:09.3947421
b 2019-04-05 16:00:09.3947421
c 2019-04-05 16:00:09.3947421
d 2019-04-05 16:00:09.3947421
Общее время выполнения составило 19 секунд, поэтому должны были быть действительные данные для проверки.
Есть предложения?
Комментарии:
1. предоставьте копию этого. Здесь нет повтора dbfiddle.uk /…
2. Может быть SQL распараллелен и ваши запросы выполняются не по порядку?
3. @Clay. no. parallelism в Sql Server так не работает.
Ответ №1:
Что ж, вместо того, чтобы записывать больше циклов, беспокоясь об этом, я просто напечатал временную метку и поставил ПЕРЕХОД между каждой итерацией моих тестов. Затем сделал математику позже.
Все еще не знаю, почему SYSDATETIME не возвращает истинное значение при каждом вызове. Возможно, SQL server пытается быть полезным.
К вашему сведению, из этого rtrim(ltrim(FIELD))) быстрее, чем ПОЛЕ типа ‘A%’, которое быстрее, чем FIELD = ‘A’, когда ПОЛЕ равно char(10).
Ответ №2:
Вероятно, весь запрос запускается одновременно.
Вместо этого попробуйте запускать каждый запрос отдельными пакетами. Это должно дать вам несколько полезных временных меток.
declare @a datetime2 = SYSDATETIME()
print @a
go
select bunch of columns from a bunch of joined tables
declare @b datetime2 = SYSDATETIME()
print @b
go
select bunch of columns and sub-queries from a bunch of tables joined a little differently
DECLARE @c datetime2 = SYSDATETIME()
print @c
go
select bunch of columns and sub-queries from a bunch of differently joined tables and sub-queries
declare @d datetime2 = SYSDATETIME()
print @d
go
Комментарии:
1. SQL Server не выполняет разные инструкции в одном пакете одновременно. Одновременно может выполняться только один оператор. Вероятно, OP допустил какую-то ошибку, не показанную в коде, который они нам предоставили. (например, оставить там инструкцию, которая присваивает все переменные в одном операторе)
2. Нет, я ничего не упустил, и я не присваиваю всем переменным одинаковые значения сразу. Я занимаюсь SQL более десяти лет.
3. Это то, что я должен был сделать, Питер, спасибо. Но не объясняет, почему SQL не может быть обеспокоен возвращением истинного значения при каждом вызове функции.