2010-01-06 14 views
6

In MySql, voglio individuare i record in cui il valore di stringa in una delle colonne inizia con (o è uguale a) una stringa di query. La colonna è indicizzata con l'ordine di confronto appropriato. Non c'è però un indice di ricerca full-text sulla colonna.In MySql, trovare stringhe con un prefisso dato

Una buona soluzione:

  1. utilizzare l'indicesulla colonna. Le soluzioni che devono scorrere tutti i record nella tabella non sono sufficienti (diversi milioni di record nella tabella)

  2. Lavorare con stringhe con qualsiasi valore di carattere. Alcuni dei valori delle colonne contengono caratteri di punteggiatura. La stringa di query potrebbe anche. Tienilo a mente se la tua soluzione include caratteri regex o simili. Le stringhe sono codificate in UTF-8, ma se la tua soluzione funziona solo con ASCII potrebbe comunque essere utile.

Il più vicino ho a questo punto è

SELECT * FROM TableName WHERE ColumnName BETWEEN query AND <<query+1>> 

Dove <<query+1>> viene pre-calcolata per seguire lessicograficamente query nell'ordine collazione. Ad esempio, se è "o hai", allora <<query+1>> è "o haj".

risposta

19

Sorprendentemente, una query LIKE utilizzerà un indice corretto se si sta eseguendo una ricerca prefisso.

SELECT * from TableName Where ColumnName LIKE 'o hai%' 

utilizzerà effettivamente un indice poiché non inizia con un carattere jolly.

questo (e altri comportamenti) è documentato nella sezione "Come MySQL utilizza indici" doc: http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html

dovrai sfuggire il carattere '%' e seguire regole di quoting normali, ma a parte che ogni utf -8 prefisso di input dovrebbe funzionare e fare il lavoro. Eseguire un EXPLAIN query per assicurarsi, a volte altri motivi possono precludere indici di lavorare come bisogno di fare un OPTIMIZE TABLE per aggiornare cardinalità indice (anche se questo può richiedere molto tempo e blocca la tabella)

+0

Perfetto - grazie. EXPLAIN indica infatti una query di intervallo. I documenti MySql per LIKE indicano che devono essere sfuggiti solo i seguenti caratteri: '%', '_': http://dev.mysql.com/doc/refman/5.0/en/string-comparison-functions.html#operator_like . –

+0

Potrei menzionare che nel caso in cui le cardinalità dell'indice debbano essere aggiornate, 'ANALYZE TABLE' è in teoria più veloce di' OPTIMIZE TABLE'. La tabella è ancora bloccata per scrivere durante questo tempo, però. Eseguire ANALYZE TABLE su un mio tavolo con ~ 6 milioni di file è durato un'ora buona. – Crast

2

Prova questo:

SELECT * FROM tablename WHERE columname LIKE CONCAT(query, '%'); 
+1

Funzionerebbe benissimo finché 'query' ha un% o un _ in esso. Devono essere scappati. – AndrewF

Problemi correlati