mysql效能最佳化

來源:互聯網
上載者:User

標籤:blog   http   使用   os   strong   io   資料   for   

http://blog.csdn.net/uestc_huan/article/category/536350  博主首頁

http://blog.csdn.net/uestc_huan/article/details/6071081 博文地址

本文不從DBA的角度去講解mysql Server的參數如何設定,而是從程式員和架構師的角度,去說明在寫程式和設計系統的時候,需要注意的mysql的一些最佳化點。因此,沒有在本文中詳細論述伺服器參數的設定含義和調優。

 

 

    關於索引

1. mysql使用的B+tree的深度的計算:

B+樹每塊數值的大小 = 每個block的大小 / 索引值的大小

比如mysql每個block為4K,索引值設為4個位元組的int,那麼每個索引塊的大小為4k/4 = 1k。

那麼儲存一億行的資料,需要的B+樹的高度為

h = log1000(一億) =3 (以1000為底,一億的對數)。可見B+樹的高度不會很高,一般深度都不會超過5.

 

 

2. 為了避免隨機IO操作,可以建立聯合index來避免隨機IO操作。即用“索引-值”對來建立一個聯合index。這樣,就可以直接從索引中讀取資料,而不需要根據索引再去磁碟讀取實際的資料。

比如 : select age from user_info where name=lisi;

那麼,建立name-age的聯合索引,那麼從索引就可以直接讀取資料。如果僅僅建立name的索引,那麼它需要根據name=lisi定位到這行資料的位置,再從這個位置讀取出age。

 

 

3. 如果僅僅是點查詢,而不需要範圍查詢,那麼使用hash索引會比B+tree索引更快。就是僅僅需要 where aaa=bbb這樣的查詢條件,而不需要where aaa> bbb這樣的查詢條件。

 

 4. 使用logloader或者dump的操作速度,會比簡單的sql語句快5倍以上。

 

 5.log 放在單獨的磁碟上,可緩解io瓶頸。

 

 6.慢查詢是影響mysql效能的主要因素。慢查詢主要通過分析慢查詢日誌來處理。很多現有的工具可以分析。諸如 mysqldumpslow,  mysql_slow_log_filter,  mysql_slow_log_parser, mysqlsal等。

 

 

關於事務的理解

1. 事務應該具有ACID屬性,(atomicity, consistency, isolation, durability),一致性和持久性比較好理解。原子性和隔離性需要做一些說明。

事務的原子性僅僅指同一個事務本身的原子性。一個事務未執行或者執行一半時,另外的事務(另外一個串連中)是可以並發執行的。這涉及到事務隔離度的概念(isolation)。可以做一個測試,用兩個用戶端去串連資料庫,分別開始事務,分別執行兩個進程。只有在事務中執行了upate,insert,delete的語句,並且affect的行數大於0的時候,才會阻塞另外一個事務。而且這個跟資料庫的隔離度等級也有關係。

下面是關於隔離度的解釋。

(1).查看當前會話隔離等級

select @@tx_isolation;

 

(2).查看系統當前隔離等級

select @@global.tx_isolation;

 

(3).設定當前會話隔離等級

set session transaction isolatin level repeatable read;

 

(4).設定系統當前隔離等級

set global transaction isolation level repeatable read;

 

(5).命令列,開始事務時

set autocommit=off 或者 start transaction

 

關於隔離等級的理解

(1)read uncommitted

可以看到未提交的資料(髒讀),舉個例子:別人說的話你都相信了,但是可能他只是說說,並不實際做。

 

(2)read committed

讀取提交的資料。但是,可能多次讀取的資料結果不一致(不可重複讀取,幻讀)。用讀寫的觀點就是:讀取的行資料,可以寫。

 

(3)repeatable read(MySQL預設隔離等級)

在MySQL中,其他事務新增的資料,看不到,不會產生幻讀。採用多版本並發控制(MVCC)機制解決幻讀問題。

 

(4)serializable

可讀,不可寫。寫資料必須等待另一個事務結束。

 

 

7. 兩個事務是可能發生死結的,

舉個例子:

Transaction1

     Start transaction;

     Update stockprice set close=45.5 where stock_id =4;

     Update stockprice set close=47.7 where stock_id=3;

     Commit;

Transaction2

    Start transaction;

     Update stockprice set close=45.5 where stock_id =3;

     Update stockprice set close=47.7 where stock_id=4;

     Commit;

當兩個事務都執行了第一條而未執行第二條時,就發生了死結。

 

 

關於資料類型

1. 避免用DEFAULT  NULL數值,原因一方面是為了索引速度更快(儘管在高版本的mysql已經不存在這個問題),另一方面是避免應用程式產生一些不必要的困惑和bug.

 

 

2. int(1)和int(20)的區別僅僅是在顯示上,對於計算和預存程序,是完全一樣的。

 

 

3. DECIMAL在4.1版本及之前,僅僅是儲存類型,它的效率比float和double都低。DEMICAL僅僅應該用在金融數字上,因為它可以指定所需要的計算精度。

 

4. Blob和text是最耗效能的。因為記憶體儲存機制(memory storage engine)不支援這兩個類型,因為查詢這兩個類型的資料都會用到磁碟暫存資料表。儘可能避免使用這兩種類型資料。如果要對這兩種類型的資料排序,用order by substring(column, length)轉成string類型。此時如果substring小,可以轉成記憶體暫存資料表,速度會快很多。額外插一句,字元匹配尋找演算法的最高效率,不會高於KMP演算法的效率。

 

 

5.可以用enum代替string類型。Enum最多可以存65535個字元。但此時排序是按enum值排序而非string值排序。

 

6. datetime 和timestamp的比較。

Datatime:  8位元組,與時區不轉換,預設值是NULL

Timestamp: 4位元組,與時區相關,預設插入值是目前時間。

如果沒有特別需要,建議用timestamp。別用整數型資料來儲存時間,儘管可以,但不推薦,因為得不到任何好處。

 

7.一般不推薦使用bit的資料類型,用tinyint會更利於擴充。Bit set也可以通過tiny int的位元運算來替代。

 

 

8. 不要濫用MySQL的類型自動轉換功能

  

 

查詢最佳化

 

1. 用跨庫動作陳述式,可能導致master和slaver不一致現象

就是對db.table這樣的語句,可能導致master和slaver不一致。

 

2.mysql用於處理串連和釋放串連的效率很高。它被設計成適合簡單快速的查詢方式。因此,如果能將很複雜的查詢分割成多個簡單的查詢,而在應用程式層將這些小查詢串連起來,效率會更高。主要原因是複雜查詢會導致比較大面積的鎖定,影響效率。而多個小查詢鎖的範圍就小很多。而串連的開銷,在mysql中基本可以忽略。

比如:

Select * from tag

Join tag_post on tag_post.tag_id=tag.id

Join post on tag_post.post_id=post.id

Where tag.tag=’mysql’;

拆分成

Select * from tag where tag=’mysql’;

Select * from tag_post where tag_id=1234;

Select * from post where post.id in (123,2343,4545);

如果應用程式層能處理這些資料的拆分和組合,那麼效率會更高。

這樣做的好處:

(1).cache會更有效,不需要中間表暫存資料表的產生。

(2)在應用程式層做組合,更有利於擴充,可以把某些表單獨放在獨立的server上,分開放。

(3)鎖的範圍更小

(4)in的執行效率比join的執行效率高。Mysql的子查詢的效率很低。據說6.0會引入semijoin的計劃來解決。但目前能少用Join還是少用join.

 

 

3. 幾個原則

(1)最佳化更需要最佳化的query

(2) 定位最佳化對象的效能瓶頸,是io還是cpu還是記憶體

(3)明確最佳化目標

(4)從explain入手,可以用force index來檢查走不同索引的效率。SELECT * FROM TABLE1 FORCE INDEX (FIELD1).

(5)開啟profile: 用命令”set profiling”命令。用”show profile”查看概要資訊。其它profile操作這裡不詳細敘述。

 

(6)永遠用曉得結果集去驅動大的結果集

(7)儘可能在索引中完成排序

 

(8)不取多餘的資料

 

(9) 使用最有效過濾條件。

(10)儘可能避免使用複雜的join和子查詢

 

  

4. 查詢語句不要對錶格資料進行操作

比如不要使用select * from tablename where  from_unixtime(operatetime) < xxxxx;

而使用select * from tablename where operatetime < unixtimstamp(xxxxx);

 

 

 

 

表設計最佳化

1. 儲存的資料編碼最好和表的編碼一致。

 

2.根據業務特點合理利用冗餘資料,減少Join查詢。

 

3.合理利用資料類型,能簡單不要複雜,能定長不要變長,能不用字元型就別用字元型。

 

4.索引很重要,合理設計索引。

 

5.將不常用的大欄位單獨拆分出去。某個欄位很大,而且不常用,就不要跟常用的一些資訊儲存在一張表中。

 

  

一些語句

 

(1)Select for update

用於查詢-更新原子操作

(2)LAST_INSERT_ID()

用於保證唯一性,比如訂單編號

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.