Neden SELECT COUNT () sorgu yürütme planı solda birleştirilmiş tablo içeriyor?


9

SQL Server 2012'de tablo değeri fonksiyonu başka bir tabloya katılmak ile bu 'tablo değerli işlevi' için satır sayısını saymak gerekir. İcra planını incelediğimde, sol birleştirme tablosunu görebiliyorum. Neden? Birleştirilen soldaki tablo, döndürülen satır sayısını nasıl etkiler? Ben db motoru SELECT sayısı (..) sorgusunda sol ortak tablo değerlendirmek gerekmez beklenir.

Select count(realtyId) FROM [dbo].[GetFilteredRealtyFulltext]('"praha"')

Uygulama planı:

resim açıklamasını buraya girin

Tablo değerli fonksiyonu:

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
)

GÜNCELLEME:

Rob Farley fikrini takip etmek için benzersiz bir dizin ekliyorum:

 Create unique nonclustered index ExternFileIsMainUnique ON ExternFile(ForeignId) WHERE IsMain = 1 AND ForeignTable = 5

DB Engine tarafından önerilen dizin:

CREATE NONCLUSTERED INDEX [RealtyOwnerLocation] ON [dbo].[Realty]

([OwnerId] ASC) DAHİL ([Kimlik], [okresId], [obecId], [pobvodId]) GO

Basitlik için koşulu kaldırıyorum

WHERE Person.ConfirmStatus = 1

yukarıdaki tablolanmış değerli fonksiyondan.

Şimdi yürütme planı çok daha basit ama yine de ExternFile tablosuna dokunuyor:

resim açıklamasını buraya girin

Belki sql server yeterince zeki değil?

Yanıtlar:


12

Eğer ForeignId, ForeignTable, IsMainbenzersiz in olmak * bilinmemektedir ExternFile, daha sonra QO sayımı dışarı çalışmalarına bu tabloyu eklenmesi gerekmektedir. Birden çok satır eşleştiğinde sayı etkilenir.

Basitleştirme için SQL Server
Tasarımında Basitleştirmeye Katılın (SQLBits kaydı)


* Optimize edici şu anda filtrelenmiş benzersiz dizinleri benzersiz olarak tanımıyor

GÜNCELLEME (OP ile) : Çözüm, LEFT JOIN (birden çok satır üretebilen) sorgu satırını değiştirmektir:

LEFT JOIN ExternFile ON realty.Id = ExternFile.ForeignId AND ExternFile.IsMain = 1 AND ExternFile.ForeignTable = 5

TOP ile BAŞVURUN (bir satır üreten ve COUNT değeri etkilemeyen)

OUTER APPLY (SELECT TOP (1) ServerPath FROM ExternFile WHERE ForeignId = realty.Id AND IsMain = 1 AND ForeignTable = 5) AS ExternFile

Sorgu artık daha etkili. Değerler benzersiz olmadığından, benzersiz bir dizin eklemek gerçekleştirilemedi, yalnızca koşuldaki kombinasyon için benzersizdi ve bu, yukarıda belirtildiği gibi benzersiz olarak kabul edilmedi .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.