Cái nhìn
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
Để đơn giản, giả sử rằng productMetadata
các cột ProductId, MetaId, Value
có ~ 87m hàng và có khoảng 400k hàng trong products
bảng.
Các truy vấn chung chống lại quan điểm này hoạt động hoàn hảo:
SELECT * FROM vProductList WHERE CalculatedPrice > 500
Kết quả truy vấn trong 2-4 giây (trên vpn và từ xa, vì vậy tôi rất tốt với điều đó).
Thay đổi số trên thành số đếm cũng nhanh không kém:
SELECT COUNT(*) from vProductList WHERE CalculatedPrice > 500
chạy trong cùng thời gian với lựa chọn thô, một lần nữa tôi thấy ổn. Có khoảng 10k sản phẩm đáp ứng tiêu chí này.
Tôi đã gặp hai trường hợp riêng biệt, nơi mọi thứ trở nên thực sự kỳ quặc và mất TUYỆT VỜI.
Đầu tiên
Thực hiện truy vấn đối với một trong các cột từ bảng cơ sở trong dạng xem:
SELECT * FROM vProductList WHERE Name = 'Hammer'
Truy vấn này mất một chút thời gian để chạy (20-30 giây) và trả về kết quả ~ 30k; tuy nhiên, một thay đổi nhỏ đối với truy vấn đã nói:
SELECT COUNT(*) FROM vProductList WHERE Name = 'Hammer'
mất mười ba PHÚT để trả lại số đếm ~ 30k.
Thứ hai
Làm một WHERE IN
truy vấn con
SELECT * FROM vProductList WHERE Id IN (SELECT ProductId FROM TableThatHasFKToProductId and ColumnInTable = 'Yes')
Truy vấn này trả về ~ 300k hàng và mất hai phút để trả về (phần lớn thời gian đó chỉ đơn giản là dành để tải dữ liệu vào SSMS tôi tin); tuy nhiên, thay đổi điều đó thành SELECT COUNT(*)
kết quả trong một truy vấn mất hai mươi phút.
SELECT COUNT(*) FROM vProductList WHERE Id IN (SELECT ProductId FROM TableThatHasFKToProductId and ColumnInTable = 'Yes')
Tại sao nó SELECT *
nhanh hơn SELECT COUNT
?
Tôi đang sử dụng Tổng thời gian thực hiện do SSMS cung cấp cho tất cả các thời gian được liệt kê ở đây.
Kế hoạch thực hiện
Lưu ý: Tôi đã thử sử dụng PasteThePlan nhưng nó vẫn báo cho biết gói của tôi không hợp lệ xml.