天天看點

關于sql語句的優化

最近在做mysql的資料庫優化以及對sql語句優化的指導,寫了一點文檔,這個大家共勉一下!

資料庫參數進行優化所獲得的性能提升全部加起來隻占資料庫應用系統性能提升的40%左右,其餘60%的系統性能提升全部來自對應用程式的優化。許多優化專家甚至認為對應用程式的優化可以得到80%的系統性能提升。是以可以肯定,通過優化應用程式來對資料庫系統進行優化能獲得更大的收益。

通常可分為兩個方面: sql語句的優化和資料庫性能調優。應用程式對資料庫的操作最終要表現為sql語句對資料庫的操作。而資料庫性能調優是結合硬體,軟體,資料量等的一個綜合解決方案,這個需要測試人員進行性能測試,和開發人員配合進行性能調優。

sql語句優化

3.1關鍵詞優化

所有關鍵詞都大寫。如:select,form,where,and,create,table等等,例如:使用mysql管理工具導出sql檔案,我們可以看到大部分關鍵詞都是大寫。如下圖:

關于sql語句的優化

解釋:這是因為,oracle的sql的處理底層,預設就将所有的sql語句,進行大寫轉換。mysql和oracle是同一家公司,不排除哪一天mysql和oracle都做的一樣了。

3.2 sql語句中不能存在*

在所有的查詢sql語句中,不能存在*符号。即,select *form 。舉例我們的部門表的查詢。錯誤寫法:select * from tdepartment 正确寫法:select idepartmentid,scompanycode,sdepartmentname,iparentdepartmentid,sdeptposttype,sifdeleted,sleafnode,sdesc from tdepartment。原因:*号會檢索全部字段,

用*号效率低,就相當于for循環和foreach一樣。用*号,sql語句查詢底層會預設去字      

典庫裡查詢公有多少個字段,然後在一個一個的取。如果不使用*,就不是去先查字典庫。

3.3 count(*)使用

項目中不能使用count(*)的sql語句。count(*)全部替換成count(1)。這在資料量比較小的情況下,不明顯,但是在表中資料較多的情況下,效果非常明顯。

3.4多用比對查詢,少用like查詢

      原因,like查詢會直接放棄索引。

3.5主鍵索引使用

      所有表的主鍵全是索引。應盡量使用主鍵查詢。如:select * from tusers order by dregistertime desc效率低于select * from tusers order by iuserid desc。這是因為所有的主鍵都預設是索引。而注冊時間不是索引字段。 

3.6第1第2索引排列使用

假設我們的使用者表中的scompanycode,dregistertime兩個字段都建立了索引。而scompanycode是第一索引。dregistertime是第二索引。那麼查詢時:select * from tusers order by scompanycode,dregistertime desc的效率高于select * from tusers order by dregistertime,scompanycode desc。這是因為第一索引将首先被檢索。

3.7建表不要給字段設定預設值

如:`sifaudited` varchar(2) default '0' comment '0:未稽核;1:已稽核'。預設值會在插入資料時,增加資料庫底層判斷是否有值情況,進行賦預設值。

3.8字段不要留null值

這是因為null值占用的資料大小比較大。null和空一般占4到8個位元組。如:`scompanycode` varchar(16) default null comment '公司編号(唯一識别)',對于這樣的,我們一般把空值改為0,你們應該懂的。

3.9多用子查詢

      子查詢性能高于連接配接查詢。子查詢性能高于左聯接、右連接配接、全連接配接查詢。

3.10連接配接查詢性能高于循環查詢

對于部門查詢,我們一般是查詢根目錄,然後循環查詢子部門,一直循環到查詢結束。性能較低。我們應該采用,連接配接查詢。或者寫函數,存儲過程進行查詢。

4.設計優化

4.1 日志子產品,新增隊列,當日志達到100條或者200、500條的時候,我們采用批量插入n條,減少磁盤的io次數。這樣可以延長磁盤的壽命,同時對資料的插入也有了明顯的提高。

5.資料庫引擎使用

5.1   engine = innodb

    innodb資料庫引擎是對外鍵,事務進行過優化。我們對建立所有的表都使用innodb引擎。這是錯誤的,應該對每一個表的用途對應一個不同的資料庫引擎。

5.2   engine = myisam

myisam類型不支援事務處理等進階處理。myisam類型的表強調的是性能,其執行數度比innodb類型更快,但是不提供事務支援。myisam類型的二進制資料檔案可以在不同作業系統中遷移。也就是可以直接從windows系統拷貝到linux系統中使用。這個是預設類型,它是基于傳統的isam類型,isam是indexed sequential access method (有索引的 順序通路方法) 的縮寫,它是存儲記錄和檔案的标準方法.與其他存儲引擎比較,myisam具有檢查和修複表格的大多數工具. myisam表格可以被壓縮,而且它們支援全文搜尋.它們不是事務安全的,而且也不支援外鍵。如果事物復原将造成不完全復原,不具有原子性。如果執行大量 的select,myisam是更好的選擇。這個類型東海們項目使用的多。最常用的引擎之一。

5.3   engine = bdb

bdb:可替代innodb的事務引擎,支援commit、rollback和其他事務特性。

5.4   engine = memory

memory:将所有資料儲存在ram中,在需要快速查找引用和其他類似資料的環境下,可提供極快的通路。

5.5   engine = merge

merge:允許mysql dba或開發人員将一系列等同的myisam表以邏輯方式組合在一起,并作為1個對象引用它們。對于諸如資料倉儲等vldb環境十分适合。

5.6    engine = archive

archive:為大量很少引用的曆史、歸檔、或安全審計資訊的存儲和檢索提供了完美的解決方案。

5.7    engine = federated

 federated:能夠将多個分離的mysql伺服器連結起來,從多個實體伺服器建立一個邏輯資料庫。十分适合于分布式 環境或資料集市環境。

5.8    engine =cluster/ndb

cluster/ndb:mysql的簇式資料庫引擎,尤其适合于具有高性能查找要求的應用程式,這類查找需求還要求具有最高的正常工作時間和可用性

5.9    other:其他存儲引擎包括csv(引用由逗号隔開的用作資料庫表的檔案),blackhole(用于臨時禁止對資料庫的應用程式輸入),以及example引擎(可為快速建立定制的插件式存儲引擎提供幫助)。

6.表字段設計

  6.1對于類型限制。是否删除字段,如:`sifdeleted` varchar(2) default '0' comment '0:正常;1:已删除',使用int(1)類型辨別,不要使用varchar(2)多占用空間。

     6.2 對于字段長度限制,如手機号11位,我們就沒有必要設計更多位數。公司編号可以隻設定8位。使用者名限制32位等等。

     6.3 少用外鍵限制

         我們可以使用代碼限制。如:級聯删除,級聯新增,修改等等操作。最好不要設計外鍵,外鍵對新增資料不利。

     6.4  少用限制,如:唯一限制。

 6.5  少用自動增長

      在圓通主鍵沒有自動增長,而是使用uuid,java自動生成。考慮到我們資料表資料較少,少用。

 6.6  對于内容較少的表,沒有必要建立索引。因為索引浪費空間。

 6.7  表分區使用

      對于日志表,我們可以使用表分區。表分區之後,對于查詢效率有很高的提升。預設有時間分區,大小分區,類型分區等等。

 6.8  對表的内容進行限制,如:日志表可以限制條數。再建立表時。我們使用max_rows進行限制。

7.其他請遵守建表規則

   如:三範式等。

好吧就到這裡,歡迎大家關注我的個人部落格!

如有疑問,請加qq群:135430763 共同學習!

點選文檔下載下傳: