โพรบแฮชคีย์และส่วนที่เหลือ


21

สมมติว่าเรามีคำถามเช่นนี้:

select a.*,b.*
from 
a join b
on a.col1=b.col1
and len(a.col1)=10

สมมติว่าแบบสอบถามดังกล่าวจะใช้แฮร่วมและมีส่วนที่เหลือที่สำคัญการสอบสวนจะเป็นและที่เหลือจะเป็นcol1len(a.col1)=10

แต่ในขณะที่ดูตัวอย่างอื่นฉันสามารถเห็นทั้งโพรบและส่วนที่เหลือเป็นคอลัมน์เดียวกัน ด้านล่างนี้เป็นรายละเอียดเกี่ยวกับสิ่งที่ฉันพยายามจะพูด:

ค้นหา:

select *
from T1 join T2 on T1.a = T2.a 

แผนการดำเนินการพร้อมโพรบและไฮไลต์ที่เหลือ:

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

ข้อมูลการทดสอบ:

create table T1 (a int, b int, x char(200))
create table T2 (a int, b int, x char(200))

set nocount on
declare @i int
set @i = 0
while @i < 1000
  begin
      insert T1 values (@i * 2, @i * 5, @i)
    set @i = @i + 1
  end

declare @i int
set @i = 0
while @i < 10000
  begin
    insert T2 values (@i * 3, @i * 7, @i)
    set @i = @i + 1
  end

คำถาม:

โพรบและส่วนที่เหลือสามารถเป็นคอลัมน์เดียวกันได้อย่างไร เหตุใด SQL Server ไม่สามารถใช้คอลัมน์โพรบได้เท่านั้น เหตุใดจึงต้องใช้คอลัมน์เดียวกับส่วนที่เหลือเพื่อกรองแถวอีกครั้ง

ข้อมูลอ้างอิงสำหรับทดสอบ:

คำตอบ:


22

หากการรวมอยู่ในคอลัมน์เดียวที่พิมพ์เป็นtinyint, smallintหรือinteger* และหากทั้งสองคอลัมน์ถูก จำกัด ให้NOT NULLฟังก์ชันแฮชเป็น 'สมบูรณ์แบบ' - หมายถึงไม่มีโอกาสที่จะเกิดการชนกันของข้อมูลและตัวประมวลผลแบบสอบถามไม่ต้องตรวจสอบ ค่าอีกครั้งเพื่อให้แน่ใจว่าพวกเขาตรงกับจริง ๆ

มิฉะนั้นคุณจะเห็นส่วนที่เหลือเป็นรายการในที่เก็บข้อมูลแฮชที่ได้รับการทดสอบสำหรับการจับคู่ไม่ใช่เพียงแค่การจับคู่ฟังก์ชันแฮช

การทดสอบของคุณไม่ได้ระบุNULLหรือNOT NULLสำหรับคอลัมน์ (วิธีปฏิบัติที่ไม่เหมาะสม) ดังนั้นจึงปรากฏว่าคุณกำลังใช้ฐานข้อมูลที่NULLเป็นค่าเริ่มต้น

ข้อมูลเพิ่มเติมในโพสต์ของฉันเข้าร่วมประสิทธิภาพการแปลงโดยปริยายและสิ่งที่เหลืออยู่และแฮชเข้าร่วมการดำเนินการภายในโดย Dmitry Pilugin


* ประเภทที่มีคุณสมบัติอื่น ๆ ได้แก่บิต , smalldatetime , smallmoneyและ(var) ถ่าน (n)สำหรับ n = 1 และการเปรียบเทียบไบนารี

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