2010-01-06 17 views
6

En MySql, quiero ubicar registros donde el valor de cadena en una de las columnas comienza con (o es lo mismo que) una cadena de consulta. La columna está indexada con el orden de clasificación apropiado. Sin embargo, no hay un índice de búsqueda de texto completo en la columna.En MySql, busque cadenas con un prefijo dado

Una buena solución será:

  1. utilizar el índiceen la columna. Las soluciones que necesitan para iterar sobre todos los registros de la tabla no son lo suficientemente bueno (varios millones de registros de la tabla)

  2. trabajar con cadenas con cualquier carácter valora. Algunos de los valores de columna contienen signos de puntuación. La cadena de consulta también podría. Tenga esto en cuenta si su solución incluye caracteres regex o similares. Las cadenas están codificadas en UTF-8, pero si su solución solo funciona con ASCII, podría ser útil.

El más cercano que tengo en este momento es

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

Dónde <<query+1>> se calcularán previamente a seguir lexicográfico query en el orden de clasificación. Por ejemplo, si query es "o hai", entonces <<query+1>> es "o haj".

Respuesta

19

Sorprendentemente, una consulta LIKE utilizará un índice muy bien si está haciendo una búsqueda de prefijo.

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

utilizará un índice, ya que no comienza con un carácter comodín.

este (y otros comportamientos) se documenta en la sección "Cómo utiliza MySQL los índices" doc: http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html

Usted tendrá que escapar del carácter '%' y seguir las reglas de cotización normales, pero aparte de eso cualquier utf -8 prefijo de entrada debe funcionar y hacer el trabajo. Ejecutar una consulta EXPLAIN para asegurarse de que, a veces otras razones pueden impedir que los índices de trabajo, tales como la necesidad de hacer un OPTIMIZE TABLE para actualizar cardinalidades índice (aunque esto puede tomar las edades y bloquea su mesa)

+0

Perfecto - gracias. EXPLAIN de hecho indica una consulta de rango. Los documentos de MySql para LIKE indican que solo se deben escapar los siguientes caracteres: '%', '_': http://dev.mysql.com/doc/refman/5.0/en/string-comparison-functions.html#operator_like . –

+0

Podría mencionar que en el caso de que las cardinalidades de índice necesiten actualizarse, 'ANALYZE TABLE' es en teoría más rápido que' OPTIMIZE TABLE'. Sin embargo, la tabla todavía está bloqueada para escribir durante este tiempo. Ejecutar ANALYZE TABLE en una mesa mía con ~ 6 millones de filas tomó una buena hora. – Crast

2

Prueba esto:

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

Eso funcionaría bien hasta que 'query' tenga un% o un _ en él. Ellos necesitan ser escapados. – AndrewF

Cuestiones relacionadas