如果程序中采用sql拼接的方式書寫代碼,那么很可能存在SQL注入漏洞。避免的方式有兩種:
1. 對于用戶輸入過濾敏感字母;
2. 參數化SQL(推薦)。
二、索引①索引分類
②碎片整理
在刪除一條數據項記錄時,并不會刪除對應的索引項。所以經過一段時間后數據庫中會出現索引碎片,降低效率。進行隨便整理的辦法可以進行索引重建。
例如:
ALTER TABLE [dbo]. [test] DROP CONSTRAINT [DF__bAuto__47A6A41B]GOALTER TABLE [dbo]. [test] ADD CONSTRAINT [DF__bAuto__47A6A41B] DEFAULT ((0)) FOR [name]GO
③全表掃描和索引查找
全表掃描:就是在整個數據表中逐條檢索每條記錄,當數據量大的時候,性能低下。
索引查找:就是當表中創建了索引并且查詢語句符合索引條件時,只對索引進行檢索,而不必對每條記錄進行篩選,性能大大提高。
三、SQL調優方案十二條在調優的時候不要追求完美,先用工具追蹤到最占資源的SQL進行優化,往往能起到事半功倍的效果。
常用優化方式:
1.創建必要的索引
在經常檢索的字段創建索引,能起到非常大的優化效果。
2.避免在索引列上進行計算
如果在索引列上進行計算或者使用函數,那么DBMS優化器將不會使用索引而是使用全表掃描。
SELECT *FROM T_EmployeeWHERE FSalary * 12 >25000;==>SELECT *FROM T_EmployeeWHERE FSalary >25000/12;
3.參數化SQL
如果SQL是根據用戶輸入動態生成的,那么可以將用戶輸入進行參數處理。這樣不僅能夠避免SQL注入漏洞,而且能提高性能。因為DBMS在第一次執行的時候會進行查詢優化和預編譯,再次執行的時候可以直接使用預編譯結果,從而提高執行效率。
4.調整where子句連接順序
where子句中盡量把子查詢放在其他篩選條件之前,可以提高效率。
例如:
SELECT * FROM T_PersonWHERE 25 < (SELECT COUNT(*) FROM T_ManagerWHERE FManagerId=2)AND FSalary > 50000AND FPosition= ‘MANAGER’ ;
5.避免使用*
在SELECT語句中寫明需要查詢的列名。即使要查詢所有列,也不要偷懶使用*查詢,因為這樣在DBMS執行的過程中仍然要解析出所有列名,浪費性能。
6.列出表名
在使用多表連接查詢時,盡量在字段前帶上表名前綴,這樣既容易理解又能減少查詢過程中的解析時間。
7.用WHERE 子句替換HAVING子句
HAVING子句會在查詢出所有結果后才對結果進行過濾,一般用于對聚合函數運算的過濾,其它情況進行條件篩選盡量使用WHERE子句。
8. 用EXISTS替換IN
第二種寫法要好于第一種寫法。
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
一般來說表連接的效率要優于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
如果進行合并的兩個表肯定不會重復記錄,那么使用UNION ALL會效率高些。因為UNION方法會一直嘗試進行合并。
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.避免隱式類型轉換
例如FAge字段類型為字符串,但是一般數據庫中的數值類型優先級比字符串類型高,因此會進行隱式類型轉換。
SELECT FId,FAge,FNameFROM T_PersonWHERE FAge=10相當于SELECT FId,FAge,FNameFROM T_PersonWHERE TO_INT(FAge)=10==>SELECT FId,FAge,FNameFROM T_PersonWHERE FAge='10'
12.防止檢索范圍過寬
如果DBMS優化器認為檢索范圍過寬,則會使用全表掃描而放棄索引查詢。
以下幾種情況容易被認為檢索范圍過寬:
新聞熱點
疑難解答