Temprano en la mañana todos los días, un trabajo de pgAgent actualiza el contenido de la tabla A de la tabla B en mi base de datos PostgreSQL 8.4. La Tabla A contiene alrededor de 140k registros en 91 columnas y tiene dos índices: uno como parte de la PRIMARY KEY y el otro un índice GIST en una columna de geometría POINT PostGIS.
Para que el proceso vaya un poco más rápido, el trabajo coloca el índice en la columna de geometría, antes de eliminar los registros en la tabla A e insertar los registros de la tabla B, luego se vuelve a crear el índice. Todo esto hecho, el daemon de autovacuum se pone a trabajar cuando se siente (después de aproximadamente diez minutos de comparar las estadísticas del trabajo y las estadísticas de la tabla para el tiempo de finalización del trabajo y el tiempo de ejecución del autovacuum).
Al revisar la mesa esta mañana, después de que todo esto sucedió, las estadísticas de la mesa me dijeron que el tamaño de la mesa era de 272 MB, el tamaño de la mesa TOAST era de 8192 bytes y el tamaño del índice era de 23 MB. Esto parecía bastante grande, así que emití un comando REINDEX en la tabla y el tamaño del índice se redujo a 9832kB.
Mi pregunta (s) es esta:
¿Por qué REINDEX aparentemente reduce tanto el tamaño de los índices cuando los índices (o al menos el índice de la columna de geometría) se han creado de nuevo desde cero? ¿Debo asegurarme de que la tabla se haya aspirado / analizado antes de que se creen los índices? ¿No es caer el índice en la clave primaria un factor en esto? ¿Qué me estoy perdiendo?
fuente
ANALYZE
el tamaño informado también disminuye.Respuestas:
Si la instrucción CREATE INDEX ve que otra sesión contiene una instantánea activa que aún podría estar interesada en los registros eliminados, entonces incluye esos registros eliminados en el nuevo índice.
Del mismo modo, si un REINDEX ve que otra sesión contiene una instantánea activa que aún podría estar interesada en los registros eliminados, entonces incluye esos registros eliminados en el nuevo índice.
Si un VACÍO ve que otra sesión contiene una instantánea activa que aún podría estar interesada en los registros eliminados, entonces mantiene esos registros en la tabla. Y luego, REINDEX o CREATE INDEX también deben llevarlos al nuevo índice, siempre que la instantánea todavía exista.
Una vez allí o ya no haya instantáneas que puedan ver las filas eliminadas, el VACÍO puede eliminarlas de la tabla. Pero un CREATE INDEX o REINDEX tampoco podría simplemente llevarlos al nuevo índice, ya sea que VACUUM haya logrado eliminarlos de la capacidad o no.
Entonces, en su escenario, el papel de VACÍO entre CREATE INDEX inicial y REINDEX es probablemente solo para tomar tiempo, durante el cual su transacción de larga duración desaparece por sí sola y deja caer la instantánea interferente.
fuente
Después de haber intentado diferentes órdenes de hacer las cosas, parece que realizar un VACÍO antes de una instrucción REINDEX es la única forma de obtener la reducción de tamaño, tal vez porque el espacio no aspirado se agrega al índice (¿indexación de registros eliminados?). Forzar una reescritura de tablas usando
hace el mismo tipo de cosas, ya que despeja el espacio en desuso.
Tener que VACUUM en el medio del proceso interrumpe un poco el flujo, ya que uno debe emitir un comando VACUUM fuera de una transacción.
fuente