Prepared statements dengan .prepare() untuk caching SQL di database server, reuse across requests untuk performa lebih baik, performance optimization termasuk index strategy dan connection pooling, serta profiling queries dengan toSQL() dan database query logging.

Setelah di episode 13 kita mempelajari Transactions & Batch — operasi atomic dan bulk operations — pada episode ini kita membahas prepared statements dan performance: bagaimana mengoptimalkan query yang berjalan berulang kali, caching SQL di database server, dan profiling untuk mengidentifikasi bottleneck.
Prepared statements adalah salah satu optimasi paling fundamental di database — SQL di-cache di server sehingga tidak perlu di-parse ulang setiap kali.
import { placeholder } from 'drizzle-orm'
const getUserById = db
.select()
.from(users)
.where(eq(users.id, placeholder('id')))
.prepare()
// Gunakan prepared statement
const user = await getUserById.execute({ id: 1 })
const anotherUser = await getUserById.execute({ id: 2 })SQL di-cache di database server — getUserById hanya di-parse sekali, lalu di-reuse dengan parameter berbeda.
| Manfaat | Penjelasan |
|---|---|
| SQL caching | SQL di-cache di server, tidak perlu parse ulang |
| Performance | Lebih cepat untuk queries yang sama berulang kali |
| Security | Parameterized, aman dari SQL injection |
| Reuse | Bisa digunakan berkali-kali dengan parameter berbeda |
import { index } from 'drizzle-orm/pg-core'
export const users = pgTable('users', {
// ... columns
}, (table) => ({
emailIdx: index('users_email_idx').on(table.email),
roleIdx: index('users_role_idx').on(table.role),
}))Index mempercepat query yang menggunakan WHERE, JOIN, dan ORDER BY pada kolom tertentu.
import { drizzle } from 'drizzle-orm/postgres-js'
import postgres from 'postgres'
const client = postgres(process.env.DATABASE_URL!, {
max: 20, // Maximum connections
idle_timeout: 20, // Close idle connections
})Connection pooling memastikan koneksi database di-reuse daripada dibuat baru setiap request.
const query = db.select().from(users).where(eq(users.age, 25))
console.log(query.toSQL())
// { sql: 'SELECT * FROM "users" WHERE "age" = $1', params: [25] }# postgresql.conf
log_statement = 'all'Log semua query yang dijalankan ke database — membantu untuk debugging dan performance analysis.
Tip
Gunakan prepared statements untuk hot path queries — endpoint API yang paling sering dipanggil. Index kolom yang sering di-gunakan di WHERE dan JOIN. Connection pooling wajib untuk production.
Pada episode 14 ini, kalian telah memahami Prepared Statements & Performance:
.prepare() caching SQL di database server.toSQL() dan database query logging.Di episode 15 selanjutnya kita akan mempelajari Raw SQL & Template Literals — executing raw SQL, SQL template literals yang aman dari SQL injection, serta kapan menggunakan raw SQL vs query builder. Sampai jumpa di episode 15!