MySQL數據庫優化的八種方式


1,選取最適用的字段屬性

  MySQL 可以很好的支持大數據量的存取,但是一般來說,數據庫中的表越小,在它上面執行的查詢也就會越快。因為,在創建表的時候,為了獲得更好的性能,我們可以將表的字段的寬度設置的盡可能的小。

  例如,在定義郵箱這個字段時候,如果我們將其設置成char(255) ,顯然給數據庫增加了不必要的空間,甚至使用varchar這種類型也是多余的,因為char(6)就可以很好的完成任務了。同樣的,如果可以的話,我們應該使用MEDIUMINT而不是BIGIN來定義整型字段。

  另一個提高效率的方法是在可能的情況下,應該盡量把字段設置為NOT NULL。這樣在將來執行查詢的時候,數據庫不用去比較NULL值。

  對於默寫文本的字段,例如:省份 ,或者 “性別” ,我們可以將他們定義為enum 類型。因為在MySQL中,enum類型被當作數值類型來處理,而數值類型數據被處理起來的速度要比文本類型快得多。這樣,我們又可以提高數據庫的性能。

2,使用連接(JOIN)來代替子查詢(Sub-Queries)

  從4.1開始支持SQL的子查詢。這個技術可以使用SELECT 語句來創建一個單列的查詢結果,然后把這個結果作為過濾條件用在另一個查詢中。例如:我們將客戶基本信息表中沒有任何訂單的客戶刪除掉,就可以利用子查詢先從銷售信息表中獎所有發出訂單的客戶ID取出來,然后將去結果傳遞給主查詢。

  如:

  delete from customerinfo where cID not in(select cID from salesinfo)

  使用子查詢可以一次性的完成很多邏輯上需要多個步驟才能完成的SQL操作,同事也可以避免失誤或者表鎖死,並且寫起來也很容易。但是有些情況下,子查詢可以被更有效率的連接(JOIN)替代。例如,假設我們要講所有沒有訂單記錄的用戶取出來,可以用下面這個查詢完成:

  select * from customerinfo where cID not in(select cID from salesinfoi)

如果使用連接(JOIN) 來完成這個查詢工作,速度將會快很多。尤其是當salesinfo表中對cID 兼有索引的話,性能將會更好,查詢如下:

  select * from customerinfo as c left join salesinfo as s on c.cID = s.cID where s.cID is NULL

連接之所以有效率,是因為MySQL不需要在內存中創建臨時表來完成這個邏輯上的需要兩個步驟的查詢工作。

 

3,使用聯合(UNION)來代替手動創建的臨時表

  從4.0的版本開始支持union查詢 ,他可以把需要臨時表的兩條或者更多的select查詢和冰的一個查詢中。在客戶端的查詢會話結束的時候,臨時表會被自動刪除,從而保證數據庫整齊,高效。使用union來創建查詢的時候,我們只需要工union作為關鍵字把多個select語句連接起來就可以了。要注意的是所有的select語句中的字段數目要相同。下面的例子就是掩飾一個使用了union的查詢。

  select name,phone from client union

  select name birhtdate from author union

  select name,supplier from product

 

4,事務

  盡管我們可以使用子查詢(sub-Queries),連接(JOIN),聯合(UNION)來創建各種各種的查詢。但不是所有的數據庫操作都可以只用一條或者少數幾條SQL語句就可以完成的。更多的時候是需要用到一系列的語句來完成某種工作。

  但是這種情況下,當這個語句塊中的某一條語句運行出錯的時候,整個語句塊的操作就會變得不確定起來。

  設想一下,要把某個數據同時插入兩個相關聯的表中,可能會出現,第一個表成功更新后,數據庫突然出現意外狀況,造成第二個表中的操作沒有完成,這樣,就會造成數據的不完整,甚至會破壞數據庫中的數據。

  要避免這種情況,就應該使用事務,他的作用就是:要么語句塊中的每天語句都操作成功,要么都失敗。換句話說,就是可以保持數據庫中的數據一致性和完成整。事務一BEGIN關鍵字開始,commit關鍵字結束。在這之間的一條SQL操作失敗,那么,ROLLBACK命令就可以把數據庫恢復到BEIGIN開始之前的狀態。

  BEGIN; insert into salesinfo set cID=14;UPDATE testable set qty=1 where id=1; commit;

  事務的另一個重要作用,就是當多個用戶同時使用相同的數據源時,它可以利用鎖定數據的方法來為用戶提供一種安全的訪問方式,這樣可以保證用戶的操作不被其他的用戶干擾。

 

5,鎖定表

  盡管事務是維護數據庫完成性的一個非常好的辦法,但是卻因為他的獨占性,有時會影響數據庫的性能,尤其是在很大的應用系統中。

  由於在事務執行的過程中,數據庫將會被鎖定,因此其他的永不請求只能暫時等待直到該事務結束。如果一個數據庫系統只有少數幾個用戶來使用,事務造成的影響不會成為一個太大的問題;但假設有成千上萬的用戶同事訪問一個數據庫系統,例如訪問一個電子商務網站,就會產生比較嚴重的相應延遲。

  其實,有些情況下,我們可以通過鎖定表的方法來獲得更好的性能。下面的例子就用鎖定表的方法來完成前面一個例子中的事務的功能

  LOCK TABLE testtable WRITE SELECT qty from testtable where id=1

  UPDATE testtable set qty=11 where id=1 ;UNLOCKTABLE

這里,我們用一個select語句去除初始數據,通過一些計算,用update語句將心智更新到表中。包含有write關鍵字的locktable 語句可以保證在unlocktable命令被執行之前,不會有其他的訪問來對testtable表進行插入,刪除等操作。

 

6,使用外鍵

  鎖定表的方法可以維護數據的完整性,但是它卻不能保證數據的關聯性。這個時候我們就可以使用外鍵。

  例如,外鍵可以保證每一條銷售記錄都指向某一個存在的客戶。在這里,外鍵可以把customerinfo表中的CustomerID映射到salesinfo表中CustomerID,任何一條沒有合法CustomerID的記錄都不會被更新或插入到salesinfo中。

  

CREATE    TABLE    customerinfo( 
    CustomerIDINT    NOT    NULL,
    PRIMARYKEY(CustomerID)
)TYPE=INNODB;

CREATE    TABLE    salesinfo( 
    SalesIDNT    NOT    NULL,
    CustomerIDINT    NOT    NULL,
    PRIMARYKEY(CustomerID,SalesID),
    FOREIGNKEY(CustomerID) REFERENCES customerinfo(CustomerID) ON DELETE    CASCADE
)TYPE=INNODB;

  注意例子中的:ON DELETE CASCADE 。該參數保證當customerinfo表中的一條客戶記錄被刪除的時候,saleinfo表中的所有與客戶相關的記錄也會被自動刪除。如果要在MySQL中使用外鍵,一定要記住在創表達額時候,將表的類型定義為事務安全的innodb引擎。

 

7,使用索引

  索引是提高數據庫性能的常用方法,它可以令數據庫服務器以比沒有索引快的多的速度檢索特定的行,尤其是在查詢語句當中包含了MAX(),MIN()和ORDERBY這些明星的時候,性能提高為明顯。

   那該對那些字段簡歷索引呢?

  一般來說,索引應該建立在那些將用戶join,where判斷和order by排序的字段上,機娘不要對數據中心某個含有大量重復值的字段簡歷索引。對於一個enum類型的字段來說,出現大量重復值是有可能的情況。

  例如customerinfo中,province 字段,在這樣的字段上建立所以拼將不會有什么幫助。相反,還有可能降低數據庫的性能。我們在創建表的時候可以同時創建合適的索引,也可以使用ALTER TABLE或CREATE INDEX 在以后創建索引。全文索引在MySQL中是一個FULLTEXT類型索引,但僅能用於MyISAM類型的表。

 

8,優化的查詢語句

  絕大多數情況下,使用索引可以提高查詢的速度,但如果sql語句使用不恰當,索引將無法發揮它應有的作用。

  下面是應該注意的幾個方面。

  •   首先,最好是在相同類型的字段間進行比較的操作。  

    例如不能將一個建有索引的int字段和bigint字段進行比較,但是作為特殊的情況,在char類型的字段和varchar類型的字段的大小相同的時候。可以將它們進行比較。

  •   其次,在兼有索引的字段上盡量不要使用函數進行操作。

  例如,在一個DEATE類型的字段上使用YEAE()函數時,將會使用索引不能發揮應有的作用,所以下面的兩個查詢雖然返回的結果一樣,但后者要比前者快得多。

  • 第三,在搜索字符型字段時,我們有時會使用LIKE關鍵字和通配符,這種做法雖然簡單,但卻也是以犧牲系統性能為代價的。

  

1,
    select * from table where name like "mm%"

2,這個下面的SQL速度要大於1的速度
    select * from table where name >="mm" and name <"mm"

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM