Đảm bảo rằng bạn xóa thực thi + bộ nhớ đệm dữ liệu giữa mỗi lần chạy thử nghiệm.
ví dụ:
DBCC FREEPROCCACHE
DBCC DROPCLEANBUFFERS
Nếu bạn chạy với UNION ALL trước và sau đó chạy 2 lựa chọn riêng biệt sau đó, dữ liệu sẽ được lưu vào bộ nhớ đệm trong bộ nhớ làm cho hiệu suất tốt hơn nhiều (do đó tạo ấn tượng sai rằng cách tiếp cận tiếp theo nhanh hơn khi có thể không).
Nếu bạn đã sử dụng UNION thì điều đó cũng có thể chậm hơn vì nó phải áp dụng DISTINCT, nhưng UNION ALL không phải làm điều đó, vì vậy nó sẽ không có gì khác biệt.
Cập nhật:
Hãy xem các kế hoạch thực hiện và so sánh chúng - xem có sự khác biệt nào không. Bạn có thể xem kế hoạch thực thi bằng cách nhấp vào nút "Bao gồm kế hoạch thực thi thực tế" trong SSMS trước khi chạy truy vấn
Cập nhật 2:
Dựa trên các CTE đầy đủ được đưa ra, tôi nghĩ rằng tôi đang xem xét việc tối ưu hóa các CTE đó - tôi không nghĩ rằng UNION ALL thực sự là vấn đề.
IMHO, điều tốt nhất nên thử là làm việc với từng CTE và cố gắng tối ưu hóa từng CTE riêng lẻ để khi bạn kết hợp tất cả chúng trong truy vấn chính, chúng hoạt động tốt hơn.
ví dụ. đối với tDictionaryStreets, hãy thử cách này:
SELECT DISTINCT
r.KladrItemName AS RegionName,
a.KladrItemName AS AreaName,
c.KladrItemName AS CityName,
sc.KladrItemName AS SubCityName,
s.StreetName
FROM StreetNames s
JOIN tFoundStreets fs ON s.StreetName = fs.KladrItemName
LEFT JOIN tFoundRegions r ON s.RegionName = r.KladrItemName
LEFT JOIN tFoundAreas a ON s.AreaName = a.KladrItemName
LEFT JOIN tFoundCities c ON s.CityName = c.KladrItemName
LEFT JOIN tFoundSubCities sc ON s.SubCityName = scc.KladrItemName
KladrItemName trên mỗi bảng ít nhất phải có chỉ mục. Hãy thử làm lại tDictionarySubCities theo cùng một cách với các phép nối.