ค้นหาแบบเต็มข้อความด้วย InnoDB


93

ฉันกำลังพัฒนาเว็บแอปพลิเคชันปริมาณมากโดยที่ส่วนหนึ่งเป็นฐานข้อมูล MySQL ของโพสต์การสนทนาที่จะต้องเพิ่มเป็น 20M + แถวอย่างราบรื่น

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

ปัญหาคือ ... InnoDB ไม่มีความสามารถในการค้นหาแบบเต็มข้อความในตัว

ฉันควรใช้ระบบค้นหาของบุคคลที่สามหรือไม่? เช่นLucene (c ++) / Sphinx ? นินจาฐานข้อมูลของคุณมีข้อเสนอแนะ / แนวทางหรือไม่?zoieของ LinkedIn (จาก Lucene) ดูเหมือนจะเป็นตัวเลือกที่ดีที่สุดในขณะนี้... ถูกสร้างขึ้นจากความสามารถแบบเรียลไทม์ (ซึ่งค่อนข้างสำคัญสำหรับแอปพลิเคชันของฉัน) ฉันลังเลเล็กน้อยที่จะกระทำโดยไม่มีข้อมูลเชิงลึก ...

(FYI: จะอยู่ใน EC2 พร้อมแท่นขุดเจาะหน่วยความจำสูงโดยใช้ PHP เพื่อให้บริการส่วนหน้า)


คำตอบ:


50

ฉันสามารถรับรองว่า MyISAM fulltext เป็นตัวเลือกที่ไม่ดี - แม้จะทิ้งปัญหาต่าง ๆ กับตาราง MyISAM โดยทั่วไปฉันได้เห็นสิ่งที่เต็มไปด้วยข้อความออกจากรางและเริ่มเสียหายตัวเองและทำให้ MySQL หยุดทำงานเป็นประจำ

เครื่องมือค้นหาเฉพาะจะเป็นตัวเลือกที่ยืดหยุ่นที่สุดที่นี่ - จัดเก็บข้อมูลโพสต์ใน MySQL / innodb แล้วส่งออกข้อความไปยังเครื่องมือค้นหาของคุณ คุณสามารถตั้งค่าการสร้าง / เผยแพร่ดัชนีแบบเต็มตามระยะเวลาได้อย่างง่ายดายและเพิ่มการอัปเดตดัชนีแบบเรียลไทม์หากคุณรู้สึกว่าจำเป็นและต้องการใช้เวลา

Lucene และ Sphinx เป็นตัวเลือกที่ดีเช่นเดียวกับXapianซึ่งดีและมีน้ำหนักเบา หากคุณไปเส้นทาง Lucene อย่าคิดว่า Clucene จะดีกว่าแม้ว่าคุณจะไม่ต้องการต่อสู้กับ Java แม้ว่าฉันจะไม่มีคุณสมบัติที่จะพูดคุยถึงข้อดีข้อเสียของทั้งสองอย่าง


7
Solr (อิงจาก Lucene) สามารถปรับขนาดได้อย่างมหาศาลและทรงพลังและยืดหยุ่นมาก เราใช้ Solr (โดยเฉพาะ LucidWorks for Solr edition) และฉันสามารถพูดได้ว่ามันเป็นชัยชนะที่ยิ่งใหญ่ สฟิงซ์มีสัญญาที่จริงจังเช่นกัน แต่ในที่สุดการขาดประเภทข้อมูลอาจเป็นปัญหาสำหรับแอปพลิเคชันของเราอย่างน้อยที่สุด สฟิงซ์นั้นเร็วมากและถ้ามันเหมาะกับความต้องการของคุณก็เป็นทางเลือกที่มั่นคงเช่นกัน
Cody Caughlan

ขอบคุณมากคุณสองคน; คำตอบที่ดี ฉันใช้นิ้วหัวแม่มือผ่านเอกสารของ Solr และดูเหมือนว่าจะเป็นวิธีแก้ปัญหาที่ดี มันมีอำนาจในเว็บไซต์ขนาดใหญ่ไม่กี่แห่งเช่นกันฉันเห็น ฉันคิดว่า Solr เป็นตั๋ว ขอบคุณเพื่อน. นอกจากนี้ยังเป็นการดีที่จะเรียนรู้เกี่ยวกับอาการปวดหัว MyISAM ของคุณเอียน ... สิ่งเหล่านี้จะเป็นสิ่งที่ดีที่จะมีในอนาคต ในโปรเจ็กต์อื่น ๆ ฉันจะหลงทางไม่เคยพยายามใช้ฟีเจอร์ Fulltext
brianreavis

11
สงสัยว่าอะไรทำให้เอียนพูดว่า "อย่าคิดว่า Clucene จะดีขึ้น"? ในฐานะหนึ่งในทีมหลักของ clucene ฉันอาจจะไม่ได้มีเป้าหมายมากนัก แต่สำหรับฉันแล้วดูเหมือนว่าพอร์ต C ++ ที่ดีที่สุดของไลบรารี Java ใด ๆ จะช่วยเพิ่มประสิทธิภาพผ่านหลังคา ฉันขอแนะนำให้ทุกคนอย่าโพสต์ความคิดเห็นดังกล่าวโดยไม่ได้เหลือบไปเห็นผลิตภัณฑ์ที่พวกเขาเสียชื่อเสียง
synhershko

4
เมื่อคุณโจมตี MyISAM คุณจะต้องเจาะจงมากขึ้น "ปิดราง"นั้นคลุมเครือมากและอาจเป็นเพราะจุดบกพร่องเดียวในบิลด์ที่คุณใช้อาจเป็นไปได้ว่าได้รับการแก้ไขแล้ว
bobobobo

6
แต่ถ้าคุณไม่มีตัวเลือกในการติดตั้งซอฟต์แวร์บนเซิร์ฟเวอร์จะมีทางเลือกใดบ้างในกรณีนี้?
acme

57

นอกเหนือจากการเลิกใช้ MyISAM ทั่วไปแล้วInnoDB full-text search (FTS) ก็มีให้บริการในรุ่น MySQL 5.6.4

จำนวนมากรายละเอียดฉ่ำที่https://dev.mysql.com/doc/refman/5.6/en/innodb-fulltext-index.html

ในขณะที่เอ็นจิ้นอื่น ๆ มีคุณสมบัติที่แตกต่างกันมากมายอันนี้คือ InnoDB ดังนั้นจึงเป็นแบบเนทีฟ (ซึ่งหมายความว่ามีเส้นทางการอัปเกรด) และทำให้เป็นตัวเลือกที่คุ้มค่า


1
ลิงก์ของบทความคือ 403 ต้องห้าม
Marco Demaio

11

คุณควรใช้เวลาหนึ่งชั่วโมงในการติดตั้งและทดลองขับ Sphinx และ Lucene ดูว่าตรงกับความต้องการของคุณหรือไม่สำหรับการอัปเดตข้อมูล

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

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


ขอบคุณบิล ใช่เอกสารของสฟิงซ์ทำให้ฉันลังเลเล็กน้อยเกี่ยวกับวิธีจัดการกับการอัปเดตดัชนี ดีที่จะได้รับการยืนยัน ระบบแบบนั้นอาจจะกลายเป็นฝันร้ายสำหรับฉันฉันจินตนาการ สำหรับ Google Custom Search นั่นคือตัวเลือก อย่างไรก็ตามปัญหาหลักของฉันคือดัชนีที่ไม่ใช่เรียลไทม์และขาดการปรับแต่ง การจัดรูปแบบผลลัพธ์และการดึงข้อมูลเพิ่มเติมจะค่อนข้างสำคัญสำหรับฉัน ขอบคุณสำหรับการพูดคุย - ข้อมูลสฟิงซ์เป็นสิ่งที่ดีอย่างแน่นอน!
brianreavis

3

บางทีคุณไม่ควรยกเลิก MySQL's FT อย่างรวดเร็ว Craigslist ใช้ที่จะใช้มัน

ความเร็วของ MySQL และการค้นหาข้อความแบบเต็มทำให้ Craigslist สามารถให้บริการผู้ใช้ได้ .. craigslist ใช้ MySQL เพื่อให้บริการการค้นหาประมาณ 50 ล้านครั้งต่อเดือนในอัตราการค้นหาสูงสุด 60 ครั้งต่อวินาที "

แก้ไข

ตามความคิดเห็นด้านล่าง Craigslist ดูเหมือนจะเปลี่ยนมาใช้ Sphinxในช่วงต้นปี 2009


บทความที่ฉันเชื่อมโยงไม่ได้กล่าวถึง Sphinx และ Nik ไม่ได้อ้างถึงแหล่งใด ๆ ที่บอกว่า Craigslist ใช้ Sphinx เลย
bobobobo

PDF ของกรณีศึกษาดูเหมือนตั้งแต่ปี 2004 ซึ่งในเวลานั้นมีการค้นหา 50 ล้านครั้งต่อเดือน หน้า Sphinx ระบุการค้นหา 50 ล้านครั้งต่อวันซึ่งอาจอธิบายเหตุผลที่พวกเขาเปลี่ยนไปใช้โซลูชันการค้นหาเฉพาะ
Halil Özgür

1

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



0

คุณควรดูสฟิงซ์ น่าลอง การจัดทำดัชนีทำได้เร็วมากและมีการกระจาย คุณควรดูสิ่งนี้ (http://www.percona.com/webinars/2012-08-22-full-text-search-throwdown) webminar พูดถึงการค้นหาและมีเกณฑ์มาตรฐานที่เป็นระเบียบ คุณอาจพบว่ามีประโยชน์



0

สำหรับใครก็ตามที่ติด MySQL / MariaDB เวอร์ชันเก่ากว่า (เช่นผู้ใช้ CentOS) โดยที่ InnoDB ไม่รองรับการค้นหาแบบ Fulltext วิธีแก้ปัญหาของฉันเมื่อใช้ตาราง InnoDB คือการสร้างตาราง MyISAM แยกต่างหากสำหรับสิ่งที่ฉันต้องการค้นหา

ตัวอย่างเช่นตาราง InnoDB หลักของฉันproductsมีคีย์ต่างๆและความสมบูรณ์ของการอ้างอิง จากนั้นฉันสร้างตาราง MyISAM แบบง่ายที่เรียกว่าproduct_searchมีสองฟิลด์product_idและproduct_nameตำแหน่งที่หลังถูกตั้งค่าเป็นFULLTEXTดัชนี ทั้งสองช่องเป็นสำเนาของสิ่งที่อยู่ในproductตารางหลักอย่างมีประสิทธิภาพ

จากนั้นค้นหาในตาราง MyISAM โดยใช้ fulltext และทำการรวมภายในกลับไปที่ตาราง InnoDB

เนื้อหาของตาราง MyISAM สามารถอัปเดตอยู่เสมอผ่านทางทริกเกอร์หรือโมเดลของแอปพลิเคชัน

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

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