2011-01-20 11 views
13

La mia query ha un join, e sembra che stia usando due indici che lo rende più complicato. Non sono sicuro di poter migliorare, ma ho pensato di chiedere.Non sono sicuro di avere gli indici corretti o se posso migliorare la velocità della mia query in MySQL?

La query produce un elenco di record con parole chiave simili al record interrogato.

Ecco la mia domanda.

SELECT match_keywords.padid, 
     COUNT(match_keywords.word) AS matching_words 
FROM keywords current_program_keywords 
     INNER JOIN keywords match_keywords 
     ON match_keywords.word = current_program_keywords.word 
WHERE match_keywords.word IS NOT NULL 
     AND current_program_keywords.padid = 25695 
GROUP BY match_keywords.padid 
ORDER BY matching_words DESC 
LIMIT 0, 11 

Il SPIEGARE alt text

Word è varchar (40).

+0

chiarimenti richiesti: si dice simile, ma nella query si utilizza 'ON match_keywords.word = current_program_keywords.word' significa entrambe le parole sono le stesse. Ora, se record # 25695.word = 'aaa', la query restituirà' n' righe che hanno word = 'aaa' ... il gruppo BY e ORDER BY non ha alcun senso. 'N 'è l'unica variabile a cui sei interessato? –

+0

Simile, anno in quanto corrisponde a quante più parole possibile e fornisce un conteggio del maggior numero di corrispondenze, l'ordinamento su che fornisce i record più simili. – Jules

risposta

9

È possibile iniziare tentando di rimuovere il test IS NOT NULL, che è implicitamente rimosso da COUNT sul campo. Sembra anche che tu voglia omettere 25695 da match_keywords, altrimenti 25695 (o altro) verrebbe sicuramente visualizzato come la "migliore" corrispondenza entro il limite di 11 righe?

SELECT  match_keywords.padid, 
      COUNT(match_keywords.word) AS matching_words 
FROM  keywords current_program_keywords 
INNER JOIN keywords match_keywords 
     ON match_keywords.word = current_program_keywords.word 
WHERE  current_program_keywords.padid = 25695 
GROUP BY match_keywords.padid 
ORDER BY matching_words DESC 
LIMIT  0, 11 

Quindi, pensa a come lo faresti come persona.

  • Si sarebbe iniziare con un padid (25695) e recuperare tutte le parole per quel padid
  • Da quelli elenco di parole, tornare indietro nella tabella di nuovo e per ogni parola corrispondente, ottenere il loro padid (presume di avere alcun duplicato padid + word)
  • gruppo del padid insieme e contarli
  • ordine i conti e tornare il più alto 11

Con la vostra lista di 3 sepa tasso di indici a colonna singola, i primi due passaggi (entrambi coinvolgono solo 2 colonne) dovranno sempre passare dall'indice ai dati per ottenere l'altra colonna. Coprendo indici può aiutare qui - a creare due indici compositi per testare

create index ix_keyword_pw on keyword(padid, word); 
create index ix_keyword_wp on keyword(word, padid); 

Con questi indici compositi in atto, è possibile rimuovere gli indici di colonna singola su padid e word poiché essi sono coperti da questi due.

Nota: Devi sempre temperare le prestazioni SELECT

  • dimensioni degli indici (più si crea più di memorizzare)
  • inserto/prestazioni di aggiornamento (i più indici, più tempo ci vuole per commit dal momento che deve aggiornare i dati, quindi aggiornare tutti gli indici)
+0

Il modo in cui lo faresti come una persona non è necessariamente il modo in cui l'ottimizzatore scegliere; Sicuramente ricordo SQL Server che elabora una semplice query di mine, esattamente il contrario della logica ingenua. – pascal

+0

Ma per andare oltre in questa direzione avremmo bisogno di una migliore comprensione del numero di padid, word, word/padid ... Se leggo correttamente la EXPLAIN, per 25695, otteniamo 8 parole, e solo 5 linee corrispondenti a queste 8 parole ... che probabilmente non è il caso medio. – pascal

+1

Hai un errore nel ragionamento. 'rimuovere il test IS NOT NULL, che è implicitamente rimosso da COUNT' non è corretto, l'IS NOT NULL è ridondante a causa di inner join su' match_keywords.word = current_program_keywords.word' –

1

Si dovrebbe indicizzare i seguenti campi (verificare in quale tabella corrisponde)

match_keyword.padid

current_program_keywords.padid

match_keyword.words

current_program_keywords.words

Speranza aiuta ad accelerare

+0

È una tabella denominata parole chiave. – Jules

+0

Ho un indice su word e padid – Jules

+0

Quindi non credo che ci sia molto altro da ottimizzare –

5

Provare quanto segue ... assicurare l'indice su PadID e uno su WORD. Quindi, cambiando l'ordine del qualificatore SELECT WHERE deve essere prima eseguito l'ottimizzazione sul PADID della parola chiave CURRENT, quindi unirsi agli altri ... Escludere un join su se stesso. Inoltre, dal momento che stavi verificando l'uguaglianza sul inner join per abbinare le parole chiave ... se la parola chiave corrente è selezionata come null, non dovrebbe mai unirsi a un valore nullo, eliminando così un confronto sull'alias delle parole chiave MATCH come se fosse a confronto come alla ricerca di NULL ...

SELECT STRAIGHT_JOIN 
     match_keywords.padid, 
     COUNT(*) AS matching_words 
    FROM 
     keywords current_program_keywords 
     INNER JOIN keywords match_keywords   
      ON match_keywords.word = current_program_keywords.word 
      and match_keywords.padid <> 25695 
    WHERE 
      current_program_keywords.padid = 25695 
     AND current_program_keywords.word IS NOT NULL 
    GROUP BY 
     match_keywords.padid 
    ORDER BY 
     matching_words DESC 
    LIMIT 
     0, 11 
Problemi correlati