LIKE ถูกนำไปใช้อย่างไร


22

ทุกคนสามารถอธิบายวิธีการใช้งานตัวดำเนินการ LIKE ในระบบฐานข้อมูลปัจจุบัน (เช่น MySQL หรือ Postgres) ได้อย่างไร หรือชี้ให้ฉันอ้างอิงบางอย่างที่อธิบายได้หรือไม่

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

คำตอบ:


19

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

SELECT *
  FROM employees
 WHERE last_name LIKE 'Cav%'

ฐานข้อมูลสามารถใช้ดัชนีบนLAST_NAMEเพื่อค้นหาแถวทั้งหมดที่ชื่อนามสกุลเริ่มต้น 'Cav' ในทางกลับกันถ้าคุณมีบางอย่างเช่น

SELECT *
  FROM employees
 WHERE last_name LIKE '%av%'

ฐานข้อมูลจะต้องสแกนทั้งตาราง (หรือดัชนีทั้งหมด) และประเมินการแสดงออกกับLAST_NAMEค่าเต็ม เห็นได้ชัดว่ามันแพงมาก

ฐานข้อมูลเชิงสัมพันธ์ที่ดีกว่าส่วนใหญ่มีระบบอำนวยความสะดวกในการค้นหาข้อความแบบเต็มประสิทธิภาพมากขึ้นโดยการสร้างดัชนีและแคตตาล็อกข้อความประเภทต่าง ๆ แต่สิ่งเหล่านี้ไม่ได้ใช้คำหลัก LIKE ยกตัวอย่างเช่นที่นี่เป็นบทความที่ดีที่กล่าวถึงการค้นหาข้อความแบบเต็มใน PostgreSQL


4
ออราเคิลสามารถใช้ดัชนีแม้จะมีค่าเปอร์เซ็นต์ หากข้อมูลที่ค้นหาหมายถึงชุดย่อยขนาดเล็กของแถวคำใบ้สามารถบังคับให้ใช้ดัชนีและทำให้การดำเนินการเร็วขึ้น ดู laurentschneider.com/wordpress/2009/07/...
Leigh Riffel

1
"สแกนทั้งตาราง ... เห็นได้ชัดว่ามีราคาแพงมาก" - ซึ่งค่อนข้างขึ้นอยู่กับตาราง;) ps คุณเห็นด้วยที่LAST_NAMEจะเป็นผู้สมัครรับ (คอลัมน์แรกใน) ดัชนีคลัสเตอร์หรือไม่ pps คำตอบนี้มีความคิดเห็นต่อระบบฐานข้อมูลมากน้อยเพียงใดโดยอ้างอิงจากหน่วยเก็บข้อมูลที่ต่อเนื่องกันบนดิสก์และดัชนีต้นไม้ B
วันที่

26

นอกจากสิ่งที่ Justin Cave เขียนไว้ตั้งแต่PostgreSQL 9.1คุณสามารถเพิ่มความเร็วในการค้นหาด้วยLIKE ( ~~) หรือILIKE( ~~*) และการจับคู่นิพจน์ทั่วไปขั้นพื้นฐานได้เช่นกัน ( ~) ใช้คลาสโอเปอเรเตอร์ที่จัดทำโดยโมดูลpg_trgmพร้อมกับดัชนี GIN หรือ GiST เพื่อเร่งความเร็วLIKEการแสดงออกที่ไม่ได้ยึดไว้ ในการติดตั้งส่วนขยายให้รันหนึ่งครั้งต่อฐานข้อมูล:

CREATE EXTENSION pg_trgm;

สร้างดัชนีของแบบฟอร์ม

CREATE INDEX tbl_col_gin_trgm_idx ON tbl USING gin (col gin_trgm_ops);

หรือ:

CREATE INDEX tbl_col_gist_trgm_idx ON tbl USING gist (col gist_trgm_ops);

การสร้างและการบำรุงรักษาดัชนี GIN หรือ GiSTนั้นมีค่าใช้จ่าย แต่ถ้าตารางของคุณไม่ได้เขียนมากนี่เป็นคุณสมบัติที่ยอดเยี่ยมสำหรับคุณ

Depeszได้เขียนบทความที่ยอดเยี่ยมในบล็อกของเขาเกี่ยวกับคุณสมบัติใหม่

GIN หรือ GiST?

คำพูดทั้งสองจากคู่มือควรมีคำแนะนำ

ตัวเลือกระหว่างการจัดทำดัชนี GiST และ GIN ขึ้นอยู่กับลักษณะการทำงานที่สัมพันธ์กันของ GiST และ GIN ซึ่งจะกล่าวถึงที่อื่น ตามกฎทั่วไปแล้วดัชนี GIN จะค้นหาได้เร็วกว่าดัชนี GiST แต่จะช้ากว่าในการสร้างหรืออัปเดต ดังนั้น GIN จะเหมาะกว่าสำหรับข้อมูลคงที่และ GiST สำหรับข้อมูลที่อัปเดตบ่อยครั้ง

แต่สำหรับประเภทข้อความค้นหา "เพื่อนบ้านที่ใกล้ที่สุด" ด้วยการใช้โอเปอเรเตอร์ระยะทาง <-> :

สิ่งนี้สามารถนำไปใช้อย่างมีประสิทธิภาพโดยดัชนี GiST แต่ไม่สามารถทำได้โดยดัชนี GIN


3
อ่านนี้ฉันสงสัยว่าจะใช้ GIN หรือ GiST ตามสิ่งที่ฉันอ่านดัชนี GIN นั้นแพงกว่าในการรักษา แต่ค้นหาได้เร็วกว่าในขณะที่ดัชนี GiST นั้นถูกกว่าเพื่อรักษา แต่ช้ากว่าการค้นหา ซึ่งหมายความว่าโดยทั่วไปแล้วดัชนี GIN ควรใช้กับข้อมูลที่ค่อนข้างคงที่ในขณะที่ดัชนี GiST นั้นต้องการในตารางที่กลายพันธุ์มากขึ้น
โคลิน 't ฮาร์ต

1
@ Colin'tHart: โดยทั่วไปแล้วเป็นเรื่องจริง แต่ก็มีข้อยกเว้นสำหรับกฎ พิจารณาภาคผนวกข้างต้น
Erwin Brandstetter

5

เมื่อพูดถึง MySQL ตำแหน่งของอักขระไวด์การ์ด (%) สร้างความแตกต่าง หากมีการระบุส่วนแรกของข้อความwhere first_name like 'Sta%'แล้วเอ็นจิ้น DB จะค้นหาคำย่อย ๆ ที่มีขนาดเล็กกว่าที่มองด้วย S จากนั้นไปที่ St จากนั้นไปที่ Sta และ Sta เป็นต้นหากคุณทำอะไรเช่นwhere first_name like '%stan%'นั้นและสแกนทั้งหมดของ จะต้องมีคอลัมน์ นอกจากนี้คุณยังสามารถดูดัชนีข้อความแบบเต็มที่ค้นหาด้วยภาษาธรรมชาติ ตรวจสอบเอกสาร MySQL ที่นี่


1
ทำไมมันจะเริ่มค้นหา "S%" เมื่อกำหนดสตริงย่อยเป็น 3 ตัวอักษร (เช่นเรารู้ว่าสตริงไม่ใช่ "Sr%") หรือว่าคุณสมมติว่าฐานข้อมูลมีต้นไม้นำหน้าเหนือแอตทริบิวต์และเป็นตัวอย่างของการสำรวจต้นไม้นี้
Nick
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.