前言
? ? ? ? 慢SQL會(huì)增加數(shù)據(jù)庫壓力适室,影響系統(tǒng)的訪問速度及用戶體驗(yàn)嫡意。
影響查詢效率的因素
1、全表掃描亭病。
2鹅很、無索引或索引無效
3、多表關(guān)聯(lián)罪帖。
3促煮、數(shù)據(jù)量。
優(yōu)化策略
1整袁,加索引菠齿。對(duì)where條件字段,order by 字段加索引或聯(lián)合索引坐昙。
? 注:有幾種情況會(huì)導(dǎo)致索引無效
a绳匀、where條件中是or關(guān)系,會(huì)導(dǎo)致索引無效。
b疾棵、in查詢時(shí)戈钢, in()中數(shù)據(jù)太多,優(yōu)化器認(rèn)為全表掃描更快時(shí)是尔,也不會(huì)使用索引殉了。
c、like拟枚、索引上使用函數(shù)等使索引失效薪铜。
d、字段屬性設(shè)置為 not null 恩溅,where條件中有 is null 或 is not null 判斷時(shí)隔箍,索引無效
2,去掉子查詢 脚乡。我們都知道子查詢效率低蜒滩,能不用就盡量不用,比如我們可以通過join或left join或right join關(guān)聯(lián)在實(shí)現(xiàn)子查詢每窖,如下例所示:
SELECT? b.businesskey, b.bo_def,? (SELECT boe.table_name FROM $ { db }.form_bo_def boe WHERE boe.alias =b.bo_def_code) table_nameFROM$ { db }.bpm b
改造后:
SELECT b.businesskey, b.bo_def, boe.table_nameFROM $ { db }.bpm bLEFT JOIN $ { db }.form_bo_def boe ON? b.bo_def_code = boe.alias
3帮掉,盡量少用或不用 or關(guān)聯(lián),可以通過union進(jìn)行拼接窒典。or會(huì)導(dǎo)致索引無效,當(dāng)數(shù)據(jù)量多大時(shí)稽莉,速度會(huì)越來越慢瀑志。如下例所示:
SELECT b.businesskey, b.bo_def, boe.table_nameFROM $ { db }.bpm bLEFT JOIN $ { db }.form_bo_def boe ON? b.bo_def_code = boe.alias where b.proc_id ='#{userId}' or b.proc_id='0'
改造后:
SELECT b.businesskey, b.bo_def, boe.table_nameFROM $ { db }.bpm bLEFT JOIN $ { db }.form_bo_def boe ON? b.bo_def_code = boe.alias where b.proc_id ='#{userId}' UNIONSELECT b.businesskey, b.bo_def, boe.table_nameFROM $ { db }.bpm bLEFT JOIN $ { db }.form_bo_def boe ON? b.bo_def_code = boe.alias where? b.proc_id='0'
4,select查詢時(shí)污秆,避免用select * from table這種寫法劈猪,采用select 字段 from 字段的方式來提升執(zhí)行效率。
5良拼、多表聯(lián)查時(shí)战得,小表驅(qū)動(dòng)大表。
例: user表10000條數(shù)據(jù)庸推,class表20條數(shù)據(jù)select * from user u left join class c u.userid=c.userid這樣則需要用user表循環(huán)10000次才能查詢出來常侦,而如果用class表驅(qū)動(dòng)user表則只需要循環(huán)20次就能查詢出來
6,適當(dāng)增加冗余字段贬媒,減少多表聯(lián)查(4張以上)情況聋亡。多表聯(lián)查必然會(huì)帶來性能問題,我們通過適當(dāng)增加冗余字段际乘,減少表之間關(guān)聯(lián)查詢坡倔。
以上為前一段時(shí)間SQL優(yōu)化的心得。