Lista de verificación de crítica de planes para PRs del equipo de aplicaciones en PostgreSQL 18.4 - flujo de trabajo estructurado que los agentes y humanos usan para aceptar o rechazar cambios de consulta con evidencia EXPLAIN.
## Habilidad EXPLAIN Review - Lista de verificación rápida- [ ] EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT) adjunto- [ ] Se ejecuta en staging con estadísticas a escala de producción (ANALYZE reciente)- [ ] Sin Seq Scan inesperado en tablas grandes- [ ] Estimaciones de filas dentro de 10x de lo real (Filas de Planificación vs. Reales)- [ ] Sin Sort en conjuntos de filas grandes sin soporte de índice LIMIT- [ ] Recuento de búferes justificado para la frecuencia de la consulta
EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)SELECT o.id, o.totalFROM orders oWHERE o.tenant_id = $1 AND o.status = 'open'ORDER BY o.created_at DESCLIMIT 50;
Cuándo invocar esta habilidad:
ORM o SQL escrito a mano en PR que toca una ruta crítica (hot path)
pgbadger/pg_stat_statements marcó regresión después del despliegue
El asesor sugirió un índice que necesita validación humana
PR de Entrada: El queryset de Django añade OR entre valores de status.
EXPLAIN (ANALYZE, BUFFERS)SELECT * FROM ordersWHERE tenant_id = $1 AND (status = 'open' OR status = 'pending');
Señales de FALLO en la salida: Seq Scan on orders (cost=0..250000 rows=1200000) Buffers: shared read=180000 Planning Rows: 50000 Actual Rows: 890000
Salida de la habilidad:
## Veredicto: FALLO### Problemas1. Seq Scan - el filtro en tenant_id + status debería usar un índice2. Estimación de filas con 18x de diferencia - ejecutar ANALYZE orders3. OR previene el uso simple de btree compuesto - considerar reescritura a IN (...)### Corrección Sugerida```sqlSELECT * FROM ordersWHERE tenant_id = $1 AND status IN ('open', 'pending');
CREATE INDEX CONCURRENTLY idx_orders_tenant_status ON orders (tenant_id, status);
## Análisis Profundo
### Rúbrica de Aprobación/Rechazo
| Señal | Aprobación | Rechazo |
| --- | --- | --- |
| Ruta de acceso | Index Scan / Index Only Scan en filtro | Seq Scan > 10k filas |
| Join | Hash/Merge en conjuntos grandes con claves de equi-join | Bucle anidado con seq scan interno |
| Sort | Escaneo de heap Top-N con índice | Sort externo en millones |
| Buffers | Estable vs frecuencia de llamada | Lectura de tabla completa por solicitud |
### Adjuntos Requeridos en el PR
```sql
-- Contexto de escala de la tabla
SELECT relname, n_live_tup, pg_size_pretty(pg_relation_size(oid))
FROM pg_class c JOIN pg_stat_user_tables s ON s.relid = c.oid
WHERE relname = 'orders';
SELECT relname, last_analyze, last_autoanalyzeFROM pg_stat_user_tables WHERE relname = 'orders';ANALYZE orders; -- staging antes de EXPLAIN si está desactualizado
Sí, cuando la selectividad es moderada y múltiples predicados se combinan. Fallar cuando el bitmap cubre la mayor parte de la tabla repetidamente a alto QPS.
¿Qué tan estricto con la deriva de la estimación de filas?
10x entre lo planificado y lo real activa la investigación de estadísticas o estadísticas extendidas. 2x puede ser aceptable en tablas volátiles.
¿La habilidad aprueba el DDL de índice de migración?