日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

SQL优化实用方法

發(fā)布時間:2025/3/15 数据库 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SQL优化实用方法 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

SQL優(yōu)化:避免索引失效

1、不使用NULL

任何在where子句中使用is null或is not null的語句優(yōu)化器是不允許使用索引的。因為只有該字段中有null值,即使創(chuàng)建了索引其實也
是沒有用的,所以創(chuàng)建索引應(yīng)該在有值的字段上創(chuàng)建;

2、like的使用

使用該sql語句將不會使用索引:select * from employee where last_name like ‘%cliton%';
這樣的話會使用索引:???? select * from employee where last_name like ‘cliton%';

3、對Order By排序的列使用索引,避免使用表達(dá)式

ORDER BY語句決定了Oracle如何將返回的查詢結(jié)果排序。Order by語句對要排序的列沒有什么特別的限制,也可以將函數(shù)加入列中(象聯(lián)接或者附加等)。任何在Order by語句的非索引項或者有計算表達(dá)式都將降低查詢速度。仔細(xì)檢查order by語句以找出非索引項或者表達(dá)式,它們
會降低性能。解決這個問題的辦法就是重寫order by語句以使用索引,也可以為所使用的列建立另外一個索引,同時應(yīng)絕對避免在order by
子句中使用表達(dá)式。

4、表記錄條數(shù)最小的寫在右邊

ORACLE 的解析器按照從右到左的順序處理FROM子句中的表名,FROM子句中寫在最后的表(基礎(chǔ)表 driving table)將被最先處理,在FROM子句
中包含多個表的情況下,你必須選擇記錄條數(shù)最少的表作為基礎(chǔ)表。如果有3個以上的表連接查詢, 那就需要選擇交叉表(intersection
table)作為基礎(chǔ)表, 交叉表是指那個被其他表所引用的表.

5、避免使用select ' * '

ORACLE在解析的過程中, 會將’*’ 依次轉(zhuǎn)換成所有的列名, 這個工作是通過查詢數(shù)據(jù)字典完成的, 這意味著將耗費(fèi)更多的時間

6、 減少訪問數(shù)據(jù)庫的次數(shù)

能使用一條sql語句查詢出來的最好使用一條語句直接查詢出來。? 整合簡單,無關(guān)聯(lián)的數(shù)據(jù)庫訪問: 如果你有幾個簡單的數(shù)據(jù)庫查詢語句,你可以把它們整合到一個查詢中(即使它們之間沒有關(guān)系)

9、 用EXISTS替代IN、用NOT EXISTS替代NOT IN

在許多基于基礎(chǔ)表的查詢中,為了滿足一個條件,往往需要對另一個表進(jìn)行聯(lián)接.在這種情況下, 使用EXISTS(或NOT EXISTS)通常將提高查詢的
效率. 在子查詢中,NOT IN子句將執(zhí)行一個內(nèi)部的排序和合并. 無論在哪種情況下,NOT IN都是最低效的 (因為它對子查詢中的表執(zhí)行了一個
全表遍歷). 為了避免使用NOT IN ,我們可以把它改寫成外連接(Outer Joins)或NOT EXISTS.
例:
?(低效)select * from z_shangbiao u where u.ann_nnum!='' and u.ann_nnum? in( select e.user_account FROM? t_evaluation e)
(高效)select * from t_user u where u.account!='' and EXISTS( select e.user_account FROM? t_evaluation e where
u.account=e.user_account)

10、 用索引提高效率

雖然使用索引能得到查詢效率的提高,但是我們也必須注意到它的代價. 索引需要空間來存儲,也需要定期維護(hù), 每
當(dāng)有記錄在表中增減或索引列被修改時, 索引本身也會被修改. 這意味著每條記錄的INSERT , DELETE , UPDATE將為此多付出4 , 5 次的磁
盤I/O . 因為索引需要額外的存儲空間和處理,那些不必要的索引反而會使查詢反應(yīng)時間變慢.。定期的重構(gòu)索引是有必要的.:

11、用EXISTS替換DISTINCT

當(dāng)提交一個包含一對多表信息(比如部門表和雇員表)的查詢時,避免在SELECT子句中使用DISTINCT. 一般可以考慮用EXIST替換, EXISTS 使查
詢更為迅速,因為RDBMS核心模塊將在子查詢的條件一旦滿足后,立刻返回結(jié)果. 例子:
(低效):
SELECT? DISTINCT? DEPT_NO,DEPT_NAME? FROM? DEPT D , EMP E WHERE? D.DEPT_NO = E.DEPT_NO
(高效):
SELECT? DEPT_NO,DEPT_NAME? FROM? DEPT D? WHERE? EXISTS ( SELECT ‘X’ FROM? EMP E? WHERE E.DEPT_NO = D.DEPT_NO);

12、sql語句用大寫的

因為oracle總是先解析sql語句,把小寫的字母轉(zhuǎn)換成大寫的再執(zhí)行

13、 避免在索引列上使用計算.

WHERE子句中,如果索引列是函數(shù)的一部分.優(yōu)化器將不使用索引而使用全表掃描.
舉例:
低效:
SELECT … FROM? DEPT? WHERE SAL * 12 > 25000;
高效:
SELECT … FROM DEPT WHERE SAL > 25000/12;

14、用>=替代>

高效:
SELECT * FROM? EMP? WHERE? DEPTNO >=4
低效:
SELECT * FROM EMP WHERE DEPTNO >3

15、 用UNION替換OR (適用于索引列)

通常情況下, 用UNION替換WHERE子句中的OR將會起到較好的效果. 對索引列使用OR將造成全表掃描. 注意, 以上規(guī)則只針對多個索引列有效.
如果有column沒有被索引, 查詢效率可能會因為你沒有選擇OR而降低. 在下面的例子中, LOC_ID 和REGION上都建有索引.
高效:
SELECT LOC_ID , LOC_DESC , REGION
FROM LOCATION
WHERE LOC_ID = 10
UNION
SELECT LOC_ID , LOC_DESC , REGION
FROM LOCATION
WHERE REGION = “MELBOURNE”
低效:
SELECT LOC_ID , LOC_DESC , REGION
FROM LOCATION
WHERE LOC_ID = 10 OR REGION = “MELBOURNE”
如果你堅持要用OR, 那就需要返回記錄最少的索引列寫在最前面.

16、 總是使用索引的第一個列

如果索引是建立在多個列上, 只有在它的第一個列(leading column)被where子句引用時,優(yōu)化器才會選擇使用該索引. 這也是一條簡單而重
要的規(guī)則,當(dāng)僅引用索引的第二個列時,優(yōu)化器使用了全表掃描而忽略了索引
例:比如你創(chuàng)建了索引(account,age,classno)三個字段為索引,那么你的sql語句使用where的時候應(yīng)該先使用account,此時才能使用索
引,如果你的where的第一個條件使用的是age或者classno那么將進(jìn)行全表搜索,而忽略了索引。

17、用UNION-ALL 替換UNION ( 如果有可能的話)

當(dāng)SQL 語句需要UNION兩個查詢結(jié)果集合時,這兩個結(jié)果集合會以UNION-ALL的方式被合并, 然后在輸出最終結(jié)果前進(jìn)行排序. 如果用UNION
ALL替代UNION, 這樣排序就不是必要了. 效率就會因此得到提高. 需要注意的是,UNION ALL 將重復(fù)輸出兩個結(jié)果集合中相同記錄. 因此各
位還是要從業(yè)務(wù)需求分析使用UNION ALL的可行性. UNION 將對結(jié)果集合排序,這個操作會使用到SORT_AREA_SIZE這塊內(nèi)存. 對于這塊內(nèi)存的
優(yōu)化也是相當(dāng)重要的. 下面的SQL可以用來查詢排序的消耗量
低效:
SELECT? ACCT_NUM, BALANCE_AMT
FROM? DEBIT_TRANSACTIONS
WHERE TRAN_DATE = ’31-DEC-95′
UNION
SELECT ACCT_NUM, BALANCE_AMT
FROM DEBIT_TRANSACTIONS
WHERE TRAN_DATE = ’31-DEC-95′
高效:
SELECT ACCT_NUM, BALANCE_AMT
FROM DEBIT_TRANSACTIONS
WHERE TRAN_DATE = ’31-DEC-95′
UNION ALL
SELECT ACCT_NUM, BALANCE_AMT
FROM DEBIT_TRANSACTIONS
WHERE TRAN_DATE = ’31-DEC-95′

18、避免改變索引列的類型

比如age字段為int型,然后你查詢的時候?qū)懙氖?where age='13',雖然查詢出來的結(jié)果是一樣的但是效率會降低,因為數(shù)據(jù)庫內(nèi)部多做了個
操作,自動對字符123 進(jìn)行TO_NUMBER(‘123′) 處理

19、 需要當(dāng)心的WHERE子句

某些SELECT 語句中的WHERE子句不使用索引. 這里有一些例子.
在下面的例子里, (1)‘!=’ 將不使用索引. 記住, 索引只能告訴你什么存在于表中, 而不能告訴你什么不存在于表中. (2) ‘||’是字符
連接函數(shù). 就象其他函數(shù)那樣, 停用了索引. (3) ‘+’是數(shù)學(xué)函數(shù). 就象其他數(shù)學(xué)函數(shù)那樣, 停用了索引. (4)相同的索引列不能互相比較,
這將會啟用全表掃描.

20、優(yōu)化GROUP BY,盡量使用where代替having

提高GROUP BY 語句的效率, 可以通過將不需要的記錄在GROUP BY 之前過濾掉.下面兩個查詢返回相同結(jié)果但第二個明顯就快了許多.
低效:
SELECT JOB , AVG(SAL)
FROM EMP
GROUP by JOB
HAVING JOB = ‘PRESIDENT’
OR JOB = ‘MANAGER’
高效:
SELECT JOB , AVG(SAL)
FROM EMP
WHERE JOB = ‘PRESIDENT’
OR JOB = ‘MANAGER’
GROUP by JOB
本文章閱讀參考:http://www.jfox.info/SQL-you-hua.html 結(jié)合自己工作中使用,選擇性的分享,如果不對,歡迎提出

轉(zhuǎn)載于:https://www.cnblogs.com/zhuziyu/p/8921309.html

總結(jié)

以上是生活随笔為你收集整理的SQL优化实用方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。