2011-05-05 16 views
9

A continuación se muestra una consulta que utilizo para buscar una persona por correo electrónicoMysql mejorar el rendimiento de búsqueda con comodines (%%)

SELECT * 
    FROM phppos_customers 
    JOIN phppos_people ON phppos_customers.person_id = phppos_people.person_id 
    WHERE deleted = 0 
    AND email LIKE '%f%' 
ORDER BY email ASC 

¿Agregar un índice en "e-mail" acelerar la consulta?

+0

[Esa explicación] (http://use-the-index-luke.com/sql/where-clause/searching-for-ranges/like-performance-tuning) podría ayudar a entender por qué no está funcionando. –

+1

[** Esta respuesta **] (http://stackoverflow.com/a/22531268/793309) muestra una buena técnica, indización de todos los sufijos, que puede hacer que este tipo de consulta funcione muy bien, pero a costa de algunos codificación adicional y mayores requisitos de almacenamiento. – antinome

Respuesta

14

No, ya que MySQL no será capaz de utilizar el índice cuando se tiene un comodín que lleva. Si cambió su LIKE a 'f%', entonces podría usar el índice.

8

No, Mysql no utilizará el índice porque LIKE argumento (%f%) comienza con el carácter comodín %. Si comienza con una constante, se usará el índice.

Más información: 7.5.3. How MySQL Uses Indexes

1

No podrá hacerlo más rápido con LIKE como todo el mundo dice (sobre el % al principio), pero puede mejorarlo un poco al unirse después de filtrar a su gente primero.

SELECT * 
    FROM (SELECT * 
      FROM `phppos_customers` 
     WHERE `deleted` = 0 
      AND `email` LIKE '%f%') `t_customers` 
    JOIN `phppos_people` ON `t_customers`.`person_id`=`phppos_people`.`person_id` 
ORDER BY `email` asc 
+0

Utilizando el 'LIKE' con un comodín lado izquierdo en una vista/en línea tabla derivada todavía no va a usar un índice ... –

+0

Nunca dije que lo haría ... –

+0

El PO se pregunta específicamente sobre el uso de índice ... I' Me inclino a menospreciar, ya que es consciente de que no proporciona nada de valor a la pregunta ... –

4

comodines el lado izquierdo de una operación de LIKE asegura que un índice, si existe uno en la columna de la email, no se puede utilizar.

búsqueda de texto completo (FTS) se prefiere la sintaxis para la búsqueda de cadenas de texto dentro a través de SQL. MySQL has native FTS functionality, using the MATCH/AGAINST syntax (Requires the table to use the MyISAM engine for v.5.5 and below. InnoDB FTS supported on v.5.6+):

SELECT c.*, p.* 
    FROM PHPPOS_CUSTOMERS c 
    JOIN PHPPOS_PEOPLE p ON p.person_id = c..person_id 
    WHERE deleted = 0 
    AND MATCH(email) AGAINST('f') 
ORDER BY email 

Pero hay tercera tecnología FTS parte, como Esfinge.

+0

detallé con el texto completo y hablamos un poco acerca de Sphynx aquí: http://stackoverflow.com/questions/3338889/how-to-find-similar-results-and-sort-by-similarity/3339034#3339034 –

+0

En MySQL 5.6 La funcionalidad FTS ahora está disponible en tablas InnoDB. – blo0p3r

3

En mi post aquí describo, en detalle, una técnica que permite a utilizar el índice con LIKE para una rápida %infix% búsqueda, a costa de algunos de almacenamiento extra:

https://stackoverflow.com/a/22531268/543814

Siempre que las cadenas sean relativamente pequeñas, el requisito de almacenamiento es generalmente aceptable.

Según Google, la dirección de correo electrónico promedio es 25 caracteres de longitud. Esto aumenta su almacenamiento requerido por un factor de 12.5 en promedio, y le da una búsqueda indexada rápida a cambio. (Ver mi publicación para los cálculos.)

Desde mi punto de vista, si está almacenando 10'000 direcciones de correo electrónico, también debería almacenar (el equivalente de) alrededor de 100'000 direcciones de correo electrónico. Si esto es lo que se necesita para permitirle usar un índice, eso parece una compensación aceptable. A menudo, el espacio en disco es barato, mientras que las búsquedas no indexadas no son asequibles.

Si usted decide tomar este enfoque, sugiero que se limite la longitud de entrada de direcciones de correo electrónico a 64 caracteres. Esas direcciones de correo electrónico raras (o atacantes) de tal longitud requerirán hasta 32 veces el almacenamiento habitual. Esto le da:

  1. protección contra un atacante tratando de inundar su base de datos, ya que estos aún no son muy impresionantes cantidades de datos.
  2. La expectativa de que la mayoría de las direcciones de correo electrónico no sean de esta longitud de todos modos.

Si se tiene en cuenta 64 caracteres demasiado dura un requisito, utilice 255 lugar, para un aumento del peor caso de almacenamiento del factor de 127.5. ¿Ridículo? Posiblemente. ¿Probable? ¿No rápido? Muy.

Cuestiones relacionadas