首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

Oracle 實戰經驗六則:HAVING、外部聯接、刪除重複、SET TRANSACTION、索引、重建

     編輯:Oracle 資料庫相關知識

技巧一:HAVING 子句正確用法

HAVING 作用於 GROUP BY 分組結果,條件中**只能引用**:常數、聚合函數、GROUP BY 中的欄位。不可引用未分組、未聚合的欄位。

技巧二:外部聯接 (+) 替代 NOT IN 大幅提速

原始慢速寫法:

SELECT a.empno FROM emp a
WHERE a.empno NOT IN (SELECT empno FROM emp1 WHERE job='SALE');

改寫為外部聯接(右聯接):

SELECT a.empno FROM emp a, emp1 b
WHERE a.empno = b.empno(+)
  AND b.empno IS NULL
  AND b.job = 'SALE';

b.empno IS NULL 過濾出無匹配的 emp 列。實測速度明顯提升。注意:NOT IN 遇 NULL 值會返回空結果集,外部聯接無此問題。

技巧三:刪除重複資料的 ROWID 法與大表對策

DELETE FROM table_name a
WHERE ROWID < (SELECT MAX(ROWID)
               FROM table_name b
               WHERE b.col1 = a.col1
                 AND b.col2 = a.col2
                 ...);

大表 (>50萬列) 效能極差**,需改用:

  • 建立臨時表存保留資料 → TRUNCATE 原表 → INSERT /*+ APPEND */ 回寫
  • 或 DBMS_REDEFINITION 線上重定義
  • 參考《電信計費中長途重複話單的技術處理》

技巧四:SET TRANSACTION 指定大回滾段避免 ORA-01555

SET TRANSACTION USE ROLLBACK SEGMENT roll_abc;
DELETE FROM table_name WHERE ...;
COMMIT;

大量刪除/更新交易常報 ORA-01555: snapshot too old,原因是隨機分配的回滾段太小。預先指定大型回滾段確保交易成功。COMMIT 後自動釋放指定。

技巧五:索引使用的 20% 黃金法則與碎片管理

  • 單條 SQL 存取**超過 20% 總列數**時,索引通常無助於效能,FTS 更優
  • 頻繁 DELETE 產生索引碎片(索引空間不重用),需定期 ALTER INDEX REBUILD
  • 條件允許時階段性 TRUNCATE TABLE 同時清除表與索引碎片

技巧六:資料庫重建兩步走避免視圖建立失敗

IMP 導入時視圖可能先於基表建立導致失敗。解法:

# 1. 只導結構,不導資料
imp jfcl/hfjf@ora1 file=expdata.dmp rows=N

# 2. 導結構+資料,忽略既有物件錯誤
imp jfcl/hfjf@ora1 file=expdata.dmp full=Y buffer=64000 commit=Y ignore=Y

第一步建立所有表/索引/視圖結構(視圖建立失敗無妨),第二步導入資料並 ignore=Y 跳過物件已存在錯誤,視圖隨基表就緒自動生效。

總結:六大實戰精華

#場景關鍵語法/原則避坑提醒
1分組過濾HAVING 只能用聚合/分組欄位別引用明細欄位
2反向查詢外部聯接 (+) + IS NULL 替代 NOT INNOT IN 怕 NULL 值
3去重ROWID 保留 MAX/MIN大表必須分批或 TRUNCATE+APPEND
4大交易SET TRANSACTION USE ROLLBACK SEGMENT指定大回滾段防 ORA-01555
5索引決策存取 >20% 列數別用索引頻繁 DELETE 必須 REBUILD 索引
6庫重建IMP 兩步走:rows=N → ignore=Y視圖依賴基表順序問題

這六則經驗來自生產環境無數次踩坑與優化,每一條都能在關鍵時刻節省數小時排查時間。內化為肌肉記憶,是資深 DBA 與開發者的分水嶺。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved