ฉันมีคำถามดังนี้
DELETE FROM tblFEStatsBrowsers WHERE BrowserID NOT IN (
SELECT DISTINCT BrowserID FROM tblFEStatsPaperHits WITH (NOLOCK) WHERE BrowserID IS NOT NULL
)
tblFEStatsBrowsers มี 553 แถว
tblFEStatsPaperHits มีแถว 47.974.301
tblFEStatsBrowsers:
CREATE TABLE [dbo].[tblFEStatsBrowsers](
[BrowserID] [smallint] IDENTITY(1,1) NOT NULL,
[Browser] [varchar](50) NOT NULL,
[Name] [varchar](40) NOT NULL,
[Version] [varchar](10) NOT NULL,
CONSTRAINT [PK_tblFEStatsBrowsers] PRIMARY KEY CLUSTERED ([BrowserID] ASC)
)
tblFEStatsPaperHits:
CREATE TABLE [dbo].[tblFEStatsPaperHits](
[PaperID] [int] NOT NULL,
[Created] [smalldatetime] NOT NULL,
[IP] [binary](4) NULL,
[PlatformID] [tinyint] NULL,
[BrowserID] [smallint] NULL,
[ReferrerID] [int] NULL,
[UserLanguage] [char](2) NULL
)
มีดัชนีคลัสเตอร์บน tblFEStatsPaperHits ที่ไม่มี BrowserID การดำเนินการค้นหาภายในจึงต้องใช้การสแกนตารางแบบเต็มรูปแบบของ tblFEStatsPaperHits - ซึ่งใช้ได้ทั้งหมด
ปัจจุบันทำการสแกนเต็มรูปแบบสำหรับแต่ละแถวใน tblFEStatsBrowsers ซึ่งหมายความว่าฉันมีการสแกนตารางเต็มรูปแบบ 553 รายการของ tblFEStatsPaperHits
การเขียนซ้ำเป็นเพียงตำแหน่งที่ไม่ได้เปลี่ยนแผน:
DELETE FROM tblFEStatsBrowsers WHERE NOT EXISTS (
SELECT * FROM tblFEStatsPaperHits WITH (NOLOCK) WHERE BrowserID = tblFEStatsBrowsers.BrowserID
)
อย่างไรก็ตามตามคำแนะนำของ Adam Machanic การเพิ่มตัวเลือก HASH JOIN จะส่งผลให้แผนการดำเนินการที่ดีที่สุด (เพียงสแกน tblFEStatsPaperHits เพียงครั้งเดียว):
DELETE FROM tblFEStatsBrowsers WHERE NOT EXISTS (
SELECT * FROM tblFEStatsPaperHits WITH (NOLOCK) WHERE BrowserID = tblFEStatsBrowsers.BrowserID
) OPTION (HASH JOIN)
ตอนนี้มันไม่ได้เป็นคำถามเกี่ยวกับวิธีการแก้ไข - ฉันสามารถใช้ตัวเลือก (HASH JOIN) หรือสร้างตารางชั่วคราวด้วยตนเอง ฉันสงสัยว่าทำไมเครื่องมือเพิ่มประสิทธิภาพข้อความค้นหาจึงใช้แผนที่ทำอยู่ในปัจจุบัน
เนื่องจาก QO ไม่มีสถิติใด ๆ ในคอลัมน์ BrowserID ฉันเดาว่ามันถือว่าเลวร้ายที่สุด - 50 ล้านค่าที่แตกต่างดังนั้นจึงต้องใช้โต๊ะทำงานหน่วยความจำ / tempdb ค่อนข้างใหญ่ ดังนั้นวิธีที่ปลอดภัยที่สุดคือทำการสแกนแต่ละแถวใน tblFEStatsBrowsers ไม่มีความสัมพันธ์กับ foreign key ระหว่างคอลัมน์ BrowserID ในสองตารางดังนั้น QO ไม่สามารถหักข้อมูลใด ๆ จาก tblFEStatsBrowsers
นี่เป็นเหตุผลง่ายๆหรือไม่?
อัปเดต 1
เพื่อให้สถิติสองสามตัวเลือก: ตัวเลือก (HASH JOIN):
208.711 การอ่านเชิงตรรกะ (สแกน 12 ครั้ง)
OPTION (LOOP JOIN, HASH GROUP):
11.008.698 การอ่านตรรกะ (~ สแกนต่อ BrowserID (339))
ไม่มีตัวเลือก:
11.008.775 การอ่านตรรกะ (~ สแกนต่อ BrowserID (339))
อัปเดต 2
คำตอบที่ยอดเยี่ยมพวกคุณทุกคน - ขอบคุณ! เลือกยากเพียงอันเดียว แม้ว่ามาร์ตินจะเป็นคนแรกและรีมัสเป็นวิธีแก้ปัญหาที่ยอดเยี่ยม แต่ฉันต้องมอบมันให้กับกีวีเพื่อไปใส่ใจในรายละเอียด :)