亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

oracle中sql語(yǔ)句的優(yōu)化(轉(zhuǎn)帖)

系統(tǒng) 1756 0

?

一、執(zhí)行順序及優(yōu)化細(xì)則

1.表名順序優(yōu)化
(1) 基礎(chǔ)表放下面,當(dāng)兩表進(jìn)行關(guān)聯(lián)時(shí)數(shù)據(jù)量少的表的表名放右邊
表或視圖:
Student_info?? (30000條數(shù)據(jù))
Description_info (30條數(shù)據(jù))?
select *
? from description_info di
????? ,student_info???? si --學(xué)生信息表
where si.student_id = di.lookup_code(+)
?? and di.lookup_type(+) = 'STUDENT_ID'?????
與???
select *
? from student_info???? si--學(xué)生信息表
????? ,description_info di
where si.student_id = di.lookup_code(+)
?? and di.lookup_type(+) = 'STUDENT_ID'??
以student_info作為基礎(chǔ)表,你會(huì)發(fā)現(xiàn)運(yùn)行的速度會(huì)有很大的差距。
??
??
(2) 當(dāng)出現(xiàn)多個(gè)表時(shí),關(guān)聯(lián)表被稱之為交叉表,交叉表作為基礎(chǔ)表
select *
? from description_info di
??? ,description_info di2
????? ,student_info???? si --學(xué)生信息表
where si.student_id = di.lookup_code(+)
?? and di.lookup_type(+) = 'STUDENT_ID'
?? and si.school_id = di.lookup_code(+)
?? and di.lookup_type(+) = 'SCHOOL_ID'

select *
? from student_info???? si--學(xué)生信息表
????? ,description_info di
????? ,description_info di2
where si.student_id = di.lookup_code(+)
?? and di.lookup_type(+) = 'STUDENT_ID'
?? and si.school_id = di.lookup_code(+)
?? and di.lookup_type(+) = 'SCHOOL_ID'
以student_info作為基礎(chǔ)表,你會(huì)發(fā)現(xiàn)運(yùn)行的速度會(huì)有很大的差距,
當(dāng)基礎(chǔ)表放在后面,這樣的執(zhí)行速度會(huì)明顯快很多。

2.where執(zhí)行順序
where執(zhí)行會(huì)從至下往上執(zhí)行
select *
from student_info si --學(xué)生信息表
where si.school_id=10 --學(xué)院ID
and? si.system_id=100--系ID
擺放where子句時(shí),把能過(guò)濾大量數(shù)據(jù)的條件放在最下邊

3. is null 和is not null
當(dāng)要過(guò)濾列為空數(shù)據(jù)或不為空的數(shù)據(jù)時(shí)使用
select *
from student_info si --學(xué)生信息表
where si.school_id is null(當(dāng)前列中的null為少數(shù)時(shí)用is not null,否則is null)

4.使用表別名
當(dāng)查詢時(shí)出現(xiàn)多個(gè)表時(shí),查詢時(shí)加上別名,
避免出現(xiàn)減少解析的時(shí)間字段歧義引起的語(yǔ)法錯(cuò)誤。

5. where執(zhí)行速度比having快
盡可能的使用where代替having
select? from student_info si
group by si.student_id
having si.system_id!=100
? and si.school_id!=10
(select? from student_info si
wehre si.system_id!=100
and si.school_id!=10
group by si.student_id)?
?
6.? * 號(hào)引起的執(zhí)行效率
盡量減少使用select * 來(lái)進(jìn)行查詢,當(dāng)你查詢使用*,
數(shù)據(jù)庫(kù)會(huì)進(jìn)行解析并將*轉(zhuǎn)換為全部列。


二、替代優(yōu)化
1、用>=替代>
select ui.user_name
? from user_info ui--員工信息表
? where ui.student_id>=10
? 與
? select ui.user_name
? from user_info ui--員工信息表
? where ui.student_id>9
? 執(zhí)行時(shí)>=會(huì)比>執(zhí)行得要快
?
2、用UNION替換OR (適用于索引列)
select ui.user_name
? from user_info ui--員工信息表
? where ui.student_id=10
? union
select ui.user_name
? from user_info ui--員工信息表
? where ui.student_id=2?
?? 上面語(yǔ)句可有效避免全表查詢
?? select ui.user_name
? from user_info ui--員工信息表
? where ui.student_id=10
? or ui.student_id=2
? 如果堅(jiān)持要用OR, 可以把返回記錄最少的索引列寫在最前面
???
3、用in 代替or
select ui.user_name
? from user_info ui--員工信息表
? where ui.student_id=10
? or ui.student_id=20
? or ui.student_id=30
? 改成
? select ui.user_name
? from user_info ui--員工信息表
? where ui.student_id in (10,20,30)
? 執(zhí)行會(huì)更有效率
???
4、 Union All 與Union
Union All重復(fù)輸出兩個(gè)結(jié)果集合中相同記錄
如果兩個(gè)并集中數(shù)據(jù)都不一樣.那么使用Union All 與Union是沒有區(qū)別的,
select ui.user_name
? from user_info ui--員工信息表
? where ui.student_id=10
? union All
select ui.user_name
? from user_info ui--員工信息表
? where ui.student_id=2?
? 與
? select ui.user_name
? from user_info ui--員工信息表
? where ui.student_id=10
? union
select ui.user_name
? from user_info ui--員工信息表
? where ui.student_id=2?
但Union All會(huì)比Union要執(zhí)行得快

5、分離表和索引
總是將你的表和索引建立在另外的表空間內(nèi)
決不要將這些對(duì)象存放到SYSTEM表空間里

三、一些優(yōu)化技巧


1、計(jì)算表的記錄數(shù)時(shí)

select count(si.student_id)
from Student_info si(student_id為索引)

select count(*) from Student_info si
執(zhí)行時(shí).上面的語(yǔ)句明顯會(huì)比下面沒有用索引統(tǒng)計(jì)的語(yǔ)句要快

2.使用函數(shù)提高SQL執(zhí)行速度

當(dāng)出現(xiàn)復(fù)雜的查詢sql語(yǔ)名,可以考慮使用函數(shù)來(lái)提高速度
查詢學(xué)生信息并查詢學(xué)生(李明)個(gè)人信息與的數(shù)學(xué)成績(jī)排名

select di.description student_name
????? ,(select res.order_num--排名
???????? from result res
??????? where res.student_id = di.student_id
??????? order by result_math) order_num
? from description_info di
????? ,student_info???? si --學(xué)生信息表
where si.student_id = di.lookup_code(+)
?? and di.lookup_type(+) = 'STUDENT_ID'
?? and di.description = '李明'
??
而且我們將上面order_num排名寫成一個(gè)fuction時(shí)
create or replace package body order_num_pkg is
function order_num(p_student_id number) return_number is
? v_return_number number;
begin
? select res.order_num --排名
??? into v_return_number
??? from result res
?? where res.student_id = di.student_id
?? order by result_math;
? return v_return_number;
exception
? when others then
??? null;
??? return null;
end;
end order_num_pkg;
執(zhí)行
select di.description student_name
????? ,order_num_pkg.order_num(di.student_id) order_num
? from description_info di
????? ,student_info???? si --學(xué)生信息表
where si.student_id = di.lookup_code(+)
?? and di.lookup_type(+) = 'STUDENT_ID'
?? and di.description = '李明'
執(zhí)行查詢時(shí)的速度也會(huì)有所提高????
?
3.減少訪問(wèn)數(shù)據(jù)庫(kù)的次數(shù)

執(zhí)行次數(shù)的減少(當(dāng)要查詢出student_id=100的學(xué)生和student_id=20的學(xué)生信息時(shí))
select address_id
from student_info si --學(xué)生信息表
where si.student_id=100

select address_id
from student_info si --學(xué)生信息表
where si.student_id=20
都進(jìn)行查詢.這樣的效率是很低的
而進(jìn)行
(
select si.address_id,si2.address_id
from student_info si --學(xué)生信息表
,student_info si2
where si.student_id=100
and si2.student_id=20

select decode(si.student_id,100,address_id)
?? ,decode(si.student_id,20,address_id)
from student_info si
)
執(zhí)行速度是提高了,但可讀性反而差了..
所以這種寫法個(gè)人并不太推薦

4、用Exists(Not Exists)代替In(Not In)

?? 在執(zhí)行當(dāng)中使用Exists或者Not Exists可以高效的進(jìn)行查詢

5、Exists取代Distinct取唯一值的

?? 取出關(guān)聯(lián)表部門對(duì)員工時(shí),這時(shí)取出員工部門時(shí),出現(xiàn)多條..
select distinct di.dept_name
? from departments_info di --部門表
????? ,user_info??????? ui --員工信息表
where ui.dept_no = di.dept_no
?? 可以修改成
? select di.dept_name
??? from departments_info di --部門表
?? where? exists (select 'X'
??????????? from user_info ui --員工信息表
?????????? where di.dept_no = ui.dept_no)
6、用表連接代替Exists
?? 通過(guò)表的關(guān)聯(lián)來(lái)代替exists會(huì)使執(zhí)行更有效率
select ui.user_name
? from user_info ui--員工信息表
where exists (select 'x '
????????? from departments_info di--部門表
???????? where di.dept_no = ui.dept_no
?????????? and ui.dept_cat = 'IT');
執(zhí)行是比較快,但還可以使用表的連接取得更快的查詢效率
?? select ui.user_name
??? from departments_info di
??????? ,user_info??????? ui --員工信息表
?? where ui.dept_no = di.dept_no
???? and ui.department_type_code = 'IT'

代碼是經(jīng)測(cè)試并進(jìn)行優(yōu)化所寫,
以上只例子,具體使用還是要針對(duì)各個(gè)不同的具體的業(yè)務(wù)使用用Exists(Not Exists)代替In(Not In)

四、索引篇

1、運(yùn)算導(dǎo)致的索引失效

select di.description student_name
????? ,(select res.order_num--排名
???????? from result res
??????? where res.student_id = di.student_id
??????? order by result_math) order_num
? from description_info di
????? ,student_info???? si --學(xué)生信息表
where si.student_id = di.lookup_code(+)
?? and di.lookup_type(+) = 'STUDENT_ID'
?? and si.student_id+0=100/*student_id索引將失效*/
??
2、類型轉(zhuǎn)換導(dǎo)致的索引失效

select di.description student_name
????? ,(select res.order_num--排名
???????? from result res
??????? where res.student_id = di.student_id
??????? order by result_math) order_num
? from description_info di
????? ,student_info???? si --學(xué)生信息表
where si.student_id = di.lookup_code(+)
?? and di.lookup_type(+) = 'STUDENT_ID'
?? and di.student_id='100'
?
student_id為number類型的索引,當(dāng)執(zhí)行下列語(yǔ)句,
oracle會(huì)自動(dòng)轉(zhuǎn)換成
select di.description student_name
????? ,(select res.order_num--排名
???????? from result res
??????? where res.student_id = di.student_id
??????? order by result_math) order_num
? from description_info di
????? ,student_info???? si --學(xué)生信息表
where si.student_id = di.lookup_code(+)
?? and di.lookup_type(+) = 'STUDENT_ID'
?? and di.student_id=to_number('100')
所幸,只是解析并轉(zhuǎn)換類型,并沒有導(dǎo)到失效,
但要是寫成下面,將會(huì)使用其失效
select di.description student_name
????? ,(select res.order_num--排名
???????? from result res
??????? where res.student_id = di.student_id
??????? order by result_math) order_num
? from description_info di
????? ,student_info???? si --學(xué)生信息表
where si.student_id = di.lookup_code(+)
?? and di.lookup_type(+) = 'STUDENT_ID'
?? and to_char(di.student_id)='100'
??
3、在索引列上進(jìn)行計(jì)算引起的問(wèn)題

select di.description student_name
????? ,(select res.order_num--排名
???????? from result res
??????? where res.student_id = di.student_id
??????? order by result_math) order_num
? from description_info di
????? ,student_info???? si --學(xué)生信息表
where si.student_id = di.lookup_code(+)
?? and di.lookup_type(+) = 'STUDENT_ID'
?? and di.student_id-2=10
在索引列中進(jìn)行運(yùn)算,將會(huì)不使用索引而使用全表掃描
而將
select di.description student_name
????? ,(select res.order_num--排名
???????? from result res
??????? where res.student_id = di.student_id
??????? order by result_math) order_num
? from description_info di
????? ,student_info???? si --學(xué)生信息表
where si.student_id = di.lookup_code(+)
?? and di.lookup_type(+) = 'STUDENT_ID'
?? and di.student_id=10+2
將會(huì)得到高效的運(yùn)行速度

4、 Is not null引起的問(wèn)題(student_id為索引)

不要把存在空值的列做為索引,否則無(wú)法使用索引
select ui.user_name
? from user_info ui--員工信息表
? where ui.student_id is not null--索引失效
?
select ui.user_name
? from user_info ui--員工信息表
? where ui.student_id>=-1--索引有效

5、Order by導(dǎo)致索引失效(student_id為索引)

select ui.user_name
? from user_info ui--員工信息表
? group by ui.student_id??
而使用
select ui.user_name
? from user_info ui--員工信息表
? where ui.student_id>=-1
? 將使其有效,
? 在order by中只存在兩種條件下可以使用索引
? (ORDER BY中所有的列必須包含在相同的索引中并保持在索引中的排列順序
ORDER BY中所有的列必須定義為非空. )
?
6、自動(dòng)選擇索引
?
如果表中有兩個(gè)以上(包括兩個(gè))索引,其中有一個(gè)唯一性索引,而其他是非唯一性.
在這種情況下,ORACLE將使用唯一性索引而完全忽略非唯一性索引.

7、 !=導(dǎo)致索引失效
?
select ui.user_name
? from user_info ui--員工信息表
? where ui.student_id!=0
在Where中使用!=將會(huì)把索引失效

8、%導(dǎo)致的索引失效

select di.description student_name
????? ,(select res.order_num--排名
???????? from result res
??????? where res.student_id = di.student_id
??????? order by result_math) order_num
? from description_info di
????? ,student_info???? si --學(xué)生信息表
where si.student_id = di.lookup_code(+)
?? and di.lookup_type(+) = 'STUDENT_ID'
?? and di.look_code Like '%12'/*look_code為索引,索引將失效*/

select di.description student_name
????? ,(select res.order_num--排名
???????? from result res
??????? where res.student_id = di.student_id
??????? order by result_math) order_num
? from description_info di
????? ,student_info???? si --學(xué)生信息表
where si.student_id = di.lookup_code(+)
?? and di.lookup_type(+) = 'STUDENT_ID'
?? and di.look_code Like '12%'/*索引有效*/
以上只例子,具體還是要針對(duì)各個(gè)不同的具體的業(yè)務(wù)使用

五、oracle 中的not Exists與Not in的性能巨大差異

Not Exists與Not in的作用同樣是排除數(shù)據(jù),在oracle 中使用not in并不象mysql中的執(zhí)行那么快,如(
select jt1.doc_num --單據(jù)號(hào)碼
????? ,oalc.description school_name --學(xué)校名稱
????? ,oalc2.description system_name --系名稱
????? ,oalc.description class_name --班級(jí)名稱
? from java_table1??????????? jt1
????? ,java_table_description oalc
????? ,java_table_description oalc2
????? ,java_table_description oalc3
where oalc.lookup_type(+) = 'JAVA_SCHOOL_NAME'
?? and jt1.school_id = oalc.lookup_code(+)
?? and oalc2.lookup_type(+) = 'JAVA_SYSTEM_NAME'
?? and jt1.system_id = oalc2.lookup_code(+)
?? and oalc3.lookup_type(+) = 'JAVA_CLASS_NAME'
?? and jt1.class_id = oalc3.lookup_code(+)
?? and not exists
(select jt2.header_id
????????? from java_table2 jt2 jt1.header_id = jt2.header_id))

select jt1.doc_num --單據(jù)號(hào)碼
????? ,oalc.description school_name --學(xué)校名稱
????? ,oalc2.description system_name --系名稱
????? ,oalc.description class_name --班級(jí)名稱
? from java_table1??????????? jt1
????? ,java_table_description oalc
????? ,java_table_description oalc2
????? ,java_table_description oalc3
where oalc.lookup_type(+) = 'JAVA_SCHOOL_NAME'
?? and jt1.school_id = oalc.lookup_code(+)
?? and oalc2.lookup_type(+) = 'JAVA_SYSTEM_NAME'
?? and jt1.system_id = oalc2.lookup_code(+)
?? and oalc3.lookup_type(+) = 'JAVA_CLASS_NAME'
?? and jt1.class_id = oalc3.lookup_code(+)
?? and jt1.header_id not in (select jt2.header_id from java_table2 jt2)

當(dāng)jt2表中的數(shù)據(jù)比較大時(shí),就會(huì)出現(xiàn)巨大的差異,以上只能是我的個(gè)人理解與測(cè)試結(jié)果(java_table1 視圖測(cè)試

數(shù)據(jù)量為36749,java_table2 為300條),如有其它可相互討論

oracle中sql語(yǔ)句的優(yōu)化(轉(zhuǎn)帖)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 亚洲深夜在线 | 日韩欧美在线观看视频 | 91视频原创| 久久国产三级精品 | 日韩在线视频一区二区三区 | 狠狠色丁香婷婷综合激情 | 欧美aa一级 | 国产理论自拍 | 全部免费毛片免费播放 | 国产在线91精品入口首页 | 国产95在线 | 亚洲 | 婷婷综合社区 | 日韩一区二区三区在线观看 | 精品一区二区三区影片 | 这里只有精品在线观看 | 日本护士a做爰免费观看 | 免费色片| 亚洲七七久久精品中文国产 | 久草视频免费看 | 国产精品亚洲第一区二区三区 | 伊人精品国产 | 日韩毛片欧美一级国产毛片 | 看欧美毛片一级毛片 | 国产草 | 国产玖玖玖精品视频 | 九九免费精品视频 | 成年黄页免费大全网站 | 国产成人青草视频 | 国产免费一区二区 | 日本aⅴ永久免费网站www | 国产精品99久久久久久宅男 | 亚洲国产日本 | 欧美大片一区 | 亚洲精品久久久中文字幕 | 亚洲综合香蕉 | 日本不卡在线观看 | 四虎ww| 99亚洲乱人伦精品 | 久久国产精品只做精品 | 欧美视频在线观看一区二区 | 亚洲毛片在线免费观看 |