項目中SQL優化面試必考必用的一項技能,讀者也在學習
對查詢進行優化,要儘量避免全表掃描,首先應考慮在進行條件判斷的字段上創建索引
。
儘量避免在 where
子句中對字段進行 null 值
判斷,否則將導致引擎放棄使用索引而進行全表掃描。
1、避免 *
全表掃描
SELECT *
FROM SCOTT.emp
WHERE job IS NULL;
2、避免在 where 子句中使用 != 或 <>
操作符,否則將引擎放棄使用索引而進行全表掃描。
SELECT *
FROM SCOTT.emp
WHERE job <> 'SALESMAN';
3、避免在 where 子句中使用 or 來連接條件,如果一個字段有索引,一個字段沒有索引,將導致引擎放棄使用索引而進行全表掃描
,而是使用union all
實現
SELECT *
FROM SCOTT.emp
WHERE job = 'SALESMAN' OR sal>1000;
使用UNION ALL
來代替
SELECT *
FROM SCOTT.emp
WHERE job = 'SALESMAN' UNION ALL
SELECT *
FROM SCOTT.emp
WHERE sal>1000;
4、避免not in
,否則會導致全表掃描,使用 NOT EXISTS
實現
SELECT *
FROM SCOTT.emp
WHERE empno NOT IN(7788);
使用NOT EXISTS
代替
SELECT *
FROM SCOTT.emp e1
WHERE NOT EXISTS(
SELECT *
FROM SCOTT.emp
WHERE e1.empno=7788
);
5、模糊查詢避免使用“%”
也將導致全表掃描(MYSQL)
這種情況只有在mysql的時候會失效
SELECT *
FROM SCOTT.emp
WHERE job LIKE '%C%';
mysql索引失效解決
將用戶可能輸入的關鍵字使用下拉列表列出來,在數據庫中使用全名稱查詢
SELECT * FROM emp WHERE job LIKE '關鍵字'
6、避免在 where 子句中對字段進行表達式計算操作
,這將導致引擎放棄使用索引而進行全表掃描
SELECT *
FROM SCOTT.emp
WHERE sal/2=1000;
解決方法
SELECT *
FROM SCOTT.emp
WHERE sal=2*1000;
7、使用索引字段作爲條件時,如果該索引是複合索引。那麼必須使用到該索引中的第一個字段
作爲條件時才能保證系統使用該索引(最左原則),否則該索引將不會被使用,並且應儘可能的讓字段順序與索引順序
相一致。所謂的複合索引就是創建一個索引的時候作用在多個字段上。
- 查詢(不使用第一個字段)使用的是全表掃面模式。
SELECT *
FROM SCOTT.emp
WHERE sal>1000;
- 查詢(使用第一個字段,字段順序與索引順序一致)
SELECT *
FROM SCOTT.emp
WHERE job='SALEMAN';
使用複合索引的時候如果要其中一個字段,必須使用第一個字段(在創建索引時候的字段順序)索引纔會生效,這叫做索引的最左原則。
8、避免使用OR
連接查詢會導致索引失效,使用UNION ALL
- 在OR連接中使用複合索引,索引失效
SELECT *
FROM SCOTT.emp
WHERE sal>1000 OR job='SALESMAN';
- 使用
UNION ALL
解決
SELECT *
FROM SCOTT.emp
WHERE sal>1000 UNION ALL
SELECT *
FROM SCOTT.Emp
WHERE
job='SALESMAN';
Update 語句,如果只更改1、2個字段,不要Update全部字段,否則頻繁調用會引起明顯的性能消耗,同時帶來大量日誌。
對於多張大數據量(這裏幾百條就算大了)的表JOIN,可以考慮使用程序去實現,不要做連接查詢,就是儘量避開多表查詢。
索引並不是越多越好,索引固然可以提高相應的 select 的效率,但同時也降低了 insert 及 update 的效率,因爲 insert 或 update 時有可能會重建索引,所以怎樣建索引需要慎重考慮,視具體情況而定。
儘量使用數字型字段,若只含數值信息的字段儘量不要設計爲字符型,這會降低查詢和連接的性能,並會增加存儲開銷。這是因爲引擎在處理查詢和連接時會逐個比較字符串中每一個字符,而對於數字型而言只需要比較一次就夠了。
任何地方都不要使用 select * from t ,用具體的字段列表代替“*”,不要返回用不到的任何字段。
SQLPLUS工具分析
一般按縮進長度來判斷,縮進最大的最先執行
,如果有2行縮進一樣,那麼就先執行上面的
ID: 一個序號,但不是執行的先後順序。執行的先後根據
縮進
來判斷。
Operation: 當前操作的內容。
Rows: 當前操作的Cardinality,Oracle估計當前操作的返回結果集。
Cost(CPU):Oracle 計算出來的一個數值(代價),用於說明SQL執行的代價。
Time:Oracle 估計當前操作的時間。