Q96Performance & Optimisasi☆☆☆☆Copy-pasteSafe to Run

Anti-Pattern: SELECT * Replacement

Dialect:bigquerypostgresqlsnowflakemysql
#anti-pattern#select-star#performance#best-practice

Kapan Pakai Query Ini

Pakai panduan ini setiap kali kamu tergiur menulis SELECT *. Terutama di BigQuery dan Snowflake (columnar database) di mana kamu bayar per kolom yang dibaca, bukan per baris. SELECT * juga bikin query rapuh terhadap perubahan schema (kolom baru ikut terbaca, kolom yang dihapus bikin error downstream), dan membuat optimizer susah mengoptimalkan query. Query ini juga menunjukkan cara menggunakan INFORMATION_SCHEMA untuk men-generate daftar kolom secara otomatis.

Yang Perlu Diganti

  • project.dataset.orders → nama tabel yang ingin kamu inspeksi kolom-kolomnya
  • Pilih kolom yang benar-benar kamu butuhkan dari hasil INFORMATION_SCHEMA di bawah

Query

-- STEP 1: Dapatkan daftar kolom untuk di-copy (jalankan sekali)
SELECT
  column_name,
  data_type,
  is_nullable
FROM `project.dataset`.INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'orders'
ORDER BY ordinal_position;

-- ──────────────────────────────────────────────────

-- STEP 2: Ganti SELECT * dengan kolom eksplisit
-- SEBELUM (jangan lakukan ini):
-- SELECT * FROM orders WHERE order_date >= '2024-01-01';

-- SESUDAH (lakukan ini):
SELECT
  order_id,
  user_id,
  order_date,
  status,
  total_amount,
  discount_amount,
  shipping_address
FROM orders
WHERE order_date >= '2024-01-01'
  AND status = 'delivered';

-- ──────────────────────────────────────────────────

-- STEP 3: Untuk BigQuery — cek estimasi bytes yang akan di-scan
-- (Jalankan di BigQuery Console dengan tombol "Dry Run")
-- BigQuery akan menampilkan berapa GB yang akan diproses
-- SELECT * bisa 10x lebih mahal dari SELECT kolom spesifik di tabel lebar

Contoh Output

Hasil STEP 1 (INFORMATION_SCHEMA):

column_namedata_typeis_nullable
order_idSTRINGNO
user_idSTRINGNO
order_dateDATENO
statusSTRINGYES
total_amountFLOAT64YES
discount_amountFLOAT64YES
shipping_addressSTRINGYES
internal_notesSTRINGYES
legacy_ref_codeSTRINGYES

Kolom internal_notes dan legacy_ref_code → tidak perlu di-SELECT kalau kamu hanya butuh laporan penjualan. Dengan SELECT eksplisit, BigQuery tidak akan membaca kedua kolom itu sama sekali.

Variasi

  • Pakai EXCEPT sebagai jalan tengah di BigQuery/Snowflake: SELECT * EXCEPT (internal_notes, legacy_ref_code) FROM orders. Lebih aman dari SELECT * tapi masih hindari untuk production query di tabel lebar
  • Buat view dengan kolom yang sudah dikurasi: CREATE OR REPLACE VIEW orders_v AS SELECT order_id, user_id, ... FROM orders. Downstream user bisa SELECT * dari view ini dengan aman
  • Untuk audit berapa kolom yang tidak pernah dipakai: cek INFORMATION_SCHEMA.COLUMN_FIELD_PATHS di BigQuery atau query log analytics

Variasi Dialect

PostgreSQL:

-- INFORMATION_SCHEMA tersedia, syntax sedikit berbeda:
SELECT column_name, data_type, is_nullable
FROM information_schema.columns
WHERE table_schema = 'public'
  AND table_name   = 'orders'
ORDER BY ordinal_position;

Snowflake:

-- Snowflake juga punya INFORMATION_SCHEMA per database:
SELECT column_name, data_type, is_nullable
FROM information_schema.columns
WHERE table_schema = 'PUBLIC'
  AND table_name   = 'ORDERS'
ORDER BY ordinal_position;

MySQL:

-- Sama, tapi pakai table_schema = nama_database:
SELECT column_name, data_type, is_nullable
FROM information_schema.columns
WHERE table_schema = 'your_database'
  AND table_name   = 'orders'
ORDER BY ordinal_position;
Anti-Pattern: SELECT * Replacement — Analyst SQL Vault | NgulikSQL