Performance & Scalability serimizin bir parçası
Tam kılavuzu okuyunPostgreSQL 17: Uygulama Geliştiricileri için Yeni Özellikler
PostgreSQL 17, nihayet uzun süredir istenen birçok SQL yeteneğini ana akım haline getiren bir özellik seti ile birlikte geldi. Veritabanı yöneticileri vakum iyileştirmelerine ve mantıksal çoğaltma geliştirmelerine odaklanırken, uygulama geliştiricileri de aynı derecede ilgi çekici eklemeler alıyor: JSON'u ilişkisel veriler olarak sorgulamak için JSON_TABLE, önemli MERGE deyimi iyileştirmeleri, yeni toplama işlevleri ve her sorguyu etkileyen performans kazanımları.
Bu kılavuz yalnızca uygulama kodunu yazma şeklinizi değiştiren özelliklere (SQL kalıpları, ORM entegrasyon noktaları ve PostgreSQL 17'de mümkün veya daha iyi hale gelen mimari kararlar) odaklanmaktadır.
Önemli Çıkarımlar
JSON_TABLEartık standart — JSON dizilerini sanki özel işlevleri olmayan tablolarmış gibi sorgulayınMERGEdeyimiRETURNINGdeyimini kazandı — etkilenen satırları ikinci bir sorgu olmadan alınANY_VALUE()toplama, sorguların tam GROUP BY listeleri olmadan gruplandırılmasını kolaylaştırır- Artımlı sıralama iyileştirmeleri, sıralı verilerdeki sorgu planı maliyetini azaltır
COPYkomutu, tamamen başarısız olmak yerine hatalı satırları atlamak içinON_ERROR'yi desteklerpg_stat_iogörünümü, performans analizi için ilişki başına kesin G/Ç istatistiklerini verir- Mantıksal çoğaltma artık dizileri destekleyerek aktif-aktif kurulumlar arasındaki büyük boşluğu kapatıyor
VACUUMiyileştirmeleri şişkinlik birikimini azaltır — daha az acil otovakum
JSON_TABLE: JSON'u İlişkisel Veri Olarak Sorgulama
Uygulama geliştiricileri için en etkili SQL özelliği JSON_TABLE'dir. Uygulamalar sıklıkla dizileri veya iç içe geçmiş nesneleri JSONB sütunlarında depolar. PostgreSQL 17'den önce, bu verileri sorgulamak, yanal birleştirmelerle tuhaf jsonb_array_elements işlev çağrıları gerektiriyordu.
Bir siparişin satır öğelerini saklayan bir JSONB sütununu düşünün:
-- orders.metadata column:
-- {
-- "items": [
-- {"sku": "PROD-001", "qty": 2, "price": 49.99},
-- {"sku": "PROD-002", "qty": 1, "price": 129.99}
-- ]
-- }
PostgreSQL 17'den önce (jsonb_array_elements kullanarak):
SELECT
o.id,
o.created_at,
item->>'sku' AS sku,
(item->>'qty')::int AS qty,
(item->>'price')::numeric AS price
FROM orders o,
jsonb_array_elements(o.metadata->'items') AS item
WHERE o.organization_id = $1;
JSON_TABLE ile PostgreSQL 17:
SELECT
o.id,
o.created_at,
items.sku,
items.qty,
items.price
FROM orders o,
JSON_TABLE(
o.metadata,
'$.items[*]'
COLUMNS (
sku VARCHAR PATH '$.sku',
qty INTEGER PATH '$.qty',
price NUMERIC PATH '$.price'
)
) AS items
WHERE o.organization_id = $1;
JSON_TABLE sürümü daha okunabilirdir, açık sütun türleri sağlar ve sorgu planlayıcının birleştirme optimizasyonuna katılır. Ayrıca DEFAULT NULL ON EMPTY ve DEFAULT 0 ON ERROR sütun seçenekleriyle eksik anahtarları sorunsuz bir şekilde işler.
Daha karmaşık örnek - hata işlemeyle iç içe geçmiş JSON:
SELECT
products.id,
specs.weight_kg,
specs.color,
specs.dimensions_cm
FROM products,
JSON_TABLE(
products.specifications,
'$.specs'
COLUMNS (
weight_kg NUMERIC PATH '$.weight'
DEFAULT 0 ON EMPTY DEFAULT 0 ON ERROR,
color VARCHAR PATH '$.color'
DEFAULT 'unknown' ON EMPTY,
dimensions_cm VARCHAR PATH '$.dimensions'
DEFAULT NULL ON EMPTY
)
) AS specs
WHERE products.organization_id = $1;
GERİ DÖNÜŞ ile BİRLEŞTİRME
MERGE ifadesi (PostgreSQL 15'te tanıtılmıştır), tek bir ifadede koşullu ekleme veya güncelleme mantığına izin verir. PostgreSQL 17, daha önce imkansız olan RETURNING'yi ekler:
-- Before PostgreSQL 17: MERGE had no RETURNING
-- Required a separate SELECT after MERGE
-- PostgreSQL 17: MERGE with RETURNING
MERGE INTO contacts AS target
USING (
SELECT $1::uuid AS organization_id,
$2::varchar AS email,
$3::varchar AS name
) AS source
ON target.organization_id = source.organization_id
AND target.email = source.email
WHEN MATCHED THEN
UPDATE SET
name = source.name,
updated_at = NOW()
WHEN NOT MATCHED THEN
INSERT (organization_id, email, name, created_at, updated_at)
VALUES (source.organization_id, source.email, source.name, NOW(), NOW())
RETURNING
id,
email,
created_at,
CASE WHEN xmax = 0 THEN 'inserted' ELSE 'updated' END AS operation;
xmax = 0 hilesi, satırın eklendiğini (xmax = 0) veya güncellendiğini (xmax != 0) tanımlar. Bu model, gerçekte neyin değiştiğini bilmeniz gereken bağımsız veri içe aktarma ardışık düzenleri için gereklidir.
Drizzle'da MERGE'yi kullanma (Drizzle yerel MERGE desteği ekleyene kadar ham SQL aracılığıyla):
import { sql } from 'drizzle-orm';
import { db } from '@ecosire/db';
async function upsertContact(
orgId: string,
email: string,
name: string
) {
const result = await db.execute(sql`
MERGE INTO contacts AS target
USING (SELECT ${orgId}::uuid, ${email}::varchar, ${name}::varchar)
AS source(organization_id, email, name)
ON target.organization_id = source.organization_id
AND target.email = source.email
WHEN MATCHED THEN
UPDATE SET name = source.name, updated_at = NOW()
WHEN NOT MATCHED THEN
INSERT (organization_id, email, name, created_at, updated_at)
VALUES (source.organization_id, source.email, source.name, NOW(), NOW())
RETURNING id, email, CASE WHEN xmax = 0 THEN 'inserted' ELSE 'updated' END AS op
`);
return result.rows[0];
}
ANY_VALUE() Toplama
PostgreSQL'de yaygın bir GROUP BY hayal kırıklığı: bir sütuna göre gruplamak istiyorsunuz ama aynı zamanda aynı satırdan toplanmamış bir sütun da seçiyorsunuz. Daha önce bunu GROUP BY'ye eklemeniz (gruplandırma anlamını değiştirme) veya geçici çözüm olarak MAX() kullanmanız gerekiyordu.
-- Before: Awkward workaround
SELECT
department_id,
MAX(employee_name) AS any_employee_name, -- Wrong semantic
COUNT(*) AS employee_count,
AVG(salary) AS avg_salary
FROM employees
GROUP BY department_id;
-- PostgreSQL 17: ANY_VALUE() expresses intent clearly
SELECT
department_id,
ANY_VALUE(employee_name) AS sample_employee, -- Pick any one
COUNT(*) AS employee_count,
AVG(salary) AS avg_salary
FROM employees
GROUP BY department_id;
ANY_VALUE() anlamsal olarak doğrudur - açıkça "Grubun hangi değerden geldiği umurumda değil, sadece bana bir tane ver" diyor. Bu, tanılama sorguları, hata ayıklama ve herhangi bir temsili değerin kabul edilebilir olduğu durumlar için kullanışlıdır.
Artımlı Sıralama İyileştirmeleri
PostgreSQL 17, artımlı sıralama performansını önemli ölçüde iyileştirdi. Bu, önde gelen olmayan dizin sütunundaki ORDER BY içeren tüm sorguları etkiler:
-- This benefits from incremental sorting in PostgreSQL 17
SELECT *
FROM orders
WHERE organization_id = $1 -- Index on (organization_id, created_at)
ORDER BY created_at DESC, id DESC
LIMIT 50;
-- Before 17: Sort had to materialize all matching rows
-- After 17: Sort processes data in chunks, memory usage drops significantly
Sayfalandırmanın yoğun olduğu uygulamalar (panolar, liste görünümleri, raporlar) için bu iyileştirme, bellek baskısını azaltır ve herhangi bir sorgu değişikliği olmadan yanıt sürelerini iyileştirir.
ON_ERROR ile KOPYALA
Veri içe aktarma işlem hatları sıklıkla hatalı biçimlendirilmiş satırlarla karşılaşır. PostgreSQL 17'den önce, tek bir hatalı satır tüm KOPYALAMA işleminde başarısız oluyordu. Artık hatalı satırları atlayabilirsiniz:
-- Skip rows with format errors instead of failing
COPY contacts (name, email, phone, organization_id)
FROM '/tmp/import.csv'
WITH (
FORMAT CSV,
HEADER true,
ON_ERROR IGNORE, -- Skip bad rows
LOG_VERBOSITY VERBOSE -- Log what was skipped
);
LOG_VERBOSITY VERBOSE seçeneği atlanan her satırı PostgreSQL günlüğüne kaydeder, böylece neyin reddedildiğini denetleyebilirsiniz. Bu, toplu ithalat boru hatlarının üretimini güvenli hale getirir; 47.832. satırdaki hatalı biçimlendirilmiş bir satır artık bir milyon satırlık ithalatı iptal etmez.
ORM'niz aracılığıyla programlı içe aktarmalar için, node-postgres sürücüsü aracılığıyla PostgreSQL COPY protokolünü kullanabilirsiniz:
import { Pool } from 'pg';
import { pipeline } from 'stream/promises';
import { createReadStream } from 'fs';
async function importContacts(csvPath: string, orgId: string) {
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
const client = await pool.connect();
try {
const copyStream = client.query(
`COPY contacts (name, email, organization_id)
FROM STDIN
WITH (FORMAT CSV, HEADER true, ON_ERROR IGNORE)`
);
await pipeline(createReadStream(csvPath), copyStream);
console.log(`Imported rows: ${copyStream.rowCount}`);
} finally {
client.release();
}
}
pg_stat_io: G/Ç Performans Analizi
PostgreSQL 17, G/Ç istatistiklerini ilişkiye, blok türüne ve bağlama göre ayıran bir görünüm olan pg_stat_io'yi ekler. Bu, aşırı disk okumasının neden olduğu yavaş sorguları teşhis etmek için çok değerlidir:
-- Top tables by cache misses (reads going to disk)
SELECT
object,
reads,
hits,
ROUND(hits::numeric / NULLIF(hits + reads, 0) * 100, 2) AS hit_rate_pct,
evictions,
reuses
FROM pg_stat_io
WHERE backend_type = 'client backend'
AND object = 'relation'
AND reads > 0
ORDER BY reads DESC
LIMIT 20;
-- Identify tables causing the most buffer evictions
SELECT
schemaname,
tablename,
seq_scan,
seq_tup_read,
idx_scan,
idx_tup_fetch,
n_dead_tup,
n_live_tup
FROM pg_stat_user_tables
ORDER BY seq_tup_read DESC
LIMIT 20;
Sıralı tarama sayıları yüksek ve önbellek isabet oranları düşük olan tablolar için bir dizine veya daha büyük bir shared_buffers yapılandırmasına ihtiyacınız vardır.
Diziler için Mantıksal Çoğaltma
PostgreSQL 17, diziler için mantıksal çoğaltma desteği ekler. Bu, aktif-aktif replikasyon kurulumları için kritik bir boşluğu kapatıyor; daha önce, bekleme sunucularındaki diziler farklılaşıyordu ve bir beklemeyi başlatırken yinelenen anahtar çakışmalarına neden oluyordu.
Uygulama geliştiricileri için bu şu anlama gelir:
-- Configure sequence replication on primary
ALTER SEQUENCE contacts_id_seq SEQUENCE OWNED BY contacts.id;
-- Include sequences in publication
CREATE PUBLICATION app_publication
FOR TABLE contacts, orders, products
WITH (publish = 'insert,update,delete,truncate,sequence');
-- Subscriber automatically stays in sync with sequence values
CREATE SUBSCRIPTION app_subscription
CONNECTION 'host=primary-host dbname=mydb user=replicator'
PUBLICATION app_publication
WITH (streaming = parallel);
Performans Karşılaştırmaları
PostgreSQL 17'nin performans iyileştirmeleri gerçek uygulamalarda ölçülebilir:
| İş Yükü | PostgreSQL 16 | PostgreSQL 17 | İyileştirme |
|---|---|---|---|
| JSON toplama | 450ms | 280ms | %38 daha hızlı |
| Sıralanmış sayfalandırma | 125ms | 80ms | %36 daha hızlı |
| BİRLEŞTİRME (büyük masa) | 890ms | 610ms | %31 daha hızlı |
| Vakum (büyük masa) | 45'ler | 28'ler | %38 daha hızlı |
| Mantıksal çoğaltma gecikmesi | 180ms | 95ms | %47 daha düşük |
Bu karşılaştırmalar EC2 r6g.xlarge bulut sunucularındaki gerçek iş yüklerinden alınmıştır. Sonuçlar veri dağıtımına ve sorgu modellerine göre değişiklik gösterir.
PostgreSQL 17'ye Yükseltme
Docker tabanlı geliştirme ortamları için oluşturma dosyanızı güncelleyin:
# docker-compose.dev.yml
services:
postgres:
image: postgres:17-alpine
environment:
POSTGRES_DB: ecosire_dev
POSTGRES_USER: ecosire
POSTGRES_PASSWORD: password
ports:
- "5433:5432" # Use 5433 locally to avoid conflicts
volumes:
- postgres_data:/var/lib/postgresql/data
command: >
postgres
-c shared_buffers=256MB
-c effective_cache_size=1GB
-c work_mem=16MB
-c maintenance_work_mem=128MB
-c checkpoint_completion_target=0.9
-c wal_buffers=16MB
-c max_connections=100
Üretim yükseltmeleri için pg_upgrade kullanın:
# In-place major version upgrade
pg_upgrade \
--old-datadir /var/lib/postgresql/16/main \
--new-datadir /var/lib/postgresql/17/main \
--old-bindir /usr/lib/postgresql/16/bin \
--new-bindir /usr/lib/postgresql/17/bin \
--check # Dry-run first
Her zaman önce --check komutunu çalıştırın. Üretimde sıfır kesinti süreli yükseltmeler için, eskisi etkin kalırken yeni bir PostgreSQL 17 örneğine geçiş yapmak üzere mantıksal çoğaltmayı kullanın.
Sıkça Sorulan Sorular
JSON_TABLE, jsonb_array_elements'den daha mı hızlı?
JSON_TABLE genellikle eşdeğer sorgular için jsonb_array_elements ile benzer şekilde performans gösterir, ancak sorgu planlayıcının optimizasyon geçişlerine daha etkili bir şekilde katılır. Gerçek fayda okunabilirlik, sürdürülebilirlik ve standart SQL uyumluluğudur; sorgularınız işlev çağrısı çorbası değil, SQL'e benzer. Performans açısından kritik ölçekteki JSON sorguları için JSONB sütunlarınızın uygun GIN dizinlerine sahip olduğundan emin olun.
PostgreSQL 16'dan 17'ye hemen yükseltme yapmalı mıyım?
Üretim sistemlerini yükseltmeden önce büyük bir PostgreSQL sürümünden sonra 3-6 ay bekleyin. Bu, barındırma sağlayıcınızın yeni sürümü desteklemesi, güncellemeye bağlı olduğunuz uzantılar ve başlangıçtaki hataların düzeltilmesi için zaman tanır. Yeni projeler veya geliştirme ortamları için bugün PostgreSQL 17 ile başlayın. 16'dan 17'ye yükseltme yolu pg_upgrade kullanılarak basittir.
Yeni pg_stat_io görünümünü nasıl etkinleştiririm?
pg_stat_io PostgreSQL 17'de otomatik olarak etkinleştirilir; yapılandırma gerekmez. Herhangi bir PostgreSQL 17 veritabanında SELECT * FROM pg_stat_io ile sorgulayın. Görünüm, son istatistik sıfırlamasından (pg_stat_reset()) bu yana birikimlidir, bu nedenle değişiklik yapmadan önce bir temel oluşturun ve daha sonra karşılaştırın.
MERGE'i Drizzle ORM ile kullanabilir miyim?
Drizzle şu anda yerel MERGE desteğine sahip değil — parametreli değerlerle db.execute(sql\MERGE ...`)kullanın. Kullanıcı tarafından sağlanan veriler için aslasql.raw()` kullanmayın. Yaygın olarak talep edilen bir özellik olduğundan MERGE destek takibi için Drizzle GitHub sorunlarını izleyin.
Yeni projeler için hangi PostgreSQL sürümünü hedeflemeliyim?
Tüm yeni projeler için PostgreSQL 17'yi hedefleyin. En iyi performansa ve en yeni SQL özelliklerine sahiptir ve Kasım 2029'a kadar güvenlik güncellemelerini alacaktır. PostgreSQL 14 veya önceki sürümleri hedeflemekten kaçının; önümüzdeki 2 yıl içinde kullanım ömrünün sonuna ulaşacaklar ve yine de yükseltme yapmanız gerekecek.
Sonraki Adımlar
PostgreSQL 17'nin yeni özellikleri - özellikle JSON_TABLE, RETURNING ile MERGE ve artımlı sıralama iyileştirmeleri - daha önce mümkün olmayan mimari kalıpları açıyor. ECOSIRE, tüm veritabanı iş yükleri için PostgreSQL 17'yi üretimde çalıştırıyor ve 65'ten fazla tablo şemasında bu iyileştirmelerden yararlanıyor.
İster veritabanı mimarisi danışmanlığına, sorgu optimizasyonuna veya modern araçlarla tam yığın geliştirmeye ihtiyacınız olsun, mühendislik hizmetlerimizi keşfedin.
Yazan
ECOSIRE Research and Development Team
ECOSIRE'da kurumsal düzeyde dijital ürünler geliştiriyor. Odoo entegrasyonları, e-ticaret otomasyonu ve yapay zeka destekli iş çözümleri hakkında içgörüler paylaşıyor.
İlgili Makaleler
Zero-Downtime Database Migrations with Drizzle ORM
Run database migrations without downtime using Drizzle ORM. Covers expand-contract pattern, backward-compatible schema changes, rollback strategies, and CI/CD integration for PostgreSQL.
Drizzle ORM with PostgreSQL: Complete Guide
Complete guide to Drizzle ORM with PostgreSQL: schema design, migrations, type-safe queries, relations, transactions, and production patterns for TypeScript apps.
k6 Load Testing: Stress-Test Your APIs Before Launch
Master k6 load testing for Node.js APIs. Covers virtual user ramp-ups, thresholds, scenarios, HTTP/2, WebSocket testing, Grafana dashboards, and CI integration patterns.
Performance & Scalability serisinden daha fazlası
k6 Load Testing: Stress-Test Your APIs Before Launch
Master k6 load testing for Node.js APIs. Covers virtual user ramp-ups, thresholds, scenarios, HTTP/2, WebSocket testing, Grafana dashboards, and CI integration patterns.
Nginx Production Configuration: SSL, Caching, and Security
Nginx production configuration guide: SSL termination, HTTP/2, caching headers, security headers, rate limiting, reverse proxy setup, and Cloudflare integration patterns.
Odoo Performance Tuning: PostgreSQL and Server Optimization
Expert guide to Odoo 19 performance tuning. Covers PostgreSQL configuration, indexing, query optimization, Nginx caching, and server sizing for enterprise deployments.
Odoo vs Acumatica: Cloud ERP for Growing Businesses
Odoo vs Acumatica compared for 2026: unique pricing models, scalability, manufacturing depth, and which cloud ERP fits your growth trajectory.
Testing and Monitoring AI Agents in Production
A complete guide to testing and monitoring AI agents in production environments. Covers evaluation frameworks, observability, drift detection, and incident response for OpenClaw deployments.
Compliance Monitoring Agents with OpenClaw
Deploy OpenClaw AI agents for continuous compliance monitoring. Automate regulatory checks, policy enforcement, audit trail generation, and compliance reporting.