Tengo una mesa con 1.4 billones de registros. La estructura de la tabla es la siguiente:
CREATE TABLE text_page (
text VARCHAR(255),
page_id INT UNSIGNED
) ENGINE=MYISAM DEFAULT CHARSET=ascii
El requisito es crear un índice sobre la columna text
.
El tamaño de la mesa es de aproximadamente 34G.
He intentado crear el índice con la siguiente declaración:
ALTER TABLE text_page ADD KEY ix_text (text)
Después de 10 horas de espera, finalmente abandono este enfoque.
¿Hay alguna solución viable para este problema?
ACTUALIZACIÓN : es poco probable que la tabla se actualice, inserte o elimine. La razón por la que se crea un índice en la columna text
es porque este tipo de consulta SQL se ejecuta con frecuencia:
SELECT page_id FROM text_page WHERE text = ?
ACTUALIZACIÓN : He resuelto el problema al particionar la tabla.
La mesa está dividida en 40 piezas en columna text
. Luego, la creación del índice en la tabla tarda aproximadamente 1 hora en completarse.
Parece que la creación del índice MySQL se vuelve muy lenta cuando el tamaño de la tabla se vuelve muy grande. Y la partición reduce la tabla en troncos más pequeños.
CREATE INDEX
declaración normal ?Respuestas:
¿Podría ser que su sistema simplemente no está a la altura? No uso MySQL (SQL Server aquí), pero conozco el dolor de indexar una tabla de 800 millones de entradas. Básicamente ... necesita el hardware adecuado para eso (como en: muchos discos rápidos). Ahora uso casi una docena de Velociraptors y el rendimiento es excelente;)
Los servidores SQL (no como MS SQL Server, sino como servidores de bases de datos que usan SQL) viven y mueren con acceso a disco, y los discos normales simplemente no están a la altura de las operaciones más grandes.
fuente
Es posible que desee crear un índice en los primeros (por ejemplo, 10) caracteres del campo de texto.
De los documentos:
Se pueden crear índices que utilicen solo la parte inicial de los valores de columna, utilizando la sintaxis col_name (longitud) para especificar una longitud de prefijo de índice:
fuente
He resuelto el problema dividiendo la tabla.
La mesa está dividida en 40 piezas en columna
text
. Luego, la creación del índice en la tabla tarda aproximadamente 1 hora en completarse.Parece que la creación del índice MySQL se vuelve muy lenta cuando el tamaño de la tabla se vuelve muy grande. Y la partición reduce la tabla en troncos más pequeños.
fuente
Establezca sort_buffer_size en 4GB (o la cantidad que pueda dependiendo de la cantidad de memoria que tenga).
En este momento, el índice de creación está haciendo una clasificación, pero dado que tiene un 32MB sort_buffer_size, básicamente está agotando innecesariamente el disco duro.
fuente
Si no necesita hacer consultas como:
Sugeriría crear una nueva columna hash e indexar la tabla por la columna. El tamaño general de la tabla + índice podría ser mucho menor.
UPD : Por cierto, 1.400 millones de enteros de clave primaria ocupan alrededor de 6 GB, es decir, la longitud promedio de la cadena es inferior a 30 caracteres, por lo que es más preferible indexar en un prefijo.
También deberías echar un vistazo al motor de almacenamiento MERGE .
fuente
Una forma de hacerlo es crear una nueva tabla con el conjunto de índices y copiar los datos a la nueva tabla.
Además, asegúrese de tener suficiente espacio temporal.
fuente
En caso de que todavía se pregunte cómo hacerlo mejor, le sugiero que use una herramienta de alteración de tablas en línea.
Hay muchos en Internet, uno de los famosos es:
http://www.percona.com/doc/percona-toolkit/2.2/pt-online-schema-change.html
Tenemos los mismos problemas con las tablas grandes (más de 500 mil registros) y la modificación es perfecta. Crea una nueva tabla tmp, agrega disparador en la tabla original (para los nuevos registros de actualización / eliminación / inserción) y, mientras tanto, copia todos los registros a la nueva tabla (con la nueva estructura)
¡Buena suerte!
fuente