La creazione di un banco di prova, piuttosto semplice, su SQL Server 2012 (11.0.6020) mi consente di ricreare un piano con due query con hash corrispondenti concatenate tramite a UNION ALL
. Il mio banco di prova non visualizza la stima errata che vedi. Forse questo è un problema di SQL Server 2014 CE.
Ottengo una stima di 133.785 righe per una query che in realtà restituisce 280 righe, tuttavia è prevedibile, come vedremo più avanti in basso:
IF OBJECT_ID('dbo.Union1') IS NOT NULL
DROP TABLE dbo.Union1;
CREATE TABLE dbo.Union1
(
Union1_ID INT NOT NULL
CONSTRAINT PK_Union1
PRIMARY KEY CLUSTERED
IDENTITY(1,1)
, Union1_Text VARCHAR(255) NOT NULL
, Union1_ObjectID INT NOT NULL
);
IF OBJECT_ID('dbo.Union2') IS NOT NULL
DROP TABLE dbo.Union2;
CREATE TABLE dbo.Union2
(
Union2_ID INT NOT NULL
CONSTRAINT PK_Union2
PRIMARY KEY CLUSTERED
IDENTITY(2,2)
, Union2_Text VARCHAR(255) NOT NULL
, Union2_ObjectID INT NOT NULL
);
INSERT INTO dbo.Union1 (Union1_Text, Union1_ObjectID)
SELECT o.name, o.object_id
FROM sys.objects o;
INSERT INTO dbo.Union2 (Union2_Text, Union2_ObjectID)
SELECT o.name, o.object_id
FROM sys.objects o;
GO
SELECT *
FROM dbo.Union1 u1
INNER HASH JOIN sys.objects o ON u1.Union1_ObjectID = o.object_id
UNION ALL
SELECT *
FROM dbo.Union2 u2
INNER HASH JOIN sys.objects o ON u2.Union2_ObjectID = o.object_id;
Penso che il motivo sia dovuto alla mancanza di statistiche per i due join risultanti che sono UNIONed. SQL Server deve fare ipotesi ponderate nella maggior parte dei casi sulla selettività delle colonne di fronte alla mancanza di statistiche.
Joe Sack ha una lettura interessante su questo qui .
Per un UNION ALL
, è sicuro dire che vedremo esattamente il numero totale di righe restituite da ciascun componente dell'unione, tuttavia poiché SQL Server sta usando le stime di riga per i due componenti di UNION ALL
, vediamo che aggiunge il totale delle righe stimate da entrambi richieste per elaborare il preventivo per l'operatore di concatenazione.
Nel mio esempio sopra, il numero stimato di righe per ogni porzione di UNION ALL
è 66.8927, che quando sommato è pari a 133.785, che vediamo per il numero stimato di righe per l'operatore di concatenazione.
Il piano di esecuzione effettivo per la query del sindacato sopra è simile a:
È possibile visualizzare il numero di righe "stimato" vs "effettivo". Nel mio caso, l'aggiunta del numero "stimato" di righe restituite dai due operatori di corrispondenza hash equivale esattamente all'importo mostrato dall'operatore di concatenazione.
Vorrei provare a ottenere output dalla traccia 2363 ecc. Come raccomandato nel post di Paul White che mostri nella tua domanda. In alternativa, è possibile provare a utilizzare OPTION (QUERYTRACEON 9481)
la query per ripristinare la versione 70 CE per vedere se "risolve" il problema.