LIKE ใช้ดัชนี CHARINDEX ไม่ได้หรือ


22

คำถามนี้เป็นคำถามที่เกี่ยวข้องกับคำถามเก่าของฉัน ข้อความค้นหาด้านล่างนี้ใช้เวลาดำเนินการ 10 ถึง 15 วินาที:

SELECT [customer].[Customer name],[customer].[Sl_No],[customer].[Id]
FROM [company].dbo.[customer]
WHERE (Charindex('123456789',CAST([company].dbo.[customer].[Phone no] AS VARCHAR(MAX)))>0) 

ในบางบทความฉันเห็นว่าการใช้CASTและCHARINDEXจะไม่ได้รับประโยชน์จากการจัดทำดัชนี นอกจากนี้ยังมีบทความบางส่วนที่กล่าวว่าการใช้LIKE '%abc%'จะไม่ได้รับประโยชน์จากการทำดัชนีในขณะที่LIKE 'abc%':

http://bytes.com/topic/sql-server/answers/81467-using-charindex-vs-like-where /programming/803783/sql-server-index-any-improvement- สำหรับ -like-query http://www.sqlservercentral.com/Forums/Topic186262-8-1.aspx#bm186568

ในกรณีของฉันฉันสามารถเขียนแบบสอบถามเป็น:

SELECT [customer].[Customer name],[customer].[Sl_No],[customer].[Id]
FROM [company].dbo.[customer]
WHERE [company].dbo.[customer].[Phone no]  LIKE '%123456789%'

แบบสอบถามนี้ให้ผลลัพธ์เช่นเดียวกับรายการก่อนหน้า ผมได้สร้างดัชนี nonclustered Phone noสำหรับคอลัมน์ เมื่อผมดำเนินการค้นหานี้มันจะทำงานในเวลาเพียง1 วินาที นี่เป็นการเปลี่ยนแปลงครั้งใหญ่เมื่อเทียบกับ14 วินาทีก่อนหน้านี้

วิธีการที่ไม่LIKE '%123456789%'ได้รับประโยชน์จากการจัดทำดัชนี?

เหตุใดบทความที่ระบุจึงไม่สามารถปรับปรุงประสิทธิภาพได้

ฉันพยายามเขียนแบบสอบถามใหม่เพื่อใช้CHARINDEXแต่ประสิทธิภาพยังคงช้า เหตุใดจึงไม่CHARINDEXได้ประโยชน์จากการจัดทำดัชนีตามที่ปรากฏในLIKEแบบสอบถาม

คำค้นหาโดยใช้CHARINDEX:

SELECT [customer].[Customer name],[customer].[Sl_No],[customer].[Id]
 FROM [Company].dbo.[customer]
 WHERE ( Charindex('9000413237',[Company].dbo.[customer].[Phone no])>0 ) 

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

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

คำค้นหาโดยใช้LIKE:

SELECT [customer].[Customer name],[customer].[Sl_No],[customer].[Id]
 FROM [Company].dbo.[customer]
 WHERE[Company].dbo.[customer].[Phone no] LIKE '%9000413237%'

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

แผนแบบสอบถาม LIKE

คำตอบ:


28

LIKE '% 123456789%' ได้ประโยชน์จากการจัดทำดัชนีอย่างไร

เพียงนิด ๆ หน่อย ๆ. ตัวประมวลผลแบบสอบถามสามารถสแกนดัชนีที่ไม่เป็นคลัสเตอร์ทั้งหมดเพื่อค้นหารายการที่ตรงกันแทนตารางทั้งหมด (ดัชนีคลัสเตอร์) ดัชนีที่ไม่ได้คลัสเตอร์จะมีขนาดเล็กกว่าตารางที่สร้างขึ้นดังนั้นการสแกนดัชนีที่ไม่ได้เป็นคลัสเตอร์อาจเร็วกว่า

ข้อเสียคือคอลัมน์ใด ๆ ที่จำเป็นสำหรับการสืบค้นที่ไม่รวมอยู่ในการกำหนดดัชนีแบบ nonclustered จะต้องค้นหาในตารางฐานต่อแถว

เครื่องมือเพิ่มประสิทธิภาพจะทำการตัดสินใจระหว่างการสแกนตาราง (ดัชนีคลัสเตอร์) และการสแกนดัชนีที่ไม่เป็นคลัสเตอร์ด้วยการค้นหาตามการประมาณการต้นทุน ค่าใช้จ่ายโดยประมาณนั้นขึ้นอยู่กับขอบเขตที่ดีเยี่ยมของจำนวนเครื่องมือเพิ่มประสิทธิภาพที่คาดว่าคุณLIKEหรือภาคCHARINDEXแสดงจะเลือก

เหตุใดบทความที่ระบุจึงไม่สามารถปรับปรุงประสิทธิภาพได้

สำหรับLIKEเงื่อนไขที่ไม่ได้เริ่มต้นด้วย wildcard นั้น SQL Server สามารถทำการสแกนบางส่วนของดัชนีแทนการสแกนได้ทั้งหมด ตัวอย่างเช่นLIKE 'A%สามารถประเมินได้อย่างถูกต้องโดยการทดสอบบันทึกดัชนีเท่านั้น>= 'A'และ< 'B'(ค่าขอบเขตที่แน่นอนขึ้นอยู่กับการเปรียบเทียบ)

การเรียงลำดับของแบบสอบถามนี้สามารถใช้ความสามารถในการค้นหาของดัชนี b-tree: เราสามารถไปที่ระเบียนแรก>= 'A'โดยใช้ b-tree จากนั้นสแกนไปข้างหน้าตามลำดับคีย์ดัชนีจนกว่าเราจะไปถึงระเบียนที่ล้มเหลวใน< 'B'การทดสอบ เนื่องจากเราจำเป็นต้องใช้การLIKEทดสอบกับจำนวนแถวที่น้อยลงโดยทั่วไปประสิทธิภาพจึงดีกว่า

ในทางตรงกันข้ามLIKE '%Aไม่สามารถเปลี่ยนเป็นการสแกนบางส่วนได้เนื่องจากเราไม่รู้ว่าจะเริ่มหรือสิ้นสุดที่ใด บันทึกใด ๆ อาจสิ้นสุดลง'A'ดังนั้นเราจึงไม่สามารถปรับปรุงการสแกนดัชนีทั้งหมดและทดสอบทุกแถวเป็นรายบุคคล

ฉันพยายามเขียนแบบสอบถามใหม่เพื่อใช้CHARINDEXแต่ประสิทธิภาพยังคงช้า เหตุใดจึงไม่CHARINDEXได้ประโยชน์จากการจัดทำดัชนีตามที่ปรากฏในแบบสอบถาม LIKE

เครื่องมือเพิ่มประสิทธิภาพแบบสอบถามมีตัวเลือกเดียวกันระหว่างการสแกนตาราง (ดัชนีคลัสเตอร์) และการสแกนดัชนีที่ไม่เป็นคลัสเตอร์ (พร้อมการค้นหา) ในทั้งสองกรณี

ทางเลือกที่จะทำระหว่างคนทั้งสองอยู่บนพื้นฐานของการประมาณค่าใช้จ่าย มันเกิดขึ้นที่ SQL Server อาจสร้างการประเมินที่แตกต่างกันสำหรับสองวิธี สำหรับLIKEรูปแบบของแบบสอบถามการประมาณอาจจะสามารถใช้สถิติสตริงพิเศษเพื่อสร้างการประมาณการที่แม่นยำอย่างสมเหตุสมผล CHARINDEX > 0แบบฟอร์มการผลิตการประมาณการอยู่บนพื้นฐานของการคาดเดา

ประมาณการที่แตกต่างกันพอที่จะทำให้เพิ่มประสิทธิภาพการเลือกคลัสเตอร์ดัชนีสแกนหาCHARINDEXและ nonclustered LIKEดัชนีสแกนด้วยการค้นหาสำหรับ หากคุณบังคับCHARINDEXให้คิวรีใช้ดัชนีที่ไม่ได้จัดกลุ่มด้วยคำใบ้คุณจะได้รับแผนเดียวกันสำหรับLIKEและประสิทธิภาพจะเหมือนกัน:

SELECT
    [Customer name],
    [Sl_No],
    [Id]
FROM dbo.customer WITH (INDEX (f))
WHERE 
    CHARINDEX('9000413237', [Phone no]) >0;

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

หากคุณพบว่าตัวเองต้องLIKE %thing%ค้นหาบ่อยครั้งคุณอาจต้องการที่จะต้องพิจารณาเทคนิคผมเขียนเกี่ยวกับในTrigram Wildcard สตริงการค้นหาใน SQL Server


16

SQL Server รักษาสถิติเกี่ยวกับสตริงในคอลัมน์สตริงในรูปแบบของความพยายามที่มีการใช้งานโดยLIKEการสอบถาม CHARINDEXแต่ไม่โดย

ดูหัวข้อสถิติสรุปสตริงสำหรับข้อมูลเพิ่มเติมเกี่ยวกับสิ่งนี้

ข้อควรระวังที่สำคัญสองประการคือการใช้ wildcard ใด ๆ ต้องใช้เทคนิคการถ่ายคร่อมแบบสี่เหลี่ยมแทนที่จะใช้ESCAPEคีย์เวิร์ดและสำหรับสายอักขระที่ยาวกว่า 80 อักขระจะใช้เพียงอักขระ 40 ตัวแรกและตัวสุดท้ายเท่านั้น

WHERE ( Charindex('9000413237',[Company].dbo.[customer].[Phone no])>0 ) 

จะใช้การคาดเดามาตรฐานสำหรับคำกริยาความไม่เท่าเทียมที่จะคืนค่า 30% ของแถว

LIKEแบบสอบถาม (ในกรณีของคุณ) สันนิษฐานประมาณการแถวมากน้อยจะตรงกับคำกริยา

โปรดทราบว่าสัญลักษณ์ตัวแทนชั้นนำยังคงป้องกันการค้นหาดัชนี ดัชนีทั้งหมดยังคงสแกนอยู่ แต่ใช้ดัชนีอื่นที่แคบกว่าดัชนีที่ทำคลัสเตอร์ ดัชนีที่แคบไม่ครอบคลุมคอลัมน์ทั้งหมดที่ใช้โดยแบบสอบถามดังนั้นแผนสองต้องการการค้นหาคีย์เพื่อดึงคอลัมน์ที่ขาดหายไป

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


ฉันไม่ชัดเจนพร้อมคำอธิบายของคุณ คุณกำลังบอกว่าการใช้ like ดีกว่า charindex หรือไม่?
นักวิจัยด้านไอที

3
@ITresearcher - ใช่อาจเป็นเพียงแค่ใช้การคาดเดาแบบครอบคลุมจำนวนแถวที่จะตรงกับเงื่อนไข ( 30%) สามารถดูLIKEรูปแบบที่ให้มาและสถิติสรุปสตริงและได้รับการประมาณการที่แม่นยำยิ่งขึ้น อาวุธที่อาจเลือกแผนอื่นที่เหมาะสมกว่า
Martin Smith

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