2012-03-06 19 views
7

मेरे पास प्रति दिन 500+ प्रविष्टियों के साथ 75,000+ पंक्तियों वाला डेटाबेस है।एसक्यूएल में खोजने के लिए सबसे प्रभावी तरीका?

प्रत्येक पंक्ति एक शीर्षक और विवरण है।

मैंने एक आरएसएस फ़ीड बनाया जो आपको एक विशिष्ट खोज शब्द (उदा। http://site.com/rss.rss?q=Pizza खोज शब्द "पिज्जा" के लिए आरएसएस आउटपुट करेगा) के लिए नवीनतम प्रविष्टियां देता है।

मैं सोच रहा था क्या सबसे अच्छा तरीका यह करने के लिए SQL क्वेरी लिखने के लिए होगा। अभी मेरे पास है:

SELECT * 
FROM 'table' 
WHERE (('title' LIKE %searcherm%) OR ('description' LIKE %searcherm%)) 
LIMIT 20; 

लेकिन समस्या को निष्पादित करने में 2 से 10 सेकंड के बीच समस्या होती है।

वहाँ एक बेहतर तरीका क्वेरी लिखने के लिए है, मैं परिणाम कैश करने के लिए है (और मुझे लगता है कि कैसे करना होगा?) या डेटाबेस संरचना गति को क्वेरी (अनुक्रमित?)

+0

व्यक्ति धागा करने के लिए तेजी से हो सकता है इससे पहले कि concat उपयोग करने के लिए है/2 सरल querys में प्रसंस्करण के लिए कांटा: 'से चयन तालिका जहां शीर्षक सीमा 20' तब 'तालिका से चुनें जहां विवरण सीमा 20' थोड़ी सी बात है, फिर अपने सर्वर साइड टेक –

+0

सोलर, लुसेन, स्फिंक्स के साथ जॉइन/सूची कॉन्सट करें? –

उत्तर

8

एक अपेक्षाकृत सरल समाधान इन दोनों पर एक प्रतिलिपि प्राप्त सूचकांक को शामिल किया जाएगा

बेहतर विकल्प पूरा टेक्स्ट अनुक्रमित उपयोग करने के लिए हो सकता है खेतों और बाद में इस सूचकांक का उपयोग करके खोज।

ALTER TABLE table ADD FULLTEXT(title, description); 

तो फिर तुम खोज करने के लिए की आवश्यकता होगी, आप निम्न कर चाहते हैं:

SELECT id FROM table 
WHERE MATCH (title, description) AGAINST ('keyterm'); 

फुलटेक्स्ट अनुक्रमित खोज स्वत: समाधान सबसे SQL डेटाबेस में शामिल है। यह LIKES करने की तुलना में बहुत तेज है। यह आपके विशिष्ट मामले के लिए अनुकूलित भी है क्योंकि आप केवल प्राकृतिक भाषा खोज शब्दों में रूचि रखते हैं।

साथ ही, पूर्ण टेक्स्ट इंडेक्स में प्रासंगिकता का पता लगाने के लिए कुछ सीमित एल्गोरिदम है। के बारे में यह here

संपादित

बदलने बयान में मैं प्रतिलिपि प्राप्त सूचकांक नाम याद आप और अधिक पढ़ सकते हैं, यह होना चाहिए:

ALTER TABLE table ADD FULLTEXT ft_index_name(title, description); 
+0

मैं कोशिश करूँगा। धन्यवाद! – supercoolville

+0

ध्यान दें कि यह केवल MyISAM तालिकाओं के साथ काम करेगा, न कि InnoDB। –

+1

बहुत बहुत धन्यवाद !!! मैंने इसका परीक्षण किया और यह मेरी खोजों को औसतन 14x तेज बना दिया !!!!!!! – supercoolville

-2

में कुछ बदल रहा होगा कुछ पॉइंटर्स: * अपने चयन कथन में * ड्रॉप करें और केवल खोजे गए मानदंडों को खींचें, और खोजे जा रहे कॉलम में अनुक्रमणिका जोड़ना सुनिश्चित करें।

SELECT `title`,`description` 
FROM `table` 
WHERE `title` LIKE '%$searchterm%' OR `description` LIKE '%$searchterm%' LIMIT 25; 
+0

"अपने चयन कथन में * ड्रॉप करें और केवल खोजे गए मानदंडों को खींचें" - अच्छी तरह से आप कैसे जानते हैं कि वह क्या प्राप्त करना चाहता है? –

+0

मैं नहीं करता, लेकिन अपने WHERE खंड पर आधारित, मैं निर्धारित कर सकता हूं कि उसे कम से कम शीर्षक और विवरण की आवश्यकता है। भले ही, वाइल्डकार्ड की बजाय अपनी तालिकाओं को निर्दिष्ट करना हमेशा बेहतर होता है, वह पूछता है कि क्वेरी को कैसे तेज करें और वाइल्डकार्ड को खत्म करना पहला कदम है। –

+0

वहाँ एक LIMIT 20 है .. मुझे संदेह है कि यह किसी भी मापनीय अंतर को बनाएगा –

-2
  1. आप title के लिए और description के लिए एक सूचकांक बनाया था?
  2. आप पूर्ण पाठ खोज क्षमताओं के लिए Sphinx विचार करना चाहिए।

टिप्पणी टायलर के लिए धन्यवाद।

मैं अपने जवाब को फिर से:

1) title और description स्तंभों पर एक सूचकांक बनाएँ, लेकिन आपकी क्वेरी नीचे दिए गए उदाहरण के लिए सीमित किया जाएगा, और कहा कि सभी प्रासंगिक पंक्तियों को ढूँढने के लिए आदर्श नहीं है:

SELECT * 
FROM 'table' 
WHERE title LIKE 'searcherm%' OR description LIKE 'searcherm%' 
LIMIT 20; 

2) जैसा कि अन्य ने उल्लेख किया है, MySQL Full-Text Search का उपयोग करें, लेकिन आप MyISAM टेबल इंजन तक सीमित हैं, क्योंकि यह InnoDB के लिए उपलब्ध नहीं है। हालांकि, आप MySQL में इंजन को मिश्रित कर सकते हैं, ताकि आप इस तालिका को MyISAM बना सकें, भले ही आपकी सभी अन्य टेबल InnoDB हों।

3) ऐसे Sphinx के रूप में, एक बाहरी पूर्ण पाठ खोज इंजन का उपयोग करें। यह आपको अधिक प्रासंगिक खोज परिणाम देगा (MySQL पूर्ण-पाठ खोज वांछित होने के लिए बहुत अधिक छोड़ देता है), यह बेहतर प्रदर्शन करेगा, और यह आपके डेटाबेस से दूर पूर्ण-पाठ खोज के बोझ को सारणीबद्ध करता है।

+2

इंडेक्स यहां मदद नहीं करेगा। '% Foo%' की तरह कभी भी इंडेक्स का उपयोग नहीं करता है। वह उसकी असली समस्या है। –

4

प्रयास करें:

SELECT * FROM table 
WHERE MATCH (title,description) AGAINST (searchterm); 

सुनिश्चित करें कि आप वर्णन एक साथ शीर्षक पर एक पूरा टेक्स्ट सूचकांक जोड़ने के लिए, सुनिश्चित करें।

न पहिया बदलने की कोशिश करते हैं। MATCH और AGAINSTprovided by mysql कि वास्तव में क्या करने के लिए और अपने जीवन आसान बनाने के लिए कर रहे हैं। हालांकि, MyISAM तालिकाओं पर पूर्ण पाठ खोज कार्य नोट करें। InnoDb के लिए आप can workaround भी।आप बस की तरह तालिका बदलकर एफटी सूचकांक जोड़ सकते हैं:

ALTER TABLE table ADD FULLTEXT(title,description); 
+0

यह एकमात्र उत्तर है जो काम करेगा। उल्लेख करें कि आपको इन कॉलम में एक पूर्ण टेक्स्ट इंडेक्स जोड़ने की आवश्यकता है और आपको MyISAM टेबल का उपयोग करना होगा। –

+0

@ फ्रैंकिसएविला ने मेरा जवाब अपडेट किया। – jerrymouse

2

आप LIKE '%term%' साथ एक प्रश्न अनुक्रमित नहीं किया जा सकता उपयोग कर रहे हैं। उनका उपयोग तभी किया जा सकता है जब आप 'term%' जैसी क्वेरी का उपयोग करते हैं। टैब के साथ एक एड्रेस बुक के बारे में सोचें, आप L अक्षर से शुरू होने वाले वास्तव में तेज़ संपर्क पा सकते हैं, लेकिन on के साथ संपर्क में कहीं भी संपर्क ढूंढने के लिए, आपको संपूर्ण पता पुस्तिका स्कैन करना होगा।

CREATE FULLTEXT INDEX title_desc 
ON table (title, description) 

और फिर क्वेरी में: इस के लिए

SELECT title, description FROM table 
WHERE MATCH (title, description) AGAINST ('+Pizza') 
0

मैं JohnB या gtr32x के जवाब के साथ जाना होगा (पूर्ण पाठ अनुक्रमण)। उनके उत्तर के पूरक के लिए, एक सरल पूर्ण पाठ अनुक्रमणिका बनाने के लिए एक मैन्युअल तरीका है जो सरल है और यह बहुत तेज़ है ...

कीवर्ड में शीर्षक और विवरण विभाजित करें, और उन्हें Keywords तालिका में रखें, जिसमें एक विदेशी कुंजी है मूल आरएसएस लेख। सुनिश्चित करें कि Keywords में कीवर्ड कॉलम अनुक्रमित है। आप कुछ ऐसा कर सकते हैं:

SELECT DISTINCT ra.* 
FROM RssArticle ra 
INNER JOIN Keywords k ON k.ArticleID = ra.ArticleID 
    WHERE k IN ('SearchTerm1', 'SearchTerm2', 'SearchTerm3') 
LIMIT 20; 

और यह तेज़ है!

+0

मुझे यकीन नहीं है कि आप इसका क्या मतलब है ... – supercoolville

0

निम्नलिखित चार प्रश्नों में से किसी का प्रयास करें:

select * from myTable where concat_ws(' ',title,description) like '%pizza%'; 
select * from myTable where concat_ws(' ',title,description) regexp '.*pizza+.*'; 
select title,description from myTable where concat_ws(' ',title,description) like '%pizza%'; 
select title,description from myTable where concat_ws(' ',title,description) regexp '.*pizza+.*'; 

बिंदु खोज

+0

यह लगभग 2x तेज था लेकिन मैक के खिलाफ जितना तेज़ नहीं था – supercoolville

संबंधित मुद्दे