2026-04-09 在資料表 是大表join 比較快 還是小表 join 比較快?

2026-04-09 在資料表 是大表join 比較快 還是小表 join 比較快?

在資料表 是大表join 比較快 還是小表 join 比較快?

下面給你 最精準、最實務、DBA 也會點頭的 SQL 高性能五大原則,特別是用在 Oracle 最有感。


🚀 寫 SQL 保證快的五大原則(Oracle 實務版)


1. Join 與 Where 條件一定要用「可走索引」的欄位

✓ 正確:

1
2
ON A.ID = B.ID
WHERE A.STATUS = 'ACTIVE'

✗ 錯誤(會破壞索引):

1
2
ON TO_CHAR(A.ID) = B.ID
WHERE UPPER(A.NAME) = 'JOHN'

理由:
只要你在欄位上做 function / 計算 → Oracle 不能用索引 → 直接變慢。

解法:改成 function-free:

1
WHERE A.NAME = 'john'

(或使用 function-based index)


2. 先把資料量縮小,再 JOIN(非常關鍵)

❌ 壞範例(join 全表後才 WHERE):

1
2
3
4
SELECT *
FROM A
JOIN B ON A.ID = B.ID
WHERE A.STATUS = 'ACTIVE';

Oracle 有時不會先 filter。

✔ 好範例(先縮小 A,再 join):

1
2
3
4
5
6
WITH A1 AS (
SELECT * FROM A WHERE STATUS = 'ACTIVE'
)
SELECT *
FROM A1
JOIN B ON A1.ID = B.ID;

理由:
將 1000 萬筆先變成 10 萬筆,再 join → 速度差 50 倍以上。


*3. 避免 SELECT ,只取需要的欄位

❌ 壞習慣:

1
SELECT *

✔ 好習慣:

1
SELECT id, name, price

理由:

  • 減少 I/O
  • 減少 CPU
  • 減少 network 傳輸
  • 減少排序和 hash join 所需的 memory

對大型 SQL 效能提升巨大。


4. 用 EXISTS / IN / JOIN 的最佳使用原則

Oracle 的性能排序一般是:

小集合 → 用 IN(list)

1
WHERE ID IN (1,2,3)

大集合 → 用 JOIN 或 EXISTS

1
2
3
WHERE EXISTS (
SELECT 1 FROM B WHERE B.ID = A.ID
)

NOT IN 極慢 → 用 NOT EXISTS 取代

1
2
3
4
5
-- 慢
WHERE A.ID NOT IN (SELECT ID FROM B)

-- 快
WHERE NOT EXISTS (SELECT 1 FROM B WHERE B.ID = A.ID)

5. ORDER BY + 大量資料 = 效能殺手(能避免就避免)

排序是業界噩夢之一(尤其沒有索引時)。

❌ 壞範例(無索引排序):

1
SELECT * FROM A ORDER BY CREATE_DATE;

會產生大量 TEMP I/O(非常慢)。

✔ 解法 1:建索引

1
CREATE INDEX IDX_A_CREATEDATE ON A(CREATE_DATE);

✔ 解法 2:只排序小集合

1
2
3
4
WITH A1 AS (
SELECT * FROM A WHERE STATUS = 'ACTIVE'
)
SELECT * FROM A1 ORDER BY CREATE_DATE;

🎯 Bonus(額外兩個超重要小技巧)


6. 要 JOIN 的欄位,兩邊資料型態要一樣

❌ 如果 A.ID 是 number,B.ID 是 varchar
Oracle 會自動轉型 → 索引失效 → 超慢。

✔ 修法:

  • 修改欄位
  • 或使用 function-based index

7. 大表統計表(statistics)要定期更新

Oracle optimizer 的預估錯誤 → SQL 會變慢。

1
EXEC DBMS_STATS.GATHER_TABLE_STATS('SCOTT','EMP');

📌 總結:SQL 想快,只要記住一句話:

“少掃資料(I/O)、可用索引、少排序 → SQL 就會快。”

你如果願意,我可以:

✔ 幫你做「SQL 優化清單模板」

✔ 幫你評估你現在的 SQL 寫法(你貼給我,我幫你改到最有效能版)

✔ 教你如何讀 Oracle Execution Plan(你一定會用到)

你要哪一個?