Die Aussicht
CREATE VIEW [dbo].[vProductList]
WITH SCHEMABINDING
AS
SELECT
p.[Id]
,p.[Name]
,price.[Value] as CalculatedPrice
,orders.[Value] as OrdersWithThisProduct
FROM
products as p
INNER JOIN productMetadata as price ON p.Id = price.ProductId AND price.MetaId = 1
INNER JOIN productMetadata as orders ON p.Id = orders.ProductId AND orders.MetaId = 2
Nehmen Sie der Einfachheit halber an, dass productMetadata
Spalten ProductId, MetaId, Value
~ 87 m Zeilen haben und die products
Tabelle ungefähr 400.000 Zeilen enthält .
Allgemeine Abfragen gegen diese Ansicht funktionieren einwandfrei:
SELECT * FROM vProductList WHERE CalculatedPrice > 500
Abfrageergebnisse in 2-4 Sekunden (über einen VPN und eine Fernbedienung, also bin ich gut damit).
Das Ändern der obigen Werte in eine Zählung ist ebenso schnell:
SELECT COUNT(*) from vProductList WHERE CalculatedPrice > 500
Läuft ungefähr zur gleichen Zeit wie die Rohauswahl, mit der ich wieder einverstanden bin. Es gibt ungefähr 10.000 Produkte, die diese Kriterien erfüllen.
Ich bin auf zwei verschiedene Fälle gestoßen, in denen die Dinge wirklich seltsam werden und für immer dauern.
Zuerst
Durchführen einer Abfrage für eine der Spalten aus der Basistabelle in der Ansicht:
SELECT * FROM vProductList WHERE Name = 'Hammer'
Die Ausführung dieser Abfrage dauert einige Zeit (20 bis 30 Sekunden) und liefert ~ 30.000 Ergebnisse. Eine geringfügige Änderung dieser Abfrage:
SELECT COUNT(*) FROM vProductList WHERE Name = 'Hammer'
Es dauert dreizehn Minuten, um eine Zählung mit ~ 30k zurückzugeben.
Zweite
Doing eine WHERE IN
Unterabfrage
SELECT * FROM vProductList WHERE Id IN (SELECT ProductId FROM TableThatHasFKToProductId and ColumnInTable = 'Yes')
Diese Abfrage gibt ~ 300.000 Zeilen zurück und dauert zwei Minuten, um zurückzukehren (ein Großteil dieser Zeit wird meines Erachtens einfach für das Herunterladen der Daten in SSMS aufgewendet). Wenn Sie dies jedoch SELECT COUNT(*)
in eine Abfrage ändern , dauert die Abfrage 20 Minuten.
SELECT COUNT(*) FROM vProductList WHERE Id IN (SELECT ProductId FROM TableThatHasFKToProductId and ColumnInTable = 'Yes')
Warum ist es SELECT *
schneller als SELECT COUNT
?
Ich verwende die von SSMS bereitgestellte Gesamtausführungszeit für alle hier aufgeführten Zeiten.
Ausführungspläne
Hinweis: Ich habe versucht, PasteThePlan zu verwenden, aber es wurde mir immer wieder mitgeteilt, dass der Plan eine ungültige XML-Datei ist.