ทำไมคุณต้องจัดทำดัชนี text_pattern_ops ในคอลัมน์ข้อความ


18

วันนี้ฐานข้อมูลเจ็ดแห่งในเจ็ดสัปดาห์แนะนำให้ฉันรู้จักกับดัชนีผู้ดำเนินการต่อ

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

CREATE INDEX moves_title_pattern ON movies (
    (lower(title) text_pattern_ops);

เราใช้text_pattern_opsเพราะชื่อเป็นข้อความประเภท หากคุณจำเป็นต้องดัชนี varchars, ตัวอักษรหรือชื่อที่ใช้ปฏิบัติการที่เกี่ยวข้อง: varchar_pattern_ops, และbpchar_pattern_opsname_pattern_ops

ฉันพบตัวอย่างที่ทำให้สับสนจริงๆ ทำไมการทำเช่นนี้จึงมีประโยชน์

หากคอลัมน์เป็นข้อความประเภทจะไม่ถูกแปลงเป็นประเภทอื่น (varchar, char, name) เป็นข้อความก่อนที่จะใช้เป็นค่าการค้นหาหรือไม่

ดัชนีนั้นมีพฤติกรรมแตกต่างจากที่ใช้ตัวดำเนินการเริ่มต้นอย่างไร

CREATE INDEX moves_title_pattern ON movies (lower(title));

1
คำถามที่เกี่ยวข้องนี้อาจช่วยได้: dba.stackexchange.com/questions/10694/…
Erwin Brandstetter

ขอบคุณเออร์วิน คำตอบของคุณสำหรับคำถามนั้นมีประโยชน์มากเมื่อทำการค้นคว้าความคิดในหนังสือ
เอียนซามูเอลแมคลีนเลน

คำตอบ:


20

เอกสารมักจะให้คำตอบสำหรับคำถามดังกล่าว เช่นเดียวกับในกรณีนี้เช่นกัน:

ตัวดำเนินการคลาส text_pattern_ops, varchar_pattern_ops และ bpchar_pattern_ops สนับสนุนดัชนี B-tree บนข้อความประเภท, varchar และ char ตามลำดับ ความแตกต่างจากคลาสโอเปอเรเตอร์เริ่มต้นคือค่าจะถูกเปรียบเทียบอักขระอย่างเคร่งครัดโดยอักขระแทนที่จะเป็นตามกฎการจัดเรียงเฉพาะโลแคล สิ่งนี้ทำให้คลาสตัวดำเนินการเหล่านี้เหมาะสมสำหรับการใช้งานโดยแบบสอบถามที่เกี่ยวข้องกับนิพจน์การจับคู่รูปแบบ (LIKE หรือ POSIX นิพจน์ทั่วไป) เมื่อฐานข้อมูลไม่ได้ใช้โลแคล "C" มาตรฐาน ตัวอย่างเช่นคุณอาจสร้างดัชนีคอลัมน์ varchar ดังนี้:

CREATE INDEX test_index ON test_table (col varchar_pattern_ops);

โปรดทราบว่าคุณควรสร้างดัชนีที่มีคลาสโอเปอเรเตอร์เริ่มต้นหากคุณต้องการคิวรีที่เกี่ยวข้องกับ <, <=,> หรือ> = เปรียบเทียบเพื่อใช้ดัชนี คำสั่งดังกล่าวไม่สามารถใช้ประกอบการเรียน xxx_pattern_ops (การเปรียบเทียบความเท่าเทียมกันทั่วไปสามารถใช้คลาสโอเปอเรเตอร์เหล่านี้ได้) มันเป็นไปได้ที่จะสร้างดัชนีหลายรายการในคอลัมน์เดียวกันกับคลาสโอเปอเรเตอร์ที่แตกต่างกัน

เอกสารอธิบายต่อไปว่า:

ถ้าคุณใช้โลแคล C คุณไม่จำเป็นต้องใช้คลาสโอเปอเรเตอร์ xxx_pattern_ops เนื่องจากดัชนีที่มีคลาสโอเปอเรเตอร์เริ่มต้นจะสามารถใช้งานได้สำหรับคิวรีการจับคู่รูปแบบในโลแคล C

คุณสามารถตรวจสอบสถานที่ของคุณดังต่อไปนี้ (น่าจะเป็น UTF8 มากกว่า "C"):

postgres=> show lc_collate;
 lc_collate
-------------
 en_GB.UTF-8

Aha! ฉันอ่านแล้ว แต่พบว่ามันยากที่จะติดตามดังนั้นจึงไม่ได้ใช้มันคุณจะบอกว่าประโยชน์ที่มีประโยชน์ของมันtext_pattern_opsขึ้นอยู่กับสถานที่เกิดเหตุหรือไม่? ดูเหมือนว่าจะเป็นประโยชน์กับฉันเพราะสถานที่ของฉันคือ 'en_US.UTF-8' (ไม่ใช่ 'C') ดังนั้นการสืบค้นรูปแบบจึงไม่สามารถใช้ดัชนีเริ่มต้นได้
เลนซามูเอลแมคลีนผู้อาวุโส

เผง ฉันจะเพิ่ม (แต่นี่เป็นเพียงการเก็งกำไร) ว่าด้วยข้อมูลที่อยู่ภายในอักขระ ASCII พื้นฐานคลาสโอเปอเรเตอร์เริ่มต้นก็ดีเหมือนกัน - อย่างน้อยฉันก็เห็นข้อความค้นหาด้วย LIKE 'บางสิ่งบางอย่าง%' โดยใช้ดัชนีดังกล่าว
dezso

5
@dezso: หากคุณเห็นLIKEข้อความค้นหาโดยใช้ดัชนี b-tree แบบธรรมดาฐานข้อมูลจะต้องใช้Cภาษานั้น หรือดัชนีจะถูกกำหนดด้วยCOLLATE "POSIX"(หรือCOLLATE "C") COLLATIONและแบบสอบถามระบุตรงกัน ด้วยการเปรียบเทียบอื่น ๆ ลำดับของดัชนีไม่ตรงกับกฎของโลแคลดังนั้นจึงไม่สามารถใช้สำหรับการจับคู่รูปแบบได้
Erwin Brandstetter

1
@ErwinBrandstetter ฉันต้องยืนยันว่าคุณพูดถูก
dezso

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