С Новым годом! Форум программистов, компьютерный форум, киберфорум
Microsoft SQL Server
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
2 / 2 / 0
Регистрация: 18.09.2022
Сообщений: 242

Время исполнения запроса с переменной

03.04.2025, 14:09. Показов 2294. Ответов 37
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть простой скрипт:

SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
DROP TABLE IF EXISTS test
GO
 
CREATE TABLE test(
id INT IDENTITY(1,1) NOT NULL,
dt DATE)
GO
 
INSERT test VALUES ('2024-12-01')
GO
 
DECLARE @val DATE
SET @val=(SELECT MIN(dt) FROM test)
 
SELECT * FROM table1 WHERE field1=@val
SELECT * FROM table1 WHERE field1='2024-12-01'
Думаю, что объяснять не нужно, все просто. Суть вопроса во времени исполнения двух последних селектов. Кажется, что время исполнения должно быть одинаковым. Но на практике оказывается, что select * from table1 where field1=@val выполняется в разы медленнее, чем второй скрипт. Причем чем больше данных в таблице table1, тем больше будет эта разница. Может кто-то объяснить, почему с @val работает все медленно? Заранее спасибо!
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
03.04.2025, 14:09
Ответы с готовыми решениями:

Завершение исполнения запроса
Доброго времени суток. Возникла проблема с временем окончания исполнения запроса: DoCmd.OpenQuery...

Влияет ли последовательность перечисления полей в JOIN на скорость исполнения запроса?
Здравствуйте! Скажите, влияет ли последовательность перечисления сцепок, идущих после ключевого слова ON в JOIN, на скорость...

Независящий от нагрузки на сервер критерий оптимальности построения(скорости исполнения) запроса
Здравствуйте! Скажите, параметр Estimated Subtree Cost самого левого оператора в актуальном плане запроса не зависит от того, какая...

37
 Аватар для Andrey-MSK
3317 / 2204 / 387
Регистрация: 14.08.2018
Сообщений: 7,411
Записей в блоге: 4
03.04.2025, 14:19
Лучший ответ Сообщение было отмечено 2022N2022 как решение

Решение

Цитата Сообщение от 2022N2022 Посмотреть сообщение
Время исполнения запроса с переменной
Добавьте OPTION (RECOMPILE), или оберните это в хранимку, результат будет как и указанной выше опции.

OPTION(RECOMPILE) — это хинт запроса в SQL Server, который указывает оптимизатору перекомпилировать план запроса каждый раз при его выполнении.

Таким образом, SQL Server генерирует оптимизированный план запроса на основе текущих значений любых переменных, используемых в запросе, а не опирается на кэшированный план
3
2 / 2 / 0
Регистрация: 18.09.2022
Сообщений: 242
03.04.2025, 14:47  [ТС]
Да, действительно при указании этой опции время исполнения одинаковое.
А можно объяснить тупому, почему только с option (recompile) это работает? вроде бы и просто так должно работать...
0
 Аватар для Andrey-MSK
3317 / 2204 / 387
Регистрация: 14.08.2018
Сообщений: 7,411
Записей в блоге: 4
03.04.2025, 15:04
2022N2022, RECOMPILE
2
 Аватар для pincet
1654 / 1153 / 173
Регистрация: 23.07.2010
Сообщений: 6,910
03.04.2025, 15:46
Andrey-MSK, и почтенная публика - как option(recompile) повлияет на param sniffing? тема весьма древняя, но до сих пор все так?

Добавлено через 1 минуту
2022N2022, и так-то (емнип) select * это полностью задача оптимизатора
0
139 / 105 / 36
Регистрация: 27.07.2022
Сообщений: 357
03.04.2025, 16:13
Цитата Сообщение от pincet Посмотреть сообщение
как option(recompile) повлияет на param sniffing?
А тут точно param sniffing? С ходу больше похоже на использование локальной переменной с вытекающими отсюда нюансами использования статистики
0
2 / 2 / 0
Регистрация: 18.09.2022
Сообщений: 242
03.04.2025, 16:27  [ТС]
Цитата Сообщение от Andrey-MSK Посмотреть сообщение
2022N2022, RECOMPILE
я посмотрел, но до конца непонятно. Изначально, когда я создал запрос и запустил его первый раз оптимизатор, насколько я понимаю, должен был как бы с нуля разобрать запрос и выполнить его. И должно быть изначально одинаковое время исполнения. Если я потом модифицировал этот запрос как-то, то да, возможно оптимизатор стал бы использовать старый план, а с помощью recompile ему дается указание на то, чтобы снова все пересчитать
0
1304 / 358 / 97
Регистрация: 14.10.2022
Сообщений: 1,087
03.04.2025, 16:27
Цитата Сообщение от katamoto Посмотреть сообщение
А тут точно param sniffing? С ходу больше похоже на использование локальной переменной с вытекающими отсюда нюансами использования статистики
А вот и проверьте. Запустите сначала с option(recompile), а потом с OPTION (USE HINT ('DISABLE_PARAMETER_SNIFFING'))
Этот хинт то ли с 2017, толи с 2019 работает (или вообще с 2016SP2).
Цитата Сообщение от 2022N2022 Посмотреть сообщение
А можно объяснить тупому, почему только с option (recompile) это работает? вроде бы и просто так должно работать...
А оно и так работает. Только в первом случае оно создает параметризованный запрос, и выдергивает его план из кэша планов, а во втором - создает adhoc запрос, заменяя переменные конкретным значением, причем, возможно, проведя некую оптимизацию, вроде приведения литералов к опр. типам.
0
 Аватар для Andrey-MSK
3317 / 2204 / 387
Регистрация: 14.08.2018
Сообщений: 7,411
Записей в блоге: 4
03.04.2025, 16:49
2022N2022, RECOMPILE создаёт временный план запроса, который оптимизирован под текущее значение параметра, делает из параметра константу, выполняет его и удаляет план. И каждый раз при замене значения будет создаваться новый оптимизированный план именно под это значение.
1
2 / 2 / 0
Регистрация: 18.09.2022
Сообщений: 242
03.04.2025, 18:37  [ТС]
Правильно я понимаю, что в любом скрипте, в котором есть переменные, значение которых получается из каких-либо запросов, необходимо использовать option recompil если необходима максимальная скорость выполнения
0
139 / 105 / 36
Регистрация: 27.07.2022
Сообщений: 357
03.04.2025, 20:02
Цитата Сообщение от uaggster Посмотреть сообщение
А вот и проверьте. Запустите сначала с option(recompile), а потом с OPTION (USE HINT ('DISABLE_PARAMETER_SNIFFING'))
Т.е. сами не проверяли? Чисто теоретически, как там может быть parameter sniffing, если фильтруем по одному и тому же значению в обоих случаях?

Я немного потыкал в студии и вижу, что в первом случае, с локальной переменной, оптимизатор опирается на density vector, а во втором - на гистограмму. Но надо смотреть, какие там у топикстартера планы и статистики, конечно. Пока всё это на кофейной гуще

Добавлено через 2 минуты
Цитата Сообщение от 2022N2022 Посмотреть сообщение
Правильно я понимаю, что в любом скрипте, в котором есть переменные, значение которых получается из каких-либо запросов, необходимо использовать option recompil если необходима максимальная скорость выполнения
It depends. Если у вас запрос пуляется 10500 раз в секунду, то вы скорее всего не заходите каждый раз его перекомпилировать, это затратно по cpu. Для не особо частых - вполне себе
0
1304 / 358 / 97
Регистрация: 14.10.2022
Сообщений: 1,087
03.04.2025, 21:26
Цитата Сообщение от katamoto Посмотреть сообщение
Т.е. сами не проверяли? Чисто теоретически, как там может быть parameter sniffing, если фильтруем по одному и тому же значению в обоих случаях?
Не подтверждается :-)
В том смысле, что ничего не подтверждается, все строго одинаково, с точностью до получения запросом ресурсов на исполнение и прогрева кэша.
T-SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
Set statistics io on; 
Set statistics time on;
 
Use testdb
go
 
DROP TABLE IF EXISTS test
GO
 
CREATE TABLE test(
id INT IDENTITY(1,1) NOT NULL,
dt DATE)
GO
 
INSERT test (dt)
Select Case when (ABS(CHECKSUM(NEWID())) % 10) % 2 = 1 then Dateadd(day,(ABS(CHECKSUM(NEWID())) % 10) ,'2024-12-01')
else Dateadd(day,(ABS(CHECKSUM(NEWID())) % 10) ,'2024-12-01')
End
from string_split(Replicate(Cast(' ' as varchar(max)), 1000000), ' ') t
 
GO
 
DECLARE @val DATE;
Print '--------------------------------------------------'
Print 'SET @val=(SELECT MIN(dt) FROM test)'
SET @val=(SELECT MIN(dt) FROM test)
Print '--------------------------------------------------'
Print 'SELECT * FROM test WHERE dt=@val'
SELECT * FROM test WHERE dt=@val
Print '--------------------------------------------------'
print 'SELECT * FROM test WHERE dt=''20241201'''
SELECT * FROM test WHERE dt='20241201'
Print '--------------------------------------------------'
print 'SELECT * FROM test WHERE dt=@val option(recompile)'
SELECT * FROM test WHERE dt=@val option(recompile)
Print '--------------------------------------------------'
print 'SELECT * FROM test WHERE dt=@val OPTION (USE HINT (''DISABLE_PARAMETER_SNIFFING''))'
SELECT * FROM test WHERE dt=@val OPTION (USE HINT ('DISABLE_PARAMETER_SNIFFING'))
Результат:

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.
 
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
 
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
 
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.
 
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 4 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.
 
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 2 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 3 ms.
Table 'test'. Scan count 0, logical reads 1003718, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 4000013, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 5017768, lob physical reads 0, lob page server reads 0, lob read-ahead reads 490440, lob page server read-ahead reads 0.
 
 SQL Server Execution Times:
   CPU time = 6265 ms,  elapsed time = 6391 ms.
 
(1000001 rows affected)
SQL Server parse and compile time: 
   CPU time = 168 ms, elapsed time = 168 ms.
--------------------------------------------------
 
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
SET @val=(SELECT MIN(dt) FROM test)
 
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
Table 'test'. Scan count 1, logical reads 3718, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.
 
 SQL Server Execution Times:
   CPU time = 140 ms,  elapsed time = 145 ms.
--------------------------------------------------
 
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
SELECT * FROM test WHERE dt=@val
 
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
 
(99904 rows affected)
Table 'test'. Scan count 1, logical reads 3718, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.
 
 SQL Server Execution Times:
   CPU time = 157 ms,  elapsed time = 156 ms.
--------------------------------------------------
 
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
SELECT * FROM test WHERE dt='20241201'
 
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 1 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.
 
(99904 rows affected)
Table 'test'. Scan count 1, logical reads 3718, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.
 
 SQL Server Execution Times:
   CPU time = 156 ms,  elapsed time = 156 ms.
--------------------------------------------------
 
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
SELECT * FROM test WHERE dt=@val option(recompile)
 
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.
 
(99904 rows affected)
Table 'test'. Scan count 1, logical reads 3718, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.
 
 SQL Server Execution Times:
   CPU time = 140 ms,  elapsed time = 153 ms.
--------------------------------------------------
 
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
SELECT * FROM test WHERE dt=@val OPTION (USE HINT ('DISABLE_PARAMETER_SNIFFING'))
 
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
 
(99904 rows affected)
Table 'test'. Scan count 1, logical reads 3718, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.
 
 SQL Server Execution Times:
   CPU time = 156 ms,  elapsed time = 157 ms.
 
Completion time: 2025-04-03T22:23:40.4503924+04:00
0
139 / 105 / 36
Регистрация: 27.07.2022
Сообщений: 357
03.04.2025, 21:49
Цитата Сообщение от uaggster Посмотреть сообщение
Не подтверждается :-)
В том смысле, что ничего не подтверждается, все строго одинаково, с точностью до получения запросом ресурсов на исполнение и прогрева кэша.
На равномерно распределённых данных - ну да, кто бы сомневался...

P.S. Плюс индекс нужен по dt, иначе, ясно дело, всё в банальный table scan в любом случае свалится. Ну, и кластерный по id, скорее всего. Не вижу других вариантов, чтоб получить описываемую ситуацию
0
 Аватар для Andrey-MSK
3317 / 2204 / 387
Регистрация: 14.08.2018
Сообщений: 7,411
Записей в блоге: 4
04.04.2025, 10:54
Цитата Сообщение от 2022N2022 Посмотреть сообщение
в котором есть переменные
В котором они есть и не важно откуда берутся их значения.
2022N2022,
Цитата Сообщение от katamoto Посмотреть сообщение
это затратно по cpu
Оберните такие запросы в хранимку и всё будет нормально, сервер сам их оптимизирует.

Что самое интересное, если вызывать запросы вот так
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
public async Task<List<LaborHBHeader>> GetLaborHBHeadersAsync(Branches branch)
{
    List<LaborHBHeader> headers = new List<LaborHBHeader>();
    string sqlText = "SELECT ID_LaborHB, ID_Branch, DateHB, DecreeHB, VersionHB FROM dbo.tblLaborHB_00 WHERE ID_Branch = @idBranch ORDER BY DateHB";
 
    try
    {
        using (SqlConnection sqlConnection = new SqlConnection(_connectionString))
        {
            using (SqlCommand sqlCommand = new SqlCommand(sqlText, sqlConnection))
            {
                SqlParameter pBranchID = new SqlParameter
                {
                    ParameterName = "@idBranch",
                    Value = (int)branch,
                    SqlDbType = SqlDbType.Int,
                    Direction = ParameterDirection.Input
                };
                sqlCommand.Parameters.Add(pBranchID);
 
                await sqlCommand.Connection.OpenAsync();
 
                using (SqlDataReader sqlDataReader = await sqlCommand.ExecuteReaderAsync())
                {
                    if (sqlDataReader.HasRows)
                    {
                        while (await sqlDataReader.ReadAsync())
                        {
                            headers.Add(new LaborHBHeader
                            {
                                LaborHBID = (int)sqlDataReader["ID_LaborHB"],
                                BranchID = (int)sqlDataReader["ID_Branch"],
                                DateHB = (DateTime)sqlDataReader["DateHB"],
                                DescreeHB = (string)sqlDataReader["DecreeHB"],
                                VersionHB = (int)sqlDataReader["VersionHB"]
                            });
                        }
                    }
                }
            }
        }
 
        return headers;
    }
    catch (SqlException sqlEx)
    {
        throw new ApplicationException(string.Format("T-SQL #{0} - {1}", sqlEx.Number, sqlEx.Message), sqlEx);
    }
    catch (Exception ex)
    {
        throw new ApplicationException(ex.Message, ex);
    }
}
то значения параметров всегда вычисляются перед выполнением запроса и идут как константы

Добавлено через 21 минуту
То бишь план всегда оптимизирован под эти значения. Вот такая особенность
0
139 / 105 / 36
Регистрация: 27.07.2022
Сообщений: 357
04.04.2025, 10:57
Цитата Сообщение от Andrey-MSK Посмотреть сообщение
Оберните такие запросы в хранимку и всё будет нормально, сервер сам их оптимизирует.
С recompile? Каким образом оптимизирует?

Цитата Сообщение от Andrey-MSK Посмотреть сообщение
Что самое интересное, если вызывать запросы вот так то значения параметров всегда вычисляются перед выполнением запроса и идут как константы
Тут ничего не могу сказать только по этому коду, не разраб. Надо смотреть, что там на стороне базы происходит при этом
0
668 / 291 / 120
Регистрация: 12.04.2022
Сообщений: 1,000
04.04.2025, 11:05
Цитата Сообщение от uaggster Посмотреть сообщение
все строго одинаково
Ммм, ну я бы сказал, что всё строго разно (за исключением первого и последнего оператора)

T-SQL
1
SELECT * FROM test WHERE dt=@val
Не использует прослушивание параметра, план компилится под 30%.

T-SQL
1
SELECT * FROM test WHERE dt='20241201'
Тут, вообще Simple parameterization с прослушиванием параметра (компиляцией плана со значением dt='20241201')

T-SQL
1
SELECT * FROM test WHERE dt=@val option(recompile)
Тут, нет параметров вообще.

T-SQL
1
SELECT * FROM test WHERE dt=@val OPTION (USE HINT ('DISABLE_PARAMETER_SNIFFING'))
Здесь, как и ожидалось прослушивание отключено, план компилится под 30%.
1
1304 / 358 / 97
Регистрация: 14.10.2022
Сообщений: 1,087
04.04.2025, 11:07
Цитата Сообщение от katamoto Посмотреть сообщение
P.S. Плюс индекс нужен по dt, иначе, ясно дело, всё в банальный table scan в любом случае свалится. Ну, и кластерный по id, скорее всего. Не вижу других вариантов, чтоб получить описываемую ситуацию
Всё равно не подтверждается.
T-SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
Set statistics io on; 
Set statistics time on;
 
Use testdb
go
 
DROP TABLE IF EXISTS test
GO
 
CREATE TABLE test(
id INT IDENTITY(1,1) NOT NULL primary key clustered,
dt DATE, index ix_dt (dt))
GO
 
INSERT test (dt)
Select Case when (ABS(CHECKSUM(NEWID())) % 10) % 2 = 1 then Dateadd(day,(ABS(CHECKSUM(NEWID())) % 10) ,'2024-12-01')
else Dateadd(month,(ABS(CHECKSUM(NEWID())) % 10) ,'2024-12-01')
End
from string_split(Replicate(Cast(' ' as varchar(max)), 10000000), ' ') t
 
GO
 
DECLARE @val DATE;
Print '--------------------------------------------------'
Print 'SET @val=(SELECT MIN(dt) FROM test)'
SET @val=(SELECT MIN(dt) FROM test)
Print '--------------------------------------------------'
Print 'SELECT * FROM test WHERE dt=@val'
SELECT * FROM test WHERE dt=@val
Print '--------------------------------------------------'
print 'SELECT * FROM test WHERE dt=''20241201'''
SELECT * FROM test WHERE dt='20241201'
Print '--------------------------------------------------'
print 'SELECT * FROM test WHERE dt=@val option(recompile)'
SELECT * FROM test WHERE dt=@val option(recompile)
Print '--------------------------------------------------'
print 'SELECT * FROM test WHERE dt=@val OPTION (USE HINT (''DISABLE_PARAMETER_SNIFFING''))'
SELECT * FROM test WHERE dt=@val OPTION (USE HINT ('DISABLE_PARAMETER_SNIFFING'))
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.
 
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
 
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
 
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.
 
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 4 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.
 
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 4 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 2 ms.
Table 'test'. Scan count 0, logical reads 60098934, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 40000013, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 50185737, lob physical reads 0, lob page server reads 0, lob read-ahead reads 43890720, lob page server read-ahead reads 0.
 
 SQL Server Execution Times:
   CPU time = 104844 ms,  elapsed time = 105916 ms.
 
(10000001 rows affected)
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.
--------------------------------------------------
 
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
SET @val=(SELECT MIN(dt) FROM test)
 
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
SQL Server parse and compile time: 
   CPU time = 251 ms, elapsed time = 251 ms.
Table 'test'. Scan count 1, logical reads 3, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.
 
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
--------------------------------------------------
 
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
SELECT * FROM test WHERE dt=@val
 
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 1 ms.
 
(998600 rows affected)
Table 'test'. Scan count 1, logical reads 3360, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.
 
 SQL Server Execution Times:
   CPU time = 469 ms,  elapsed time = 7523 ms.
--------------------------------------------------
 
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
SELECT * FROM test WHERE dt='20241201'
 
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 2 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.
 
(998600 rows affected)
Table 'test'. Scan count 1, logical reads 3360, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.
 
 SQL Server Execution Times:
   CPU time = 515 ms,  elapsed time = 9034 ms.
--------------------------------------------------
 
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
SELECT * FROM test WHERE dt=@val option(recompile)
 
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.
 
(998600 rows affected)
Table 'test'. Scan count 1, logical reads 3360, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.
 
 SQL Server Execution Times:
   CPU time = 610 ms,  elapsed time = 9904 ms.
--------------------------------------------------
 
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
SELECT * FROM test WHERE dt=@val OPTION (USE HINT ('DISABLE_PARAMETER_SNIFFING'))
 
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 1 ms.
 
(998600 rows affected)
Table 'test'. Scan count 1, logical reads 3360, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.
 
 SQL Server Execution Times:
   CPU time = 672 ms,  elapsed time = 9004 ms.
 
Completion time: 2025-04-04T12:04:19.4482201+04:00
Цитата Сообщение от katamoto Посмотреть сообщение
На равномерно распределённых данных - ну да, кто бы сомневался...
Там как раз НЕ равномерно распределенные данные.

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
Statistics for INDEX 'ix_dt'.
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 
                            Name                         Updated                            Rows                    Rows Sampled                           Steps                         Density              Average Key Length                    String Index
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
                           ix_dt             Apr  4 2025 11:03AM                        10000001                          384670                              19                               0                               7                             NO                                                         10000001                               0
 
                     All Density                  Average Length                         Columns
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
                      0.05263158                               3                              dt
                    2.572493E-06                               7                          dt, id
 
                 Histogram Steps
                    RANGE_HI_KEY                      RANGE_ROWS                         EQ_ROWS             DISTINCT_RANGE_ROWS                  AVG_RANGE_ROWS
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
              01.12.2024 0:00:00                               0                        996412,6                               0                               1
              02.12.2024 0:00:00                               0                        495567,7                               0                               1
              03.12.2024 0:00:00                               0                        501728,8                               0                               1
              04.12.2024 0:00:00                               0                        501156,9                               0                               1
              05.12.2024 0:00:00                               0                        493929,9                               0                               1
              06.12.2024 0:00:00                               0                        496867,5                               0                               1
              07.12.2024 0:00:00                               0                        501494,8                               0                               1
              08.12.2024 0:00:00                               0                        499155,2                               0                               1
              09.12.2024 0:00:00                               0                        501026,9                               0                               1
              10.12.2024 0:00:00                               0                        500870,9                               0                               1
              01.01.2025 0:00:00                               0                          507370                               0                               1
              01.02.2025 0:00:00                               0                        494501,8                               0                               1
              01.03.2025 0:00:00                               0                        506486,1                               0                               1
              01.04.2025 0:00:00                               0                        501260,9                               0                               1
              01.05.2025 0:00:00                               0                        505576,3                               0                               1
              01.06.2025 0:00:00                               0                        497101,5                               0                               1
              01.07.2025 0:00:00                               0                        495411,7                               0                               1
              01.08.2025 0:00:00                               0                        498011,3                               0                               1
              01.09.2025 0:00:00                               0                        506070,2                               0                               1
0
 Аватар для Andrey-MSK
3317 / 2204 / 387
Регистрация: 14.08.2018
Сообщений: 7,411
Записей в блоге: 4
04.04.2025, 11:17
Цитата Сообщение от katamoto Посмотреть сообщение
Каким образом оптимизирует?
Либо OPTION(RECOMPILE), либо сделать из запроса хранимку - результат будет одинаковый. План будет одинаковый, сколько раз замечал такое. Без опции, если просто запрос, то вызывается куча LOOP для поиска, а если его обернуть в ХП, то сразу всё приходит в норму. Да и писали про это не раз...
Цитата Сообщение от katamoto Посмотреть сообщение
Надо смотреть, что там на стороне базы происходит при этом
SSMS показывает как обычно
T-SQL
1
@id = 23
но при этом план запроса получается как с опцией RECOMPILE. Видать особенность класса SqlCommand()...
0
139 / 105 / 36
Регистрация: 27.07.2022
Сообщений: 357
04.04.2025, 11:54
Цитата Сообщение от uaggster Посмотреть сообщение
Всё равно не подтверждается.
Давай так

T-SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
Set statistics io on; 
Set statistics time on;
 
Use tempdb
go
 
DROP TABLE IF EXISTS test
GO
 
CREATE TABLE test(
id INT IDENTITY(1,1) NOT NULL primary key clustered,
dt DATE, index ix_dt (dt),
payload UNIQUEIDENTIFIER CONSTRAINT df_payload DEFAULT(NEWID()))
GO
 
INSERT test (dt)
VALUES ('2024-12-01')
 
INSERT test (dt)
Select Case when (ABS(CHECKSUM(NEWID())) % 10) % 2 = 1 then Dateadd(day,(ABS(CHECKSUM(NEWID())) % 10) ,'2024-12-02')
else Dateadd(month,(ABS(CHECKSUM(NEWID())) % 10) ,'2024-12-02')
End
from string_split(Replicate(Cast(' ' as varchar(max)), 1000000), ' ') t
 
GO
 
DECLARE @val DATE;
Print '--------------------------------------------------'
Print 'SET @val=(SELECT MIN(dt) FROM test)'
SET @val=(SELECT MIN(dt) FROM test)
Print '--------------------------------------------------'
Print 'SELECT * FROM test WHERE dt=@val'
SELECT * FROM test WHERE dt=@val
Print '--------------------------------------------------'
print 'SELECT * FROM test WHERE dt=''20241201'''
SELECT * FROM test WHERE dt='20241201'
Print '--------------------------------------------------'
print 'SELECT * FROM test WHERE dt=@val option(recompile)'
SELECT * FROM test WHERE dt=@val option(recompile)
Print '--------------------------------------------------'
print 'SELECT * FROM test WHERE dt=@val OPTION (USE HINT (''DISABLE_PARAMETER_SNIFFING''))'
SELECT * FROM test WHERE dt=@val OPTION (USE HINT ('DISABLE_PARAMETER_SNIFFING'))
Добавлено через 1 минуту
Цитата Сообщение от Andrey-MSK Посмотреть сообщение
Либо OPTION(RECOMPILE), либо сделать из запроса хранимку - результат будет одинаковый. План будет одинаковый, сколько раз замечал такое. Без опции, если просто запрос, то вызывается куча LOOP для поиска, а если его обернуть в ХП, то сразу всё приходит в норму. Да и писали про это не раз..
Просто запрос - это что имеется в виду? В ssms?
0
 Аватар для Andrey-MSK
3317 / 2204 / 387
Регистрация: 14.08.2018
Сообщений: 7,411
Записей в блоге: 4
04.04.2025, 11:57
Цитата Сообщение от katamoto Посмотреть сообщение
В ssms?
Ага. Просто SELECT с параметрами...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
04.04.2025, 11:57
Помогаю со студенческими работами здесь

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

Периодическое увеличение времени исполнения запроса при вставке
Пишу на go запрос к бд на postgres ради теста веб сервиса. Начал с 1000 запросов подряд с интервалом от 0 до 100мс. Запрос простой ...

Громадное время исполнения "тяжелого" скрипта
Dion (19.04.2006) Неплохая идея, кстати. Правда я нифига в T-SQL не понимаю... А хранимые процедуры пишутся только на этом языке,...

Union all в Access - увеличение времени исполнения?
Есть 2 запроса Q1 и Q2 Время выполнения Q1 - 6 сек, Q2 - 4 сек Ok, надо UNION ALL этих запросов. SELECT * FROM Q1 UNION ALL ...

Разработать информационную систему "контроль исполнения поручений" для некоторой организации
Помогите,плиз, сделать задание по Access... Вариант1. Разработать информационную систему КОНТРОЛЬ ИСПОЛНЕНИЯ ПОРУЧЕНИЙ для некоторой...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru