[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-deep-evm-27-rendimiento-postgresql-indices-vacuum":3},{"article":4,"author":42},{"id":5,"category_id":6,"title":7,"slug":8,"excerpt":9,"content_md":10,"content_html":11,"locale":12,"author_id":13,"published":14,"published_at":15,"meta_title":16,"meta_description":17,"focus_keyword":18,"og_image":19,"canonical_url":19,"robots_meta":20,"created_at":15,"updated_at":15,"tags":21,"category_name":22,"related_articles":23},"d8000000-0000-0000-0000-000000000127","a0000000-0000-0000-0000-000000000085","Deep EVM #27: Rendimiento de PostgreSQL a Escala — Índices, VACUUM y Optimización de Consultas","deep-evm-27-rendimiento-postgresql-indices-vacuum","Optimiza PostgreSQL para alto rendimiento: tipos de índices y cuándo usarlos, VACUUM y autovacuum, EXPLAIN ANALYZE, y técnicas de optimización de consultas para tablas de millones de filas.","## Índices: más allá de B-tree\n\nPostgreSQL soporta múltiples tipos de índices:\n\n### B-tree (predeterminado)\nIdeal para comparaciones de igualdad y rango:\n```sql\nCREATE INDEX idx_tx_block ON transactions (block_number);\n```\n\n### GIN (Generalized Inverted Index)\nIdeal para búsquedas en JSONB y arrays:\n```sql\nCREATE INDEX idx_tx_data ON transactions USING GIN (data);\n```\n\n### BRIN (Block Range Index)\nIdeal para datos naturalmente ordenados (timestamps, IDs secuenciales). Muy compacto:\n```sql\nCREATE INDEX idx_tx_created ON transactions USING BRIN (created_at);\n```\n\n### Hash\nSolo para igualdad exacta, más compacto que B-tree:\n```sql\nCREATE INDEX idx_tx_hash ON transactions USING HASH (tx_hash);\n```\n\n## VACUUM y autovacuum\n\nPostgreSQL usa MVCC (Multi-Version Concurrency Control). Las filas actualizadas o eliminadas no se borran físicamente — se marcan como \"muertas\". VACUUM limpia estas filas muertas.\n\n```sql\n-- VACUUM manual\nVACUUM (VERBOSE) transactions;\n\n-- Configurar autovacuum agresivo para tablas de alto tráfico\nALTER TABLE transactions SET (\n    autovacuum_vacuum_scale_factor = 0.01,\n    autovacuum_analyze_scale_factor = 0.005,\n    autovacuum_vacuum_cost_delay = 5\n);\n```\n\n## EXPLAIN ANALYZE\n\nLa herramienta más importante para optimización de consultas:\n\n```sql\nEXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)\nSELECT * FROM transactions\nWHERE block_number BETWEEN 18000000 AND 18001000\nAND from_addr = '\\xABC...'::bytea;\n```\n\nBusca:\n- **Seq Scan** en tablas grandes = necesitas un índice\n- **Bitmap Heap Scan** = OK, usa índice\n- **Index Only Scan** = óptimo, no necesita acceder a la tabla\n- **Nested Loop** con tabla grande = considera un Hash Join\n\n## Connection pooling con PgBouncer\n\nPostgreSQL crea un proceso por conexión. Con miles de conexiones concurrentes, esto consume memoria y CPU. PgBouncer multiplexa conexiones:\n\n```ini\n[databases]\nmydb = host=localhost port=5432 dbname=mydb\n\n[pgbouncer]\nlisten_port = 6432\npool_mode = transaction\nmax_client_conn = 10000\ndefault_pool_size = 50\n```\n\n## pg_stat_statements\n\nExtensión esencial para identificar consultas lentas:\n\n```sql\nSELECT query, calls, mean_exec_time, rows\nFROM pg_stat_statements\nORDER BY mean_exec_time DESC\nLIMIT 20;\n```\n\n## Conclusión\n\nEl rendimiento de PostgreSQL a escala requiere índices apropiados, VACUUM bien configurado, EXPLAIN ANALYZE para diagnosticar problemas, connection pooling y monitoreo continuo con pg_stat_statements.","\u003Ch2 id=\"ndices-m-s-all-de-b-tree\">Índices: más allá de B-tree\u003C\u002Fh2>\n\u003Cp>PostgreSQL soporta múltiples tipos de índices:\u003C\u002Fp>\n\u003Ch3>B-tree (predeterminado)\u003C\u002Fh3>\n\u003Cp>Ideal para comparaciones de igualdad y rango:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-sql\">CREATE INDEX idx_tx_block ON transactions (block_number);\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>GIN (Generalized Inverted Index)\u003C\u002Fh3>\n\u003Cp>Ideal para búsquedas en JSONB y arrays:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-sql\">CREATE INDEX idx_tx_data ON transactions USING GIN (data);\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>BRIN (Block Range Index)\u003C\u002Fh3>\n\u003Cp>Ideal para datos naturalmente ordenados (timestamps, IDs secuenciales). Muy compacto:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-sql\">CREATE INDEX idx_tx_created ON transactions USING BRIN (created_at);\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>Hash\u003C\u002Fh3>\n\u003Cp>Solo para igualdad exacta, más compacto que B-tree:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-sql\">CREATE INDEX idx_tx_hash ON transactions USING HASH (tx_hash);\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"vacuum-y-autovacuum\">VACUUM y autovacuum\u003C\u002Fh2>\n\u003Cp>PostgreSQL usa MVCC (Multi-Version Concurrency Control). Las filas actualizadas o eliminadas no se borran físicamente — se marcan como “muertas”. VACUUM limpia estas filas muertas.\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-sql\">-- VACUUM manual\nVACUUM (VERBOSE) transactions;\n\n-- Configurar autovacuum agresivo para tablas de alto tráfico\nALTER TABLE transactions SET (\n    autovacuum_vacuum_scale_factor = 0.01,\n    autovacuum_analyze_scale_factor = 0.005,\n    autovacuum_vacuum_cost_delay = 5\n);\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"explain-analyze\">EXPLAIN ANALYZE\u003C\u002Fh2>\n\u003Cp>La herramienta más importante para optimización de consultas:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-sql\">EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)\nSELECT * FROM transactions\nWHERE block_number BETWEEN 18000000 AND 18001000\nAND from_addr = '\\xABC...'::bytea;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Busca:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Cstrong>Seq Scan\u003C\u002Fstrong> en tablas grandes = necesitas un índice\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Bitmap Heap Scan\u003C\u002Fstrong> = OK, usa índice\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Index Only Scan\u003C\u002Fstrong> = óptimo, no necesita acceder a la tabla\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Nested Loop\u003C\u002Fstrong> con tabla grande = considera un Hash Join\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2 id=\"connection-pooling-con-pgbouncer\">Connection pooling con PgBouncer\u003C\u002Fh2>\n\u003Cp>PostgreSQL crea un proceso por conexión. Con miles de conexiones concurrentes, esto consume memoria y CPU. PgBouncer multiplexa conexiones:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-ini\">[databases]\nmydb = host=localhost port=5432 dbname=mydb\n\n[pgbouncer]\nlisten_port = 6432\npool_mode = transaction\nmax_client_conn = 10000\ndefault_pool_size = 50\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"pg-stat-statements\">pg_stat_statements\u003C\u002Fh2>\n\u003Cp>Extensión esencial para identificar consultas lentas:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-sql\">SELECT query, calls, mean_exec_time, rows\nFROM pg_stat_statements\nORDER BY mean_exec_time DESC\nLIMIT 20;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"conclusi-n\">Conclusión\u003C\u002Fh2>\n\u003Cp>El rendimiento de PostgreSQL a escala requiere índices apropiados, VACUUM bien configurado, EXPLAIN ANALYZE para diagnosticar problemas, connection pooling y monitoreo continuo con pg_stat_statements.\u003C\u002Fp>\n","es","b0000000-0000-0000-0000-000000000001",true,"2026-03-28T10:44:31.659082Z","Rendimiento de PostgreSQL a Escala — Índices, VACUUM y Optimización de Consultas","Optimización PostgreSQL: tipos de índices, VACUUM, EXPLAIN ANALYZE, PgBouncer y pg_stat_statements para alto rendimiento.","PostgreSQL rendimiento índices VACUUM",null,"index, follow",[],"DevOps",[24,30,36],{"id":25,"title":26,"slug":27,"excerpt":28,"locale":12,"category_name":22,"published_at":29},"d8000000-0000-0000-0000-000000000128","Deep EVM #28: Pipeline de Datos de Alto Rendimiento — Inserciones Batch, COPY y Resolución de Conflictos","deep-evm-28-pipeline-datos-alto-rendimiento-batch","Construye pipelines de datos de alto rendimiento con PostgreSQL usando protocolo COPY, patrones de upsert masivo, ajuste de WAL, connection pooling con PgBouncer y monitoreo.","2026-03-28T10:44:31.664358Z",{"id":31,"title":32,"slug":33,"excerpt":34,"locale":12,"category_name":22,"published_at":35},"d8000000-0000-0000-0000-000000000126","Deep EVM #26: Sharding vs Particionamiento — Arquitectura para Tablas Masivas","deep-evm-26-sharding-vs-particionamiento-tablas-masivas","Comprende las diferencias entre sharding y particionamiento: cuándo usar cada uno, estrategias de clave de distribución, consistencia entre shards, y patrones para escalar PostgreSQL horizontalmente.","2026-03-28T10:44:31.653366Z",{"id":37,"title":38,"slug":39,"excerpt":40,"locale":12,"category_name":22,"published_at":41},"d8000000-0000-0000-0000-000000000125","Deep EVM #25: Particionamiento de Tablas en PostgreSQL — Cuando Tu Tabla Supera 10M+ Filas","deep-evm-25-particionamiento-tablas-postgresql","Guía práctica de particionamiento en PostgreSQL para tablas grandes. Cubre particionamiento por rango, lista y hash con ejemplos reales, estrategias de migración y planificación de consultas.","2026-03-28T10:44:31.648416Z",{"id":13,"name":43,"slug":44,"bio":45,"photo_url":19,"linkedin":19,"role":46,"created_at":47,"updated_at":47},"Open Soft Team","open-soft-team","The engineering team at Open Soft, building premium software solutions from Bali, Indonesia.","Engineering Team","2026-03-28T08:31:22.226811Z"]