6

Estoy construyendo una base de datos MySQL que contiene entradas sobre subcadenas especiales de ADN en especies de levadura. Mi tabla se ve así:COUNT y GROUP BY en los campos de texto parece lento

+--------------+---------+------+-----+---------+-------+ 
| Field  | Type | Null | Key | Default | Extra | 
+--------------+---------+------+-----+---------+-------+ 
| species  | text | YES | MUL | NULL |  | 
| region  | text | YES | MUL | NULL |  | 
| gene   | text | YES | MUL | NULL |  | 
| startPos  | int(11) | YES |  | NULL |  | 
| repeatLength | int(11) | YES |  | NULL |  | 
| coreLength | int(11) | YES |  | NULL |  | 
| sequence  | text | YES | MUL | NULL |  | 
+--------------+---------+------+-----+---------+-------+ 

Hay aproximadamente 1,8 millones de registros. En un tipo de consulta Quiero ver cuántos sub-cadenas de ADN están asociados con cada tipo de especie y región, por lo que expido el presente consulta:

select species, region, count(*) group by species, region; 

Las especies y columnas región tiene sólo dos posibles entradas (conservada/SCER para especies, y promotor/codificación para región) aún esta consulta toma alrededor de 30 segundos.

¿Es esta una cantidad de tiempo normal a esperar para este tipo de consulta dado el tamaño de la tabla? ¿Es lento porque estoy usando campos de texto en lugar de enteros simples o valores booleanos (prefiero campos de texto ya que varios investigadores que no son CS usarán la base de datos). Cualquier otra idea y sugerencia sería bienvenida.

Disculpe, por favor, si se trata de una pregunta objetiva, soy un neófito de SQL.

P.S. También he visto this question pero la solución propuesta no parece relevante para lo que estoy haciendo.

EDIT: Convirtiendo esos campos a VARCHAR redujo el tiempo de ejecución a ~ 2.5 segundos. Tenga en cuenta que también lo sincronicé contra ENUM que tuvieron un tiempo similar.

+0

¿Qué campo es su clave principal? –

+0

No tengo una clave principal. Podría hacer artificialmente uno, pero ¿importaría? – Rich

Respuesta

6

¿Por qué todas sus columnas basadas en cadenas se definen como TEXT? Si lee la comparación del rendimiento, verá que el TEXTO fue ~ 3 veces más lento que una columna VARCHAR con la misma indexación: http://forums.mysql.com/read.php?24,105964,105964

+0

Buena captura. No noté que eran 'texto'. –

+0

Hice TEXTO porque un colega de los míos dijo que no habría ninguna diferencia entre eso y VARCHAR. :) Usar un VARCHAR tomó mi tiempo de ejecución de 33 segundos a 2.5. – Rich

+0

@Rich: Wow - no esperaba una diferencia tan dramática. Puede ser que baje si se cambiaron las columnas de especie y región para que sean claves foráneas para las tablas que contienen sus respectivos valores. Una INT siempre es de 4 bytes, mientras que una VARCHAR (4) es 5, por lo que puede imaginar cuántos bytes es VARCHAR (100). –

3

Si sus campos solo van a tener 2 valores, será mejor que los convierta en booleanos. También debe hacer todo NOT NULL a menos que haya una razón real por la que necesite que sea NULL.

También vea el ENUM type para una mejor forma de usar una cantidad finita de valores legibles por humanos para una columna.

En cuanto a la lentitud, lo primero que debe intentar es crear índices en sus columnas. Para la consulta en particular que está mostrando aquí, un índice en species, region debe hacer una gran diferencia:

create index on mytablename (species, region); 

debe hacerlo.

+2

¿Estás seguro de que el índice hará una gran diferencia con estos datos de baja cardinalidad? –

+1

No, no estoy seguro, pero creo que es una buena suposición. Empecé a escribir sobre el uso de 'EXPLAIN', pero comenzó a convertirse en una lata de gusanos. Y supuse que el resultado final probablemente sería que deberíamos intentar crear un índice de todos modos. – Vineet

+0

Probé el índice, pero no hizo ninguna diferencia. También probé VARCHAR como OMG Ponies sugirió que era mucho más rápido. Después de eso lo probé contra enumeraciones sin una velocidad notable de VARCHARs. – Rich