2015-10-21 13 views
6

मैं प्रोपेल ORM पर चल रहे एक वेबसाइट पर काम करते हैं और मैं इस प्रश्न हैं:MySQL मैच ... क्वेरी बहुत धीमी गति से खिलाफ

if(isset($args["QueryText"]) && $args["QueryText"] != "") { 
    $query = $query 
    ->withColumn("(MATCH (Request.Subject, Request.Detail) AGAINST ('" . $args["QueryText"] . "' IN BOOLEAN MODE) + MATCH (Response.Response) AGAINST ('" . $args["QueryText"] . "' IN BOOLEAN MODE))", "RequestRelevance") 
    ->condition('cond1', "(MATCH (Request.Subject, Request.Detail) AGAINST ('" . $args["QueryText"] . "' IN BOOLEAN MODE) + MATCH (Response.Response) AGAINST ('" . $args["QueryText"] . "' IN BOOLEAN MODE)) > 0.2") 
    ->condition('cond2', 'Request.Id = ?', $args["QueryText"]) 
    ->where(array('cond1', 'cond2'), 'or') 
    ->orderBy("RequestRelevance", Criteria::DESC); 
} 

जो एसक्यूएल में निम्नलिखित करने के लिए अनुवाद:

SELECT DISTINCT 
(MATCH (requests.subject, requests.detail) AGAINST ('46104' IN BOOLEAN MODE) + 
    MATCH (Response.response) AGAINST ('46104' IN BOOLEAN MODE)) 
    AS RequestRelevance, requests.requestID AS "Id", requests.subject AS "Subject", requests.detail AS "Detail", requests.created AS "CreatedDate", requests.lastresponsedate AS "LastResponseDate", SupportStatus.supportstatusID AS "SupportStatus.Id", SupportStatus.supportstatus AS "SupportStatus.Name", SupportStatus.isnew AS "SupportStatus.IsNew", SupportStatus.isclosed AS "SupportStatus.IsClosed", CustomerGroup.customergroupID AS "CustomerGroup.Id", CustomerGroup.customergroup AS "CustomerGroup.Name", Site.siteID AS "Site.Id", Site.site AS "Site.Name", InternalUser.userID AS "InternalUser.Id", InternalUser.username AS "InternalUser.Username", User.userID AS "User.Id", User.username AS "User.Username", Customer.customerID AS "Customer.Id", Customer.customer AS "Customer.Name", Customer.customergroupID AS "Customer.CustomerGroupId", Customer.rate AS "Customer.Rate" 
FROM requests 
    LEFT JOIN responses Response ON (requests.requestID=Response.requestID) 
    INNER JOIN supportstatus SupportStatus ON (requests.supportstatusID=SupportStatus.supportstatusID) 
    INNER JOIN customergroups CustomerGroup ON (requests.customergroupID=CustomerGroup.customergroupID) 
    INNER JOIN customers Customer ON (requests.customerID=Customer.customerID) 
    INNER JOIN sites Site ON (requests.siteID=Site.siteID) 
    LEFT JOIN users InternalUser ON (requests.twistedfish_userID=InternalUser.userID) 
    LEFT JOIN users User ON (requests.userID=User.userID) 
WHERE ((MATCH (requests.subject, requests.detail) AGAINST ('46104' IN BOOLEAN MODE) + 
    MATCH (Response.response) AGAINST ('46104' IN BOOLEAN MODE)) > 0.2 OR requests.requestID = '46104') 
ORDER BY requests.created ASC,RequestRelevance DESC 

यह SQL क्वेरी चलाते समय प्रोपेल और 7.020 सेकंड का उपयोग कर वेबसाइट पर लोड करने के लिए एक अच्छा 20 सेकंड लेता है।

SELECT DISTINCT 
    requests.requestID AS "Id", requests.subject AS "Subject", requests.detail AS "Detail", requests.created AS "CreatedDate", requests.lastresponsedate AS "LastResponseDate", SupportStatus.supportstatusID AS "SupportStatus.Id", SupportStatus.supportstatus AS "SupportStatus.Name", SupportStatus.isnew AS "SupportStatus.IsNew", SupportStatus.isclosed AS "SupportStatus.IsClosed", CustomerGroup.customergroupID AS "CustomerGroup.Id", CustomerGroup.customergroup AS "CustomerGroup.Name", Site.siteID AS "Site.Id", Site.site AS "Site.Name", InternalUser.userID AS "InternalUser.Id", InternalUser.username AS "InternalUser.Username", User.userID AS "User.Id", User.username AS "User.Username", Customer.customerID AS "Customer.Id", Customer.customer AS "Customer.Name", Customer.customergroupID AS "Customer.CustomerGroupId", Customer.rate AS "Customer.Rate" 
FROM requests 
    LEFT JOIN responses Response ON (requests.requestID=Response.requestID) 
    INNER JOIN supportstatus SupportStatus ON (requests.supportstatusID=SupportStatus.supportstatusID) 
    INNER JOIN customergroups CustomerGroup ON (requests.customergroupID=CustomerGroup.customergroupID) 
    INNER JOIN customers Customer ON (requests.customerID=Customer.customerID) 
    INNER JOIN sites Site ON (requests.siteID=Site.siteID) 
    LEFT JOIN users InternalUser ON (requests.twistedfish_userID=InternalUser.userID) 
    LEFT JOIN users User ON (requests.userID=User.userID) 
WHERE (requests.subject LIKE '%46104%' OR requests.detail LIKE '%46104%' OR Response.response LIKE '%46104%' OR requests.requestID = '46104') 
ORDER BY requests.created 

जो निष्पादित करने के लिए 3.308 सेकंड लेता है:

मैं एक निम्न बजाय कोशिश की। इससे OR Response.response LIKE '%46104%' को हटाने से समय 0.140 सेकेंड तक कम हो जाता है। प्रतिक्रिया तालिका में 288317 पंक्तियां और प्रतिक्रियाएं होती हैं। प्रतिक्रिया कॉलम एक FLELTEXT अनुक्रमणिका के साथ एक टेक्स्ट() कॉलम है।

इस खोज के निष्पादन समय को कम करने का सबसे अच्छा तरीका क्या होगा? मैं हालांकि इस https://dba.stackexchange.com/questions/15214/why-is-like-more-than-4x-faster-than-match-against-on-a-fulltext-index-in-mysq जवाब का उपयोग कर की कोशिश की है जब मैं निष्पादित करें:

Error Code: 1191. Can't find FULLTEXT index matching the column list

मदद बहुत सराहना की जाएगी:

SELECT responseID FROM 
(
SELECT * FROM responses 
WHERE requestID = 15000 
AND responseID != 84056 
) A 
WHERE MATCH(response) AGAINST('twisted'); 

मैं इस त्रुटि मिलती है!

संपादित करें 1:

की कोशिश की @Richard ईबी के प्रश्न:

ALTER TABLE responses ADD FULLTEXT(response) 
288317 row(s) affected Records: 288317 Duplicates: 0 Warnings: 0 78.967 sec 

हालांकि:

SELECT responseID FROM ( SELECT * FROM responses  WHERE requestID = 15000  AND responseID != 84056) A WHERE MATCH(response) AGAINST('twisted') LIMIT 0, 2000 
Error Code: 1191. Can't find FULLTEXT index matching the column list 0.000 sec 

DISTINCT निकाला जा रहा है .952 सेकंड के लिए निष्पादन समय कम कर देता है लेकिन इसे पुनः प्राप्त नहीं है परिणाम मुझे चाहिए।

संपादित करें 2:

इस क्वेरी निष्पादित:

SELECT DISTINCT 
responses.requestID AS "Id" FROM responses WHERE MATCH(response) AGAINST('twisted') 

0,062 सेकेंड लेता है।

इस निष्पादित:

SELECT DISTINCT responses.requestID 
    FROM responses 
WHERE (
    MATCH (Responses.response) AGAINST ('twisted' IN BOOLEAN MODE) 
) 
ORDER BY responses.requestID ASC 

केवल 0.046 सेकेंड लेता है। हालांकि, अनुरोधों से चयन करना और प्रतिक्रियाओं में शामिल होना क्वेरी को धीमा कर देता है। मुझे यकीन नहीं है कि इसका अर्थ यह है कि प्रतिक्रियाओं से चुनने और अनुरोधों में शामिल होने के लिए पूरी क्वेरी को पूरी तरह से फिर से लिखा जाना चाहिए?

संपादित करें 3:

यहाँ अनुक्रमित मैं Requests पर है कि और Responses तालिकाओं हैं:

# Table, Non_unique, Key_name, Seq_in_index, Column_name, Collation, Cardinality, Sub_part, Packed, Null, Index_type, Comment, Index_comment 
    responses, 0, PRIMARY, 1, responseID, A, 288317, , , , BTREE, , 
    responses, 1, requestID, 1, requestID, A, 48052, , , YES, BTREE, , 
    responses, 1, response, 1, response, , 1, , , YES, FULLTEXT, , 
    responses, 1, response_2, 1, response, , 1, , , YES, FULLTEXT, , 
    responses, 1, response_3, 1, response, , 1, , , YES, FULLTEXT, , 

    # Table, Non_unique, Key_name, Seq_in_index, Column_name, Collation, Cardinality, Sub_part, Packed, Null, Index_type, Comment, Index_comment 
    requests, 0, PRIMARY, 1, requestID, A, 46205, , , , BTREE, , 
    requests, 1, supportstatusID, 1, supportstatusID, A, 14, , , YES, BTREE, , 
    requests, 1, twistedfish_userID, 1, twistedfish_userID, A, 344, , , YES, BTREE, , 
    requests, 1, customergroupID, 1, customergroupID, A, 198, , , , BTREE, , 
    requests, 1, userID, 1, userID, A, 1848, , , YES, BTREE, , 
    requests, 1, siteID, 1, siteID, A, 381, , , YES, BTREE, , 
    requests, 1, request, 1, subject, , 1, , , YES, FULLTEXT, , 
    requests, 1, request, 2, detail, , 1, , , YES, FULLTEXT, , 
    requests, 1, request, 3, ponumber, , 1, , , YES, FULLTEXT, , 

उत्तर

3

एक जैसे खोज हर रिकॉर्ड के माध्यम से जाने के लिए और गैर-सटीक स्ट्रिंग तुलना प्रदर्शन करेंगे, जो यही कारण है कि यह बहुत धीमी है।

आपके द्वारा चिपकाई गई mysql त्रुटि इंगित करती है कि MATCH क्लॉज में संदर्भित कॉलम में पूर्ण टेक्स्ट इंडेक्स नहीं है (या ऐसा करता है, लेकिन ऐसा नहीं है क्योंकि यह MATCH क्लॉज में संदर्भित है)।

ALTER TABLE responses ADD FULLTEXT(response); 

संपादित करें:: उत्तर (टिप्पणी में):

आप MyISAM का उपयोग कर या MySQL 5.6 है और InnoDB, कोशिश कर रहे हैं मान लिया जाये कि "यदि दो मैच बयान में उल्लेख किया स्तंभ हैं, तो ऐसा करना चाहिए उन दोनों कॉलम पर एक पूर्ण टेक्स्ट इंडेक्स बनें, प्रत्येक कॉलम पर दो पूर्ण टेक्स्ट इंडेक्स नहीं "

+0

धन्यवाद, मैंने कोशिश की है कि हालांकि इस मुद्दे को हल नहीं किया गया है। मैंने अपनी मूल पोस्ट संपादित की है। बात यह है कि, LIKE खोज में आधा समय लगता है कि MATCH ... खोज के खिलाफ हालांकि मुझे लगता है कि उत्तरार्द्ध को अनुकूलित/सुधारकर, यह पसंद की तुलना में बहुत तेज हो सकता है। क्या मैं सही हूँ? – Pawel

+0

जब आप केवल कोशिश करते हैं तो चुनें: चयन करें * प्रतिक्रियाओं से "प्रतिक्रिया" ('मुड़') यदि यह काम नहीं करता है, तो कोशिश करें: वैकल्पिक तालिका तालिका प्रतिक्रियाएं सक्षम करें यदि यह काम करता है, तो समस्या है फुलटेक्स्ट इंडेक्स के साथ नहीं, लेकिन जिस तरीके से आपने ऑर्डर लिखा है। –

+0

धन्यवाद, मैंने अपनी मूल पोस्ट को प्रश्नों और परिणामों के साथ संपादित किया है। – Pawel

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