ทำไม SELECT COUNT () แผนการดำเนินการแบบสอบถามรวมตารางเข้าร่วมด้านซ้าย


9

ใน SQL Server 2012 ฉันมีตารางที่มีฟังก์ชั่นที่มีค่าเมื่อเข้าร่วมกับตารางอื่นฉันต้องนับจำนวนแถวสำหรับ 'ฟังก์ชั่นที่มีค่าของตาราง' เมื่อฉันตรวจสอบแผนการดำเนินการฉันจะเห็นตารางเข้าร่วมด้านซ้าย ทำไม? การเข้าร่วมตารางด้านซ้ายจะมีผลต่อจำนวนแถวที่คืนกลับอย่างไร ฉันคาดหวังว่าโปรแกรม db ไม่จำเป็นต้องประเมินตารางร่วมด้านซ้ายในแบบสอบถามจำนวน count (.. )

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

แผนการดำเนินการ:

ป้อนคำอธิบายรูปภาพที่นี่

ฟังก์ชั่นมูลค่าตาราง:

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
)

UPDATE:

ฉันเพิ่มดัชนีเฉพาะเพื่อติดตามแนวคิดของ Rob Farley:

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

และจัดทำดัชนีที่แนะนำโดย DB Engine:

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

([OwnerId] ASC) รวม ([Id], [okresId], [obecId], [pobvodId]) GO

เพื่อความเรียบง่ายฉันลบเงื่อนไข

WHERE Person.ConfirmStatus = 1

จากฟังก์ชั่นมูลค่า tabled ด้านบน

ตอนนี้แผนการดำเนินการนั้นง่ายกว่ามาก แต่ก็ยังคงสัมผัสกับตาราง ExternFile:

ป้อนคำอธิบายรูปภาพที่นี่

เซิร์ฟเวอร์ sql อาจไม่ฉลาดพอใช่ไหม

คำตอบ:


12

หากForeignId, ForeignTable, IsMainไม่ทราบว่าเป็น * ที่ไม่ซ้ำใครExternFileQO จะต้องรวมตารางนั้นเพื่อคำนวณจำนวน เมื่อใดก็ตามที่ตรงกันหลายแถวการนับจะได้รับผลกระทบ

เข้าร่วมความเรียบง่ายใน
การออกแบบเซิร์ฟเวอร์ SQL เพื่อความเรียบง่าย (การบันทึก SQLBits)


* ขณะนี้เครื่องมือเพิ่มประสิทธิภาพไม่รู้จักดัชนีที่ไม่ซ้ำที่กรองแล้วว่าไม่ซ้ำกัน

UPDATE (โดย OP) : การแก้ปัญหาคือการเปลี่ยนบรรทัดในแบบสอบถามจากซ้ายเข้าร่วม (ซึ่งสามารถผลิตหลายแถว):

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

ถึงภายนอกใช้กับ TOP (ซึ่งสร้างหนึ่งแถวและไม่ส่งผลกระทบต่อ COUNT)

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

แบบสอบถามตอนนี้มีประสิทธิภาพมากขึ้น ไม่สามารถเพิ่มดัชนีที่ไม่ซ้ำกันได้เนื่องจากค่าไม่ได้เป็นค่าเฉพาะสำหรับการรวมกันในเงื่อนไขและไม่ถือว่าเป็นค่าที่ไม่ซ้ำกันดังที่ได้กล่าวไว้ข้างต้น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.