SQL調優不僅是加索引、改執行計劃,更是在業務邏輯層面通過改寫減少數據庫引擎的處理工作量。本文精選10個高頻實戰技巧,前5個聚焦於結果集構建與邏輯簡化。
員工基本信息表需生成「崗位 姓名 出生於 YYYY年MM月DD日」格式的顯示列,用於報表導出。
SELECT
job_title || ' ' || emp_name || ' 出生於 ' ||
TO_CHAR(birth_date, 'YYYY"年"MM"月"DD"日"') AS emp_profile
FROM emp_basic_info;
SELECT JSON_OBJECT(
'title' VALUE job_title,
'name' VALUE emp_name,
'birth' VALUE TO_CHAR(birth_date, 'YYYY-MM-DD')
) AS emp_json FROM emp_basic_info;
# Python示例 - 低效
rows = cursor.fetchall()
unique_depts = set()
for row in rows:
unique_depts.add((row.dept, row.job))
SELECT DISTINCT dept_name, job_title
FROM emp_basic_info
WHERE status = 'ACTIVE'; -- 關鍵:先過濾再去重,減少排序/哈希工作量
DISTINCT觸發HASH UNIQUE或SORT UNIQUE操作;CREATE INDEX idx_dept_job ON emp_basic_info(dept_name, job_title); 可實現INDEX FULL SCAN避免排序。「能在存儲層過濾的,絕不傳到服務層;能在索引層過濾的,絕不讀表塊。」
-- 低效:全表掃描後過濾
SELECT * FROM big_table WHERE UPPER(name) = 'ZHANG';
-- 高效:函數索引支撐
CREATE INDEX idx_big_name_upper ON big_table(UPPER(name));
SELECT * FROM big_table WHERE UPPER(name) = 'ZHANG'; -- INDEX RANGE SCAN
-- 更高效:業務協議約定存儲大寫,省去函數調用
SELECT * FROM big_table WHERE name = 'ZHANG';
-- 範圍分區表,查詢條件包含分區鍵
SELECT * FROM sales_part
WHERE sale_date >= DATE '2024-01-01'
AND sale_date < DATE '2024-02-01'; -- 僅掃描2024年1月分區
-- 低效:全表排序後取前N
SELECT * FROM (
SELECT * FROM huge_table ORDER BY create_time DESC
) WHERE ROWNUM <= 20;
CREATE INDEX idx_huge_create_time ON huge_table(create_time DESC);
SELECT * FROM huge_table
WHERE create_time IS NOT NULL -- 確保索引可用
ORDER BY create_time DESC
FETCH FIRST 20 ROWS ONLY; -- 12c語法,自動轉為FIRST ROWS(n)優化
SELECT * FROM (
SELECT dept_id, AVG(sal) avg_sal FROM (
SELECT * FROM emp WHERE hiredate > SYSDATE - 365
) GROUP BY dept_id
) WHERE avg_sal > 5000;
WITH recent_emp AS (
SELECT /*+ MATERIALIZE */ * FROM emp WHERE hiredate > SYSDATE - 365
),
dept_avg AS (
SELECT dept_id, AVG(sal) avg_sal FROM recent_emp GROUP BY dept_id
)
SELECT * FROM dept_avg WHERE avg_sal > 5000;
MATERIALIZE Hint:強制物化CTE結果到臨時段,避免重複計算(適用於多次引用);INLINE Hint:簡單CTE建議內聯,減臨時段開銷;| 技巧 | 適用場景 | 典型收益 | 風險提示 |
|---|---|---|---|
| || 連接符 | 報表顯示列構建 | 網傳↓30%、邏輯集中 | 超長字符串超過4000字節需CLOB |
| DISTINCT | 業務去重 | 排序/哈希工作量↓ | 大數據集慎用,考慮近似去重 |
| WHERE下推 | 所有查詢 | I/O↓90%+ | 隱式轉換導致索引失效 |
| 分頁優化 | 前端分頁 | 響應時間ms級 | 深分頁(OFFSET大)需游標/Keyset分頁 |
| CTE模塊化 | 複雜報表/ETL | 可維護性↑、重複計算↓ | 過度物化佔用TEMP空間 |
後五大技巧將聚焦:分析函數替代自連接、Bind Variable Peeking應對、Hint精準干預、統計信息管理策略、SQL Plan Baseline穩定計劃,敬請期待。