2 votos

¿Cómo puedo evitar el escaneo completo de una gran tabla PostGIS en QGIS?

Intento abrir una tabla grande de PostGIS en QGIS, con más de 500 filas. Me acerco a un área pequeña, y limito los zooms, por lo que se espera que la respuesta de la consulta sea razonablemente pequeña. Probado esto también directamente en la DB. La tabla tiene índices, así que puedo ver que la consulta en bruto es rápida. La tabla ya tiene único índice para dos campos ("partición", "partición_desplazamiento")

Problema: Cuando añado la tabla como capa, entonces QGIS se cuelga. Veo en la DB una consulta de larga duración: SELECT count(distinct ("partition","partition_offset"))=count(("partition","partition_offset")) FROM "public"."mytable_geo" y desde el planificador de consultas veo que esto hace un escaneo completo a la tabla, lo cual toma posiblemente horas en mi caso. Parece que QGIS quiere estar realmente seguro de que mi restricción "única" hace que los valores sean realmente únicos. ¿Hay alguna manera de evitarlo?

Versión de QGIS: 3.6.1-Noosa

Actualización: GDAL tiene parámetro checkPrimaryKeyUnicity='1' . Si esto se puede convertir en el valor "0" en QGIS, entonces debería ayudar, pero no han descubierto cómo / si esto es posible. No se puede encontrar la opción de interfaz de usuario para esto.

1 votos

No estoy seguro de si es el problema o no, pero un índice único puede tener valores repetidos si uno de ellos es nulo (2 nulos no son iguales). Intente marcar las columnas como no nulas, o declare una clave primaria compuesta (que no puede contener nulos por definición).

0 votos

@JGH ¿es posible marcar columnas como no nulas o tener claves primarias para la vista materializada? mi vista 500M es en realidad una subselección de otra tabla 1+B.

0 votos

¿Tiene un problema similar cuando se conecta a través de db_manager utilizando una consulta sin procesar? Es una solución provisional, pero normalmente db_manager omite algunas pruebas y no requiere un identificador único (a costa de estar en modo de sólo lectura).

2voto

Sanket Gupta Puntos 21

Una fea solución rápida, inspirada por mi compañero de soporte que siempre señala que las vistas materializadas no están todavía tan maduras como nos gustaría y que las antiguas soluciones siguen siendo útiles.

En lugar de una vista materializada, cree una tabla real refrescada por una vista.

  1. Asumiendo que los datos provienen de "mi_tabla_grande"
  2. Crear una vista "my_geo_table_refresh" que contenga la consulta/filtro real de "my_big_table"
    _PS: y tal vez crear una columna de identificación NO NULL utilizando row_number() OVER ()_
  3. Crear una tabla "my_geo_table" con la misma definición de columnas
  4. Configurar todos los índices pk/index/espaciales necesarios en "mi_tabla_geo"
  5. Cada vez que necesites refrescar esa "vista materializada de la vieja escuela" simplemente ejecuta ese SQL en una sola transacción:

    TRUNCATE TABLE "my_geo_table";
    INSERT INTO "my_geo_table" SELECT * FROM "my_geo_table_refresh";

    Por supuesto, esto es asumiendo un uso de sólo lectura y ninguna referencia que apunte a "mi_tabla_geo_", de lo contrario tendría que ser más cuidadoso y/o utilizar disparadores complejos.

También se puede escribir FUNCIÓN/PROCEDIMIENTO para refrescar la "vista materializada de la vieja escuela"
Eso podría ser más elegante ya que no aparecerá el intermediario "my_geo_table_refresh" en el catálogo.

0 votos

Gracias, esto parecía funcionar. Se necesitaban dos comandos para hacerlo rápido, y evitar un escaneo completo más para obtener la extensión completa: ANALYZE my_geo_table; -- bastante rápido, <1 min para una tabla de 500M+ filas SELECT ST_EstimatedExtent('my_geo_table', 'geom'); -- solo revisa si da algun alcance, muy rapido, tambien qis usa esto; pero solo si se hace el analisis.

0 votos

De nada.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X