Quando osservo il piano di exection reale di alcune delle mie query, noto che le costanti letterali utilizzate in una clausola WHERE si presentano come una catena nidificata di calcoli di scansione scalare e costante .
Per riprodurre questo, uso la seguente tabella
CREATE TABLE Table1 (
[col1] [bigint] NOT NULL,
[col2] [varchar](50) NULL,
[col3] [char](200) NULL
)
CREATE NONCLUSTERED INDEX IX_Table1 ON Table1 (col1 ASC)
Con alcuni dati al suo interno:
INSERT INTO Table1(col1) VALUES (1),(2),(3),
(-9223372036854775808),
(9223372036854775807),
(2147483647),(-2147483648)
Quando eseguo la seguente query (senza senso):
SELECT a.col1, a.col2
FROM Table1 a, Table1 b
WHERE b.col1 > 2147483648
Vedo che eseguirà un disegno ad anello annidato nel risultato di Index Seek e un calcolo scalare (da una costante).
Si noti che il valore letterale è maggiore di maxint. Aiuta a scrivere CAST(2147483648 as BIGINT)
. Qualche idea sul perché MSSQL lo sta deframmentando al piano di esecuzione ed esiste un modo più breve per evitarlo rispetto all'utilizzo del cast? Influisce anche sui parametri associati alle istruzioni preparate (da jtds JDBC)?
Il calcolo scalare non viene sempre eseguito (sembra essere un indice specifico per la ricerca ). E a volte l'analizzatore di query non lo mostra graficamente ma come col1 < scalar(expr1000)
nelle proprietà del predicato.
Ho visto questo con MS SSMS 2016 (13.0.16100.1) e SQL Server 2014 Expres Edition 64 bit su Windows 7, ma suppongo sia un comportamento generale.