¿Es mejor crear un índice antes de llenar una tabla con datos o después de que los datos estén en su lugar?

87

Tengo una tabla de aproximadamente 100 millones de filas que voy a copiar para modificar, agregando un índice. No estoy tan preocupado por el tiempo que lleva crear la nueva tabla, pero ¿el índice creado será más eficiente si modifico la tabla antes de insertar cualquier dato o inserto los datos primero y luego agrego el índice?

Drew Stephens
fuente

Respuestas:

113

Crear un índice después de la inserción de datos es una forma más eficiente (incluso a menudo se recomienda eliminar el índice antes de la importación por lotes y después de la importación volver a crearlo).

Ejemplo sintético (PostgreSQL 9.1, máquina de desarrollo lento, un millón de filas):

CREATE TABLE test1(id serial, x integer);
INSERT INTO test1(id, x) SELECT x.id, x.id*100 FROM generate_series(1,1000000) AS x(id);
-- Time: 7816.561 ms
CREATE INDEX test1_x ON test1 (x);
-- Time: 4183.614 ms

Insertar y luego crear índice - aproximadamente 12 segundos

CREATE TABLE test2(id serial, x integer);
CREATE INDEX test2_x ON test2 (x);
-- Time: 2.315 ms
INSERT INTO test2(id, x) SELECT x.id, x.id*100 FROM generate_series(1,1000000) AS x(id);
-- Time: 25399.460 ms

Cree un índice y luego insértelo: aproximadamente 25,5 segundos (más de dos veces más lento)

Valodzka
fuente
5
+1, los índices ralentizarán notablemente una operación que implique una tarea de inserción de filas de 100 millones, por lo que es mejor eliminarlos y volver a crearlos.
code4life
10

Probablemente sea mejor crear el índice después de agregar las filas. No solo será más rápido, sino que el equilibrio del árbol probablemente será mejor.

Editar "equilibrio" probablemente no sea la mejor opción de términos aquí. En el caso de un árbol b, está equilibrado por definición. Pero eso no significa que el árbol b tenga el diseño óptimo. La distribución de nodos secundarios dentro de los padres puede ser desigual (lo que genera más costos en futuras actualizaciones) y la profundidad del árbol puede terminar siendo más profunda de lo necesario si el equilibrio no se realiza cuidadosamente durante las actualizaciones. Si el índice se crea después de agregar las filas, es más probable que tenga una mejor distribución. Además, las páginas de índice en el disco pueden tener menos fragmentación después de que se crea el índice. Un poco más de información aquí

Mark Wilkins
fuente
2

Esto no importa en este problema porque:

  1. Si agrega datos primero a la tabla y luego agrega index. El tiempo de generación de su índice será más O(n*log(N))largo (donde nse agregan filas). Debido a que el tiempo de generación del árbol es O(N*log(N))entonces, si divide esto en datos antiguos y datos nuevos, obtiene, O((X+n)*log(N))esto simplemente se puede convertir aO(X*log(N) + n*log(N)) y en este formato simplemente puede ver lo que esperará adicionalmente.
  2. Si agrega index y luego coloca data. Cada fila (tiene nnuevas filas) obtiene más tiempo de inserción adicional O(log(N))necesario para regenerar la estructura del árbol después de agregar un nuevo elemento (columna de índice de una nueva fila, porque el índice ya existe y se agregó una nueva fila, entonces el índice debe regenerarse para equilibrar estructura, este costo O(log(P))donde Pes un índice de potencia [elementos en índice] ). Usted tiene nnuevas filas, finalmente, usted tiene n * O(log(N))a continuación O(n*log(N))resumen tiempo adicional.
Svisstack
fuente
1

Los índices creados después son mucho más rápidos en la mayoría de los casos. Caso en cuestión: 20 millones de filas con texto completo en varchar (255) - (Nombre de la empresa) Índice en su lugar mientras se importan filas - una coincidencia en contra de tomar hasta 20 segundos en el peor de los casos. Deje caer el índice y vuelva a crear: coincida con tomar menos de 1 segundo cada vez

Mike Cross
fuente
-2

No estoy seguro de que realmente importe por el bien de la eficiencia del índice, ya que en ambos casos está insertando nuevos datos en el índice. El servidor no sabría cuán desequilibrado estaría un índice hasta después de su construcción, básicamente. En cuanto a la velocidad, obviamente, haga las inserciones sin el índice.

Gran MaestroB
fuente