2012-06-09 15 views
5

Así que aquí es una tabla muy simple 'TBL':¿Por qué esta simple consulta de MySQL es tan lenta?

+---------+---------------------+------+-----+---------+----------------+ 
| Field | Type    | Null | Key | Default | Extra   | 
+---------+---------------------+------+-----+---------+----------------+ 
| val  | varchar(45)   | YES | MUL | NULL |    | 
| id  | bigint(20) unsigned | NO | PRI | NULL | auto_increment | 
+---------+---------------------+------+-----+---------+----------------+ 

e índices para ello:

+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | 
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 
| tbl |   0 | PRIMARY |   1 | id   | A   | 201826018 |  NULL | NULL |  | BTREE  |   | 
| tbl |   1 | val  |   1 | val   | A   |  881336 |  NULL | NULL | YES | BTREE  |   | 
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 

Estoy tratando este sencillo selecto:

select val from tbl where val = 'iii'; 

resultado: 86208 filas en el conjunto (0.08 seg)

Pero cuando quiero modificarlo ligeramente:

select id, val from tbl where val = 'iii'; 

el resultado es: 86208 filas en el conjunto (47.30 segundos)

que tienen un índice derecho en el que coumn donde los puntos a, todo lo que la modificación es la representación filas de resultados. ¿Por qué hay un retraso tan aterrador? (Debo decir que no puedo reproducir este retraso cada vez que quiero: incluso después de 'reiniciar la caché de consultas' o establecer el comando 'query_cache_type = off' se puede hacer rápidamente).

+2

Puede intentar ejecutar 'EXPLAIN', pero sospecha que se trata más de un problema relacionado con el servidor. –

+0

¿Por qué debería seleccionar 86 mil campos y hacer eso de DOS columnas? Creo que el problema aquí es la lógica de la consulta:/¿Quizás deberías compartir lo que debes lograr? –

+0

Engine ?, prueba el índice de texto completo – jcho360

Respuesta

3

Sin examinar realmente la configuración de su servidor es difícil de decir, pero aquí hay una conjetura. En primer lugar, MySQL puede satisfacer su consulta sin leer realmente los datos de la tabla. Toda la información que ha solicitado se puede recuperar solo del índice. Observe que la cardinalidad del índice val es solo del orden de 10 filas, y las filas serán muy cortas en el índice.

En el segundo caso, ha solicitado datos NO en el índice en val. Ahora el motor tiene que encontrar y leer filas de los datos. Aquí la cardinalidad es aproximadamente 250 veces mayor, y dado que el índice recuperará las filas ordenadas por val, encontrar los valores id correspondientes requerirá MUCHO saltar en varios cientos de gigas de datos en el disco. Esto va a ser mucho más lento.

+0

esta es la razón. – Sebas

+0

Sí, el índice de tupla apropiado hizo la cosa. Gracias y por favor visite mi nueva pregunta: http://stackoverflow.com/questions/11004651/how-to-make-well-indexed-mysql-tables-join-effectively :) –

0

Intente agregar un ORDER BY y `LIMIT a la consulta. Eso debería ayudar mucho.

Creo que si se cambia la consulta a este que será más rápido:

select id, val from tbl where val = 'iii' order by val limit 10; 
+0

"limit" limitará solo el número de filas recuperadas ... es más rápido, pero si necesita el conjunto de datos completo, es inútil. por otro lado, el "orden por" ralentizará la consulta, porque el servidor tiene que ordenar el conjunto de resultados antes de enviar los datos – Barranka

+0

El orden por ralentizará la consulta – jcho360

+0

@Barranka: suponiendo que estaba seleccionando todas las filas, sí. De lo contrario, estaba seleccionando algunas filas aleatorias y la base de datos no sabe cómo optimizar eso. – Wolph

0

Estás haciendo un selecto basado en dos columnas, pero no hay ningún índice de ambos. Intente agregar un nuevo índice que conste de ambos id y val.

+1

¿por qué necesitaría un índice en la identificación cuando solo está buscando en val? – gbjbaanb

Cuestiones relacionadas