Trong SQL Server 2012, tôi có hàm có giá trị bảng với phép nối với bảng khác tôi cần đếm số lượng hàng cho 'hàm có giá trị bảng' này. Khi tôi kiểm tra kế hoạch thực hiện, tôi có thể thấy bảng tham gia bên trái. Tại sao? Làm thế nào có thể trái bảng tham gia ảnh hưởng số lượng hàng trả về? Tôi hy vọng rằng công cụ db không cần phải đánh giá bảng khớp bên trái trong truy vấn SELECT Count (..).
Select count(realtyId) FROM [dbo].[GetFilteredRealtyFulltext]('"praha"')
Kế hoạch thực hiện:
Hàm có giá trị bảng:
CREATE FUNCTION [dbo].[GetFilteredRealtyFulltext]
(@criteria nvarchar(4000))
RETURNS TABLE
AS
RETURN (SELECT
realty.Id AS realtyId,
realty.OwnerId,
realty.Caption AS realtyCaption,
realty.BusinessCategory,
realty.Created,
realty.LastChanged,
realty.LastChangedType,
realty.Price,
realty.Pricing,
realty.PriceCurrency,
realty.PriceNote,
realty.PricePlus,
realty.OfferState,
realty.OrderCode,
realty.PublishAddress,
realty.PublishMap,
realty.AreaLand,
realty.AreaCover,
realty.AreaFloor,
realty.Views,
realty.TopPoints,
realty.Radius,
COALESCE(realty.Wgs84X, ruian_cobce.Wgs84X, ruian_obec.Wgs84X) as Wgs84X,
COALESCE(realty.Wgs84Y, ruian_cobce.Wgs84Y, ruian_obec.Wgs84Y) as Wgs84Y,
realty.krajId,
realty.okresId,
realty.obecId,
realty.cobceId,
IsNull(CONVERT(int,realty.Ranking),0) as Ranking,
realty.energy_efficiency_rating,
realty.energy_performance_attachment,
realty.energy_performance_certificate,
realty.energy_performance_summary,
Category.Id AS CategoryId,
Category.ParentCategoryId,
Category.WholeName,
okres.nazev AS okres,
ruian_obec.nazev AS obec,
ruian_cobce.nazev AS cobce,
ExternFile.ServerPath,
Person.ParentPersonId,
( COALESCE(ftR.Rank,0) + COALESCE(ftObec.Rank,0) + COALESCE(ftOkres.Rank,0) + COALESCE(ftpobvod.Rank,0)) AS FtRank
FROM realty
JOIN Category ON realty.CategoryId = Category.Id
LEFT JOIN ruian_cobce ON realty.cobceId = ruian_cobce.cobce_kod
LEFT JOIN ruian_obec ON realty.obecId = ruian_obec.obec_kod
LEFT JOIN okres ON realty.okresId = okres.okres_kod
LEFT JOIN ExternFile ON realty.Id = ExternFile.ForeignId AND ExternFile.IsMain = 1 AND ExternFile.ForeignTable = 5
INNER JOIN Person ON realty.OwnerId = Person.Id
Left JOIN CONTAINSTABLE(Realty, *, @criteria) ftR ON realty.Id = ftR.[Key]
Left JOIN CONTAINSTABLE(ruian_obec, *, @criteria) ftObec ON realty.obecId = ftObec.[Key]
Left JOIN CONTAINSTABLE(Okres, *, @criteria) ftOkres ON realty.okresId = ftOkres.[Key]
Left JOIN CONTAINSTABLE(pobvod, *, @criteria) ftpobvod ON realty.pobvodId = ftpobvod.[Key]
WHERE Person.ConfirmStatus = 1
AND ( COALESCE(ftR.Rank,0) + COALESCE(ftObec.Rank,0) + COALESCE(ftOkres.Rank,0) + COALESCE(ftpobvod.Rank,0)) > 0
)
CẬP NHẬT:
Tôi thêm chỉ mục duy nhất để làm theo ý tưởng của Rob Farley:
Create unique nonclustered index ExternFileIsMainUnique ON ExternFile(ForeignId) WHERE IsMain = 1 AND ForeignTable = 5
Và được lập chỉ mục bởi DB Engine:
CREATE NONCLUSTERED INDEX [RealtyOwnerLocation] ON [dbo].[Realty]
([Chủ sở hữu] ASC) BAO GỒM ([Id], [okresId], [obecId], [pobvodId]) GO
Để đơn giản, tôi loại bỏ điều kiện
WHERE Person.ConfirmStatus = 1
từ chức năng có giá trị theo bảng ở trên.
Bây giờ kế hoạch thực hiện đơn giản hơn nhiều nhưng nó vẫn chạm vào bảng ExternFile:
Có lẽ máy chủ sql không đủ thông minh?