LIKE vs CONTAINS บน SQL Server


210

ข้อใดข้อหนึ่งต่อไปนี้เร็วกว่า (เช่น vs CONTAINS)

SELECT * FROM table WHERE Column LIKE '%test%';

หรือ

SELECT * FROM table WHERE Contains(Column, "test");

12
ยอมรับคำตอบไหม
AgentFire

7
เขาไม่ได้อยู่ในคนหลายปี
คริส

คำตอบ:


174

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

แบบสอบถามแรกที่ใช้ LIKE จะไม่สามารถใช้ดัชนีได้เนื่องจากเริ่มต้นด้วย wildcard ดังนั้นจะต้องใช้การสแกนแบบเต็มตารางเสมอ


CONTAINSแบบสอบถามควรจะ:

SELECT * FROM table WHERE CONTAINS(Column, 'test');

@edze - คุณหมายถึงหน้าเดียวกันที่เชื่อมโยงกับการกล่าวถึงครั้งแรกของฉันแล้วCONTAINSหรือไม่ มันคืออะไร รูปแบบดั้งเดิมของคำถามมีColumn CONTAIN("%test%",Column)>0ซึ่งไม่มีที่ไหนใกล้กับที่ถูกต้อง มันยังไม่ถูกต้องสมบูรณ์
Damien_The_Unbeliever

สิ่งนี้ช่วยให้เราเรียงลำดับแบบสอบถามบน SharePoint มีตราคำตอบที่ดีอีกอันหนึ่ง
ouflak

14

มีการเรียกใช้แบบสอบถามทั้งสองบนอินสแตนซ์ของ SQL Server 2012 ฉันสามารถยืนยันแบบสอบถามแรกได้เร็วที่สุดในกรณีของฉัน

แบบสอบถามที่มีLIKEคำหลักแสดงการสแกนดัชนีแบบคลัสเตอร์

CONTAINSยังมีสแกนดัชนีคลัสเตอร์กับผู้ประกอบการที่เพิ่มขึ้นสำหรับการแข่งขันข้อความเต็มรูปแบบและผสานเข้าร่วม

วางแผน


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

กำลังดูแผนปฏิบัติการจริงที่ดึงข้อมูลกว่า 200,000 รายการ การวางทั้งแบบสอบถามในชุดงานทั้งสแกนดัชนีคลัสเตอร์ แต่นอกเหนือจากแบบสอบถาม "CONTAINS" จะมีค่าใช้จ่ายเพิ่มเติมของการจับคู่ข้อความเต็มรูปแบบและการรวมเข้าร่วม
MI C

ถ้าเลือกการรวมการผสานแล้ว SQL Server จะประมาณมากกว่า x% ของแถวจะสิ้นสุดลงตรงกับเพรดิเคต (โดยที่ X = จุดเปลี่ยน ) ในกรณีนี้ฉันคิดว่าทั้งคู่สามารถจับคู่กันได้อย่างเท่าเทียมกัน ต้นทุนที่แสดงในแผนการดำเนินการเป็นเพียงการประมาณการ (แม้จะอยู่ในแผนจริง) ในขณะที่มีตัวดำเนินการแผนปฏิบัติการเพิ่มเติมในแผน FT จะมีประโยชน์บางอย่าง ผสานเข้าร่วมสามารถหยุดก่อนที่จะสิ้นสุดของการสแกนเมื่อมันไหลออกมาจากผล FT LIKEและยังไม่ได้มีการประเมิน
Martin Smith

1
ฉันได้เรียกใช้แบบสอบถามที่คล้ายกันเพื่อตรวจสอบแผนการดำเนินการใน sql 2012 และให้ดัชนี Seek แก่ฉัน ในตัวอย่างที่นี่ตารางอาจเกือบจะว่างเปล่า ในบางกรณี sql ใช้การสแกนดัชนีในตารางเล็ก ๆ แทนการใช้ดัชนีเพราะเร็วกว่า
Juan

8

ผมคิดว่าCONTAINSใช้เวลานานและใช้Mergeเพราะคุณมีขีดกลาง ( "-") adventure-works.comในการค้นหาของคุณ

เครื่องหมายขีดกลางเป็นคำหยุดดังนั้นการCONTAINSค้นหาดัชนีข้อความแบบเต็มadventureและมากกว่าที่ค้นหาworks.comและผสานผลลัพธ์


8

ลองเปลี่ยนจากนี้:

    SELECT * FROM table WHERE Contains(Column, "test") > 0;

สำหรับสิ่งนี้:

    SELECT * FROM table WHERE Contains(Column, '"*test*"') > 0;

อดีตจะค้นหาระเบียนที่มีค่าเช่น " นี่คือการทดสอบ " และ " กรณีทดสอบคือแผน "

หลังจะพบระเบียนที่มีค่าเช่น " ฉันกำลังทดสอบนี้ " และ " นี่คือสิ่งที่ยิ่งใหญ่ที่สุด "


4
การใส่เครื่องหมายดอกจันก่อนและหลังคำค้นหาหรือไม่ ในการอ่านเอกสารสำหรับCONTAINSกล่าวถึงเฉพาะการใช้คำนำหน้าเช่น 'test *' ไม่ใช่คำต่อท้ายเช่น ' test' และไม่ค้นหาซับสตริงแบบเต็มเช่น '* test ' ฉันยังไม่ได้ลองเลย
matt forsythe

5
หากคุณอ่านเอกสารประกอบสำหรับ CONTAINS ( docs.microsoft.com/en-us/sql/t-sql/queries/ ...... ) สนับสนุนการค้นหาคำนำหน้าเท่านั้น ฉันได้ลองทำสิ่งนี้หลายครั้งและไม่สามารถหา "นี่คือสิ่งที่ยิ่งใหญ่ที่สุด" (ใน SQL Sever) ด้วยประกอบด้วย (คอลัมน์ '' ทดสอบ '')
cl0rkster
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.