ORDER BY 僅在嚴格條件下使用索引:列含於同一索引且順序一致、列定義 NOT NULL、WHERE 與 ORDER BY 不共用索引。
-- 低效:DEPT_TYPE 為 NULL 且無索引
SELECT DEPT_CODE FROM DEPT ORDER BY DEPT_TYPE;
-- 高效:利用索引範圍掃描
SELECT DEPT_CODE FROM DEPT WHERE DEPT_TYPE > 0;
EMPNO = '123' → Oracle 內部轉為 TO_NUMBER('123'),**索引未失效** (轉換發生在常量側)EMP_TYPE = 123 → 轉為 TO_NUMBER(EMP_TYPE)=123,**索引失效** (轉換發生在列側)原則:顯式轉換常量,保持列原樣:WHERE EMP_TYPE = TO_CHAR(123)。
| 寫法 | 原因 |
|---|---|
COL != 'val' | 索引只存「存在」,不存「不存在」 |
COL1 || COL2 = 'val' | 函數操作列 |
COL + 0 = 100 | 數學運算列 |
COL1 = COL2 | 同表索引列互比 → 全表掃描 |
COL IS NULL / IS NOT NULL | 單列索引不存 NULL;復合索引全 NULL 不存 |
DISTINCT、UNION、MINUS、INTERSECT、ORDER BY 觸發 SORT。DISTINCT 一次排序,其餘至少兩次。可重寫:
-- 低效
SELECT ... UNION SELECT ...
-- 高效 (業務允許重複時)
SELECT ... UNION ALL SELECT ...
-- 低效:全表聚合再過濾
SELECT JOB, AVG(SAL) FROM EMP GROUP BY JOB HAVING JOB IN ('PRESIDENT','MANAGER');
-- 高效:先過濾再聚合
SELECT JOB, AVG(SAL) FROM EMP WHERE JOB IN ('PRESIDENT','MANAGER') GROUP BY JOB;
+ 拼接 SQL,用 StringBuilder 或綁定變量NOT、不計算、不函數>= 替代 > (直接定位首行)OR 改 UNION / INALTER INDEX ... REBUILD 消除碎片