国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 開(kāi)發(fā) > 綜合 > 正文

讀《程序員的SQL金典》[4]--SQL調(diào)優(yōu)

2024-07-21 02:50:50
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友
讀《程序員的SQL金典》[4]--SQL調(diào)優(yōu)一、SQL注入

如果程序中采用sql拼接的方式書(shū)寫(xiě)代碼,那么很可能存在SQL注入漏洞。避免的方式有兩種:

1. 對(duì)于用戶輸入過(guò)濾敏感字母;

2. 參數(shù)化SQL(推薦)。

二、索引

①索引分類(lèi)

  • 聚簇索引:數(shù)據(jù)表的物理順序和索引順序相同。每個(gè)表只能建立一個(gè)聚簇索引,應(yīng)該在表中經(jīng)常訪問(wèn)的列或者按順序訪問(wèn)的列建立聚簇索引。
  • 非聚簇索引:數(shù)據(jù)表的物理順序和索引順序不同。每個(gè)表可以建立多個(gè)非聚簇索引。

②碎片整理

在刪除一條數(shù)據(jù)項(xiàng)記錄時(shí),并不會(huì)刪除對(duì)應(yīng)的索引項(xiàng)。所以經(jīng)過(guò)一段時(shí)間后數(shù)據(jù)庫(kù)中會(huì)出現(xiàn)索引碎片,降低效率。進(jìn)行隨便整理的辦法可以進(jìn)行索引重建。

例如:

ALTER TABLE [dbo]. [test] DROP CONSTRAINT [DF__bAuto__47A6A41B]GOALTER TABLE [dbo]. [test] ADD CONSTRAINT [DF__bAuto__47A6A41B] DEFAULT ((0)) FOR [name]GO

③全表掃描和索引查找

全表掃描:就是在整個(gè)數(shù)據(jù)表中逐條檢索每條記錄,當(dāng)數(shù)據(jù)量大的時(shí)候,性能低下。

索引查找:就是當(dāng)表中創(chuàng)建了索引并且查詢語(yǔ)句符合索引條件時(shí),只對(duì)索引進(jìn)行檢索,而不必對(duì)每條記錄進(jìn)行篩選,性能大大提高。

三、SQL調(diào)優(yōu)方案十二條

在調(diào)優(yōu)的時(shí)候不要追求完美,先用工具追蹤到最占資源的SQL進(jìn)行優(yōu)化,往往能起到事半功倍的效果。

常用優(yōu)化方式:

1.創(chuàng)建必要的索引

在經(jīng)常檢索的字段創(chuàng)建索引,能起到非常大的優(yōu)化效果。

2.避免在索引列上進(jìn)行計(jì)算

如果在索引列上進(jìn)行計(jì)算或者使用函數(shù),那么DBMS優(yōu)化器將不會(huì)使用索引而是使用全表掃描。

SELECT *FROM T_EmployeeWHERE FSalary * 12 >25000;==>SELECT *FROM T_EmployeeWHERE FSalary >25000/12;

3.參數(shù)化SQL

如果SQL是根據(jù)用戶輸入動(dòng)態(tài)生成的,那么可以將用戶輸入進(jìn)行參數(shù)處理。這樣不僅能夠避免SQL注入漏洞,而且能提高性能。因?yàn)镈BMS在第一次執(zhí)行的時(shí)候會(huì)進(jìn)行查詢優(yōu)化和預(yù)編譯,再次執(zhí)行的時(shí)候可以直接使用預(yù)編譯結(jié)果,從而提高執(zhí)行效率。

4.調(diào)整where子句連接順序

where子句中盡量把子查詢放在其他篩選條件之前,可以提高效率。

例如:

SELECT * FROM T_PersonWHERE 25 < (SELECT COUNT(*) FROM T_ManagerWHERE FManagerId=2)AND FSalary > 50000AND    FPosition= ‘MANAGER’ ;

5.避免使用*

在SELECT語(yǔ)句中寫(xiě)明需要查詢的列名。即使要查詢所有列,也不要偷懶使用*查詢,因?yàn)檫@樣在DBMS執(zhí)行的過(guò)程中仍然要解析出所有列名,浪費(fèi)性能。

6.列出表名

在使用多表連接查詢時(shí),盡量在字段前帶上表名前綴,這樣既容易理解又能減少查詢過(guò)程中的解析時(shí)間。

7.用WHERE 子句替換HAVING子句

HAVING子句會(huì)在查詢出所有結(jié)果后才對(duì)結(jié)果進(jìn)行過(guò)濾,一般用于對(duì)聚合函數(shù)運(yùn)算的過(guò)濾,其它情況進(jìn)行條件篩選盡量使用WHERE子句。

8. 用EXISTS替換IN

第二種寫(xiě)法要好于第一種寫(xiě)法。

SELECT * FROM T_EmployeeWHERE FNumber> 0AND FDEPTNO IN (SELECT FNumber FROM T_Department WHERE FMangerName = 'Tome')==>SELECT * FROM T_EmployeeWHERE FNumber > 0AND EXISTS (SELECT 1FROM T_DepartmentWHERE T_Department. FDEPTNO = EMP.FNumberAND FMangerName = ‘MELB’)

9.用表連接替換EXISTS

一般來(lái)說(shuō)表連接的效率要優(yōu)于EXISTS。

例如:

SELECT FName FROM T_EmployeeWHERE EXISTS(SELECT 1 FROM T_DepartmentWHERE T_Employee.FDepartNo= FNumberAND FKind='A');==>SELECT FName FROM T_Department, T_EmployeeWHERE T_Employee. FDepartNo = T_Departmen. FNumberAND FKind = ‘A’ ;

10.用UNION ALL替換UNION

如果進(jìn)行合并的兩個(gè)表肯定不會(huì)重復(fù)記錄,那么使用UNION ALL會(huì)效率高些。因?yàn)閁NION方法會(huì)一直嘗試進(jìn)行合并。

SELECT ACCT_NUM, BALANCE_AMT        FROM DEBIT_TRANSACTIONS1        WHERE TRAN_DATE = '20010101'        UNION        SELECT ACCT_NUM, BALANCE_AMT        FROM DEBIT_TRANSACTIONS2        WHERE TRAN_DATE ='20010102'==>        SELECT ACCT_NUM, BALANCE_AMT        FROM DEBIT_TRANSACTIONS1        WHERE TRAN_DATE ='20010101'        UNION ALL        SELECT ACCT_NUM, BALANCE_AMT        FROM DEBIT_TRANSACTIONS2        WHERE TRAN_DATE = '20010102'

11.避免隱式類(lèi)型轉(zhuǎn)換

例如FAge字段類(lèi)型為字符串,但是一般數(shù)據(jù)庫(kù)中的數(shù)值類(lèi)型優(yōu)先級(jí)比字符串類(lèi)型高,因此會(huì)進(jìn)行隱式類(lèi)型轉(zhuǎn)換。

SELECT FId,FAge,FNameFROM T_PersonWHERE FAge=10相當(dāng)于SELECT FId,FAge,FNameFROM T_PersonWHERE TO_INT(FAge)=10==>SELECT FId,FAge,FNameFROM T_PersonWHERE FAge='10'

12.防止檢索范圍過(guò)寬

如果DBMS優(yōu)化器認(rèn)為檢索范圍過(guò)寬,則會(huì)使用全表掃描而放棄索引查詢。

以下幾種情況容易被認(rèn)為檢索范圍過(guò)寬:

  • 使用IS NOT NULL;
  • 使用不等于判斷;
  • 使用LIKE匹配字符串時(shí),使用'a%'可以用到索引,但是使用'%b'或者'a%b'則會(huì)使用全表掃描。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 桐梓县| 鸡东县| 武功县| 醴陵市| 东宁县| 宜川县| 万源市| 崇文区| 顺昌县| 九江县| 德阳市| 石河子市| 姜堰市| 澎湖县| 县级市| 海安县| 敖汉旗| 华宁县| 利津县| 孟州市| 金寨县| 崇信县| 万宁市| 淳化县| 平安县| 普陀区| 定陶县| 偃师市| 常宁市| 公安县| 易门县| 湛江市| 祥云县| 清远市| 昭平县| 蓬莱市| 亳州市| 沙坪坝区| 扶沟县| 永城市| 富顺县|