DEV Community

Cover image for Stop Query Lemot! Cara Cepat Bikin JOIN Table Pakai Teknik Rahasia Ini
Insight 105
Insight 105

Posted on

Stop Query Lemot! Cara Cepat Bikin JOIN Table Pakai Teknik Rahasia Ini

Di dunia sistem produksi, database hampir selalu menjadi bottleneck. CPU masih santai, RAM masih longgar, tapi halaman dashboard muter-mutir seperti mikir keras soal hidup. Sering kali penyebabnya bukan spesifikasi server, melainkan struktur query yang kurang cerdas.

Salah satu kesalahan klasik yang sering terjadi adalah:
menggabungkan (JOIN) tabel mentah yang sangat besar secara langsung, lalu berharap SQL Server “mengurus sisanya”.

Spoiler: SQL Server bisa pintar, tapi bukan cenayang.

Di sinilah Common Table Expressions (CTE) berperan sebagai alat berpikir sebelum bekerja.


Masalah Umum: JOIN Tabel Besar Tanpa Penyaringan Awal

Bayangkan skenario realistis berikut:

  • Orders → 10 juta baris
  • OrderItems → 50 juta baris
  • Customers → 1 juta baris

Lalu muncul query seperti ini:

SELECT 
    c.CustomerName,
    o.OrderDate,
    SUM(oi.Quantity * oi.Price) AS TotalAmount
FROM Orders o
JOIN OrderItems oi ON oi.OrderId = o.Id
JOIN Customers c ON c.Id = o.CustomerId
WHERE o.OrderDate >= '2025-01-01'
  AND o.Status = 'COMPLETED'
GROUP BY c.CustomerName, o.OrderDate;
Enter fullscreen mode Exit fullscreen mode

Sekilas terlihat normal.
Masalahnya: JOIN terjadi dulu, baru WHERE menyaring (secara logis).

Walaupun optimizer SQL Server bisa melakukan predicate pushdown, dalam praktik—terutama pada query kompleks—engine tetap harus:

  • Membaca banyak halaman data
  • Mengelola memory grant besar
  • Melakukan hash atau merge join berat

Akibatnya:

  • IO tinggi
  • CPU spike
  • Execution time bisa detik bahkan puluhan detik

Prinsip Dasar: Saring Dulu, Gabung Belakangan

CTE memberi kita cara mengekspresikan niat ke SQL Server:

“Ini data yang benar-benar saya butuhkan. Sisanya jangan disentuh.”

CTE bukan sekadar gaya penulisan, tapi alat untuk mengendalikan alur kerja query.


Solusi: Optimasi dengan Common Table Expressions (CTE)

Mari kita refactor query tadi dengan pendekatan bertahap.

Langkah 1: Saring Orders Sejak Awal

WITH FilteredOrders AS (
    SELECT 
        Id,
        CustomerId,
        OrderDate
    FROM Orders
    WHERE OrderDate >= '2025-01-01'
      AND Status = 'COMPLETED'
)
SELECT 
    c.CustomerName,
    fo.OrderDate,
    SUM(oi.Quantity * oi.Price) AS TotalAmount
FROM FilteredOrders fo
JOIN OrderItems oi ON oi.OrderId = fo.Id
JOIN Customers c ON c.Id = fo.CustomerId
GROUP BY c.CustomerName, fo.OrderDate;
Enter fullscreen mode Exit fullscreen mode

Apa yang Berubah Secara Fundamental?

  • SQL Server tidak lagi memindai seluruh tabel Orders
  • Jumlah baris yang masuk ke JOIN turun drastis
  • Memory grant lebih kecil
  • Execution plan lebih sederhana

Dalam banyak kasus nyata, ini saja sudah memangkas waktu eksekusi dari detik ke ratusan milidetik.


Optimasi Lanjutan: CTE Bertingkat (Layered CTE)

Kita bisa melangkah lebih jauh dengan memecah logika bisnis menjadi tahap-tahap kecil.

WITH FilteredOrders AS (
    SELECT 
        Id,
        CustomerId,
        OrderDate
    FROM Orders
    WHERE OrderDate >= '2025-01-01'
      AND Status = 'COMPLETED'
),
OrderTotals AS (
    SELECT 
        fo.Id AS OrderId,
        fo.CustomerId,
        fo.OrderDate,
        SUM(oi.Quantity * oi.Price) AS TotalAmount
    FROM FilteredOrders fo
    JOIN OrderItems oi ON oi.OrderId = fo.Id
    GROUP BY fo.Id, fo.CustomerId, fo.OrderDate
)
SELECT 
    c.CustomerName,
    ot.OrderDate,
    ot.TotalAmount
FROM OrderTotals ot
JOIN Customers c ON c.Id = ot.CustomerId;
Enter fullscreen mode Exit fullscreen mode

Kenapa Ini Lebih Sehat?

  • Agregasi dilakukan sebelum join ke Customers
  • Baris hasil jauh lebih sedikit
  • JOIN terakhir jadi ringan dan cepat

Secara mental, query ini juga lebih mudah dibaca dan dirawat.
Debugger manusia senang, SQL Server pun ikut senang.


Catatan Penting Khusus SQL Server

Sedikit nuansa teknis yang sering disalahpahami:

  • CTE bukan temporary table
  • Secara default, CTE akan di-inline ke execution plan
  • Keuntungannya datang dari:

    • Penyaringan dini
    • Pengurangan baris
    • Struktur query yang membantu optimizer

Jika CTE dipakai berulang atau sangat kompleks, kadang:

  • #temp table + index sementara bisa lebih optimal Namun sebagai default strategi, CTE adalah senjata pertama yang sangat efektif.

Dampak Nyata di Produksi

Dalam sistem nyata (ERP, finance, academic system, e-commerce), pola ini sering menghasilkan:

  • Penurunan logical reads hingga >70%
  • Waktu eksekusi turun dari:

    • 3–5 detik → 50–200 ms
  • Tanpa:

    • Upgrade server
    • Tambah RAM
    • Scaling horizontal

Ini murni kemenangan logika query.


Penutup: Optimasi Itu Soal Cara Berpikir

CTE bukan sekadar fitur SQL.
Ia adalah cara memaksa diri kita untuk berpikir:

“Data mana yang benar-benar relevan?”

Ketika database hanya memproses data yang diperlukan,
hardware bernapas lega,
aplikasi terasa instan,
dan tim tidak perlu panik saat traffic naik.

Optimasi performa jarang soal trik rahasia.
Hampir selalu soal menghormati mesin dengan struktur query yang cerdas.

Di dunia produksi, itu bedanya sistem yang “jalan” dan sistem yang “tahan banting”.

kamu bisa menonton versi videonya di channel YouTube berikut:
👉 @insight105

Top comments (0)