Когда я смотрю на фактический план выполнения некоторых из моих запросов, я замечаю, что литеральные константы, используемые в предложении WHERE, отображаются в виде вложенной цепочки вычисления скаляра и константы сканирования .
Чтобы воспроизвести это, я использую следующую таблицу
CREATE TABLE Table1 (
[col1] [bigint] NOT NULL,
[col2] [varchar](50) NULL,
[col3] [char](200) NULL
)
CREATE NONCLUSTERED INDEX IX_Table1 ON Table1 (col1 ASC)
С некоторыми данными в нем:
INSERT INTO Table1(col1) VALUES (1),(2),(3),
(-9223372036854775808),
(9223372036854775807),
(2147483647),(-2147483648)
Когда я запускаю следующий (бессмысленный) запрос:
SELECT a.col1, a.col2
FROM Table1 a, Table1 b
WHERE b.col1 > 2147483648
Я вижу, что он выполнит рисование Nested Loop в результате поиска по индексу и скалярного вычисления (из константы).
Обратите внимание, что литерал больше, чем maxint. Это помогает писать CAST(2147483648 as BIGINT)
. Любая идея, почему MSSQL откладывает это на план выполнения и есть более короткий способ избежать этого, чем использование приведения? Влияет ли это на параметры привязки к подготовленным операторам (из jtds JDBC)?
Скалярное вычисление не всегда выполняется (кажется, что поиск по индексу специфичен). И иногда анализатор запросов показывает его не графически, а col1 < scalar(expr1000)
в свойствах предиката.
Я видел это с MS SSMS 2016 (13.0.16100.1) и SQL Server 2014 Expres Edition 64bit на Windows 7, но я предполагаю, что это общее поведение.