Io lavoro su un sito web in esecuzione su Propel e ho questa domanda:MySQL Partita ... Contro di query molto lenta
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);
}
che si traduce al seguente in SQL:
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
E ' richiede un buon 20 secondi per caricare sul sito web utilizzando Propel e 7.020 secondi quando si esegue la query SQL.
Ho provato il seguente invece:
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
che richiede 3.308 secondi per eseguire. La rimozione di OR Response.response LIKE '%46104%'
da esso riduce il tempo a 0,140 secondi. La tabella delle risposte contiene 288317 righe e la colonna responses.responses è una colonna TEXT() con un indice FULLTEXT.
Quale sarebbe il modo migliore per ridurre il tempo di esecuzione di questa ricerca? Ho provato con questa https://dba.stackexchange.com/questions/15214/why-is-like-more-than-4x-faster-than-match-against-on-a-fulltext-index-in-mysq risposta tuttavia quando eseguo:
SELECT responseID FROM
(
SELECT * FROM responses
WHERE requestID = 15000
AND responseID != 84056
) A
WHERE MATCH(response) AGAINST('twisted');
ottengo questo errore:
Error Code: 1191. Can't find FULLTEXT index matching the column list
aiuto sarà molto apprezzato!
EDIT 1:
provato domanda di @pluto EB:
ALTER TABLE responses ADD FULLTEXT(response)
288317 row(s) affected Records: 288317 Duplicates: 0 Warnings: 0 78.967 sec
Tuttavia:
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
Rimozione DISTINCT
riduce il tempo di esecuzione di 0,952 secondi tuttavia non recupera i risultati di cui ho bisogno.
EDIT 2:
che esegue la query:
SELECT DISTINCT
responses.requestID AS "Id" FROM responses WHERE MATCH(response) AGAINST('twisted')
prende 0,062 secondi.
L'esecuzione di questo:
SELECT DISTINCT responses.requestID
FROM responses
WHERE (
MATCH (Responses.response) AGAINST ('twisted' IN BOOLEAN MODE)
)
ORDER BY responses.requestID ASC
richiede solo 0,046 secondi. Tuttavia, selezionare da Richieste e unire le risposte è ciò che rallenta la query. Non sono sicuro che ciò significhi che l'intera query deve essere completamente riscritta per selezionare da Risposte e unire Richieste invece?
EDIT 3:
Qui ci sono gli indici che ho sul Requests
e Responses
tabelle:
# 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, ,
Grazie, ho provato che tuttavia non ha risolto il problema. Ho modificato il mio post originale. Il fatto è che la ricerca LIKE impiega la metà del tempo che la ricerca MATCH ... CONTRO fa tuttavia suppongo che ottimizzando/migliorando quest'ultimo, potrebbe essere molto più veloce della ricerca LIKE. Ho ragione? – Pawel
Cosa succede quando si prova solo: SELECT * FROM risposte WHERE MATCH (risposta) CONTRO ('intrecciato') Se ciò non funziona, provare: ALTER TABLE risposte della tabella ENABLE KEYS Se funziona, il problema è non con l'indice di testo completo, ma nel modo/nell'ordine in cui hai scritto la query. –
Grazie, ho modificato il mio post originale con le query e i risultati. – Pawel