1. 程式人生 > >高效能mysql的讀書筆記(一)

高效能mysql的讀書筆記(一)

1、  備份資料庫hive:mysqldump  -uhive  -phive hive  > test.sql 。其中使用者為hive,使用者密碼為hive

2、  備份資料庫的某表,比如test1、test2:mysqldump –uhive  –phive --database hive –table test1 –table test2 >test1_test2.sql

3、  恢復資料庫hive:mysql  –uhive -phive  < test.sql

4、  恢復資料庫中的某張表,比如hive資料庫中的test1表:mysql  -uhive -phive –database hive < test1.sql

5、  Mysql最重要、與眾不同的特性是它的儲存引擎架構,這種架構的設計將查詢處理及其他系統任務和資料的儲存/提取相分離。這種處理和儲存分離的設計可以在使用時根據效能、特性,以及其他需求來選擇資料儲存的方式

6、  對於select語句,在解析查詢之前,伺服器會先檢查查詢快取,如果能夠在其中找到對應的查詢,伺服器就不必再執行查詢解析。優化和執行的整個過程。

7、  在處理併發讀或者寫時,可以通過實現一個由兩種型別的鎖組成的鎖系統來解決問題。這兩種型別的鎖通常被稱為共享鎖和排他鎖,也叫讀鎖和寫鎖

8、  事務就是一組原子性的SQL查詢,或者說一個獨立的工作單元。如果資料庫引擎能夠成功地對資料庫應用該組查詢的全部語句,那麼就執行該組查詢。如果其中有任何一條語句因為崩潰或者其他原因無法執行,那麼所有的語句都不會執行。也就是說,事務內的語句,要麼全部執行成功,要不全部執行失敗。由start transaction語句開始事務,然後要麼使用commit提交事務,要麼使用rollback撤銷所有的修改

9、  ACID表示原子性(atomicity)、一致性(consistency)、隔離性(isolation)和永續性(durability)

10、             SQL定義了四種隔離級別,每一種級別都規定了一個事務中所做的修改,拿些在事務內和事務間是可見的,那些是不可見的。READ UNCOMMITED、READ  COMMITED、REPEATEDREAD、SERIALIZABLE

11、 InnoDB目前處理死鎖的方法是,將持有最少行級排他鎖的事務進行回滾

12、Mysql預設採用自動提交模型(AUTOCOMMIT),也就是說,如果不是顯式地開始一個事務,則每個查詢都被當做一個事務執行提交操作。

13、 通過SET SESSION TRANSACTION ISOLATION  LEVEL  READ COMMITED設計MySQL的隔離級別為READ COMMITED

14、MySQL伺服器層不管理事務,事務是由下層的儲存引擎實現的。所有在同一個事務中,使用多種儲存引擎是不可靠的。InnoDB是事務型的,而MyISAM表是非事務型的。如果事務需要回滾,非事務型的表上的變更就無法撤銷

15、 MVCC多版本併發控制,不同儲存引擎的MVCC實現不同,典型的有樂觀併發控制和悲觀併發控制。MVCC只在REPEATABLE  READ和READ  COMMITTED兩個隔離級別工作。

16、 InnoDB的MVCC是通過在每行記錄後面儲存兩個隱藏的列來實現的。這兩個列,一個是儲存了行的建立時間,一個儲存行的過期時間。當然儲存的並不是實際的時間值,而是系統版本號,每開始一個新的事物,系統版號都會自動遞增。事務開始時刻的系統版本號會作為事務的版本號,用來和查詢到的每行記錄的版本號進行比較

17、表相關資訊的查詢可以通過:show  table  status like  ‘employees’

18、MySQL的預設事務型引擎是InnoDB,它被設計用來處理大量的短期事務,短期事務大部分是正常提交的,很少會被回滾。

19、MySQL 5.1中建議使用InnoDBplugin

20、InnoDB表是基於聚簇索引建立的

21、InnoDB的行為負責,建議讀官方手冊“InnoDB事務模型和鎖”一節

22、 Collation 表示表的預設字元列排序規則

23、MyISAM不支援事務和行級鎖,而且有一個毫無疑問的缺陷是崩潰後無法安全恢復

24、引擎改變,將表從一個引擎修改為另一個引擎最簡單的辦法是使用ALTER  TABLE語句:ALTERTABLE TEST ENGINE = InnoDB;該方法花費的時間久,替代的方法是利用匯出與匯入方法,手工進行表的複製。

25、mysqldump工具將資料匯出到檔案,然後修改檔案中的create  table語句的儲存引擎選項,注意同時修改表名,因為同一個資料庫中不能存在相同的表名,即使它們使用的是不同的儲存引擎。同時mysqldump預設會自動在create  table語句前加上droptable語句。

26、也可以通過建立與查詢來改變表的引擎,create  table  test1 like  test; alter table test2engin=InnoDB;Insert into test1 select * from test。如果資料流不大的話,這樣做工作得很好,但是如果資料量很大,則可以考慮做分批處理。針對每一段資料提交事務操作。Start  transaction; inset intotest1 select * from test where id between x and y; commit;

27、 如果能理解MySQL在儲存引擎和服務層之間處理查詢時如何通過API來回互動,就能抓住MySQL的核心基礎架構精髓

28、 基準測試是MySQL針對系統設計的一種壓力測試

29、可以通過mysql  -uhive  -phive -e,比如mysql  -uhive  -phive -e  ‘show  global variables’執行mysql語句 ,其中使用者為hive,使用者密碼為hive

30、SHOW  PROFILES 。通過SET PROFILING = 1,然後在伺服器上執行的所有語句,都會測量其耗費的時間和其他一些查詢執行狀態變更相關的資料。Show  profile  for query 1;

31、Show status命令返回了一些計數器。既有伺服器級別的全域性計數器,也有基於某個連線的會話級別的計數器。例如執行show  global  status則可以檢視伺服器級別的從伺服器啟動時開始計算的查詢次數統計。最用用的計數器包括控制代碼計數器(handler counter)、臨時檔案和表計數器show status where Variable_name like 'Handler%'

32、 Show  processlist捕獲show  processlist的輸出

33、Show index from test顯示錶test的索引

34、 Mysql資料型別的優化(1)更小的通常更好,應該儘量使用可以正確儲存資料的最小資料型別、(2)簡單就好,簡單資料型別的操作通常需要更小的CPU週期。例如整型比字元操作代價更低,因為字符集和校對規則(排序規則)使字元比較比整型比較更加複雜、(3)儘量避免NULL,通常情況下最好指定列為NOT NULL,除非真的需要儲存NULL值。如果查詢中包括可為NULL的列,對MySQL來說更難優化,因為可為NULL的列使得索引、索引統計和值比較都更加複雜,可為NULL的列被索引時,每個索引記錄需要一個額外的位元組

35、整數型別有:TINYINT、SMALLINT、MEDIUMINT、INT、BIGINT。分別使用8,16,24,32,64位儲存空間。整型型別有可選的unsigned屬性,如TINYINT UNSIGNED

36、DECIMAL型別用於儲存精確的小數。在MySQL5.0和更高的版本,DECIMAL型別執行精確計算。FLOAT 和DOUBLE型別支援使用標準的浮點運算進行近似計算。相對而言,CPU直接支援原生浮點計算,所有浮點運算明顯更快。對於DECIMAL,每四個位元組存9個數字。例如DECIMAL(18,9),小數點兩邊各儲存9個數,一共使用9個位元組,其中有一個是小數點

37、Varchar型別用於儲存可變長字串,它比定長型別更節省空間,但是MySQL表使用ROW_FORMAT=FIXED建立的話,每行都會使用定長儲存。Varchar需要使用1或2個額外位元組記錄字串的長度:如果列的最大長度小於或等於255位元組,則使用一個位元組表示,否則使用2個位元組表示。Varchar省空間,但是在update時可能導致額外花費

38、CHAR型別是定長的:MySQL根據定義的字串長度分配足夠的空間。當儲存CHAR值時,MySQL會刪除所有的末尾空格,(在新版本中VARCHAR也是這樣實現的,也就是說CAHR和VARCHAR在邏輯上是一樣的,區別是儲存格式上),CHAR適合儲存很短的字串,或者所有值都接近一個長度。對於經常變更的資料,CHAR也比VARCHAR在儲存空間上有效率,不易產生碎片

39、 使用列舉:create  table  enum_test(e ENUM(‘fish’,  ‘apple’,  ‘dog’) not null)。列舉有個不好是:當VARCHAR列和ENUM列進行關聯時則慢很多。一個通用設計實踐,在“查詢表”時採用整數主鍵而避免採用基於字串的值進行關聯。

40、MySQL時間:DATETIME 型別儲存大範圍的值,從1001年到9999年,精確到秒,使用八個位元組;TIMESTAMP 型別儲存了從1970年1月1日午夜以來的秒數,只使用4個位元組,只能記錄到2038年時間。通過FROM_UNIXTIME()函式把UNIX的時間戳轉換成日期。並提供了UNIX_TIMESTAMP()函式把日期轉換成Unix時間戳。

41、標識列的型別最好是整型型別,對於標識列EMUN和SET型別通常都是糟糕的選擇,如果可能,應該避免使用字串型別作為標識列,因為它們很消耗空間,並且通常比數字型別慢

42、 MySQL  schema設計中的陷阱:(1)太多的列、(2)太多的關聯,單個查詢最好在12個表以內做關聯

43、MySQL會在索引中儲存NULL值,而Oracle則不會

44、Alter table操作一般會引起表重建,但是並不是所有都是這樣的。例如,有兩種方法可以改變或者刪除一個列的預設值(一個方法快,一個慢)。(一)alter  table  test modify  column  num tinyint(3)  not  null default  5;這個操作直接重建了表,其實列的預設值實際上存在表的.frm檔案中。然而MySQL還沒有采用這種優化,所有modify  column操作都將導致表的重建;(二)通過alter  column操作來改變列的預設值alter  table  test alter  column  num set  default  5;

45、 通過直接修改.frm檔案可以很快對錶的一些性質進行改變,但是要承擔一定的風險。

46、快速建立MyISAM索引,為了高校載入資料到MyISAM,有一個常用的技巧是先禁用索引、載入資料,然後重新啟用索引:alter  table  test disable  keys;  load data;alter  table  test enable  keys;但是這個方法對唯一索引無效(高效能mysql 138頁)

47、索引可以包含一個或多個列的值,如果索引包含多個列,那麼列的順序也十分重要,因為mysql只能高效的使用索引的最左字首列。

48、B-Tree索引的限制:如果不是按照索引的最左列開始查詢,則無法使用索引。

49、索引列的順序會影響搜尋的效率,在優化的時候,可能需要使用相同的列但順序不同的索引來滿足不同型別的查詢需求。

50、索引選擇的指標:不重複的索引值和資料表的記錄總數的比值,範圍從0到1,越大越好,select  count(distinct  left(name,2))/count(*)  from  test;

51、可以通過引數optimizer_switch來關閉索引合併功能。也可以使用ignore index提示讓優化器忽略丟某些索引。這都是除錯索引的方法

52、二級索引需要兩次索引,在於二級索引中儲存的“行指標”的實質,二級索引葉子節點儲存的不是指向行的物理位置的指標,而是行的主鍵值

53、InnoDB 和MYISAM在儲存和索引的表示(PDF高效能mysql  167頁)

54、在InnoDB表中,按主鍵順序插入行,這樣能夠在一般情況下高效工作,但是這樣也有它的缺點,就是在併發工作負載時,因為所有的插入都發生在主鍵的上界,高併發可能會導致間隙鎖競爭。

55、在範圍條件中:對於範圍條件查詢,MySQL無法再使用範圍列後面的其他索引列,但是對於“多個等值條件查詢”則沒有這個限制

56、表的維護,可以通過check  table  test來找出大多數的表和索引的錯誤。在MyISAM中,可以通過repair  table test來修復它們。在InnoDB中,如果遇到資料損壞,最重要是找出損壞的原因,否則很有可能不斷地損壞。可以通過innodb_force_recovery引數進入InnoDB的強制恢復模式修復資料。

57、InnoDB在開啟某些INFORMATION_SCHEMA表,或者使用show  table status  和show  index ,抑或在MySQL客戶端開始自動補全功能的時候都會觸發索引統計資訊的更新,影響效能。可以通過關閉innodb_stats_on_metadata引數來避免。

58、查詢效能低下最基礎的原因是訪問的資料太多了。

59、可以通過explain來了解mysql語句的執行過程的情況,如  explain select* from test。在explain語句中的type列反應了訪問型別。訪問型別有很多種,從全表掃描到索引掃描、範圍掃描、唯一索引查詢、常數引用等。它們的速度是從慢到快

60、在進行關聯查詢的時候,如:select  test.*,  test1.*, test2.*  from  test inner join  test1  using(num) inner  join  using (name)  ,mysql的優化器會優化我們的關聯順序。但是有時候優化器並不是最優的關聯順序,這時候,我們可以使用STRAIGHT_JOIN關鍵字重寫查詢,讓優化器按照你認為最優的關聯順序執行(一般不推薦)

61、當需要關聯的表超過optimizer_search_depth的限制的時候,就會選擇“貪婪”搜尋模式

62、 Mysql的子查詢實現得非常糟糕。最糟糕的一類查詢是WHERE條件中包含IN()的子查詢語句。比如select  *   from film  where  film_id in  (select  film_id from  film_actor  where actor_id  =  1);Mysql的優化是:select  * from film  where  exists (select  * from  film_actor  where actor_id  =  1 and  film_actor.film_id  = film.film.film_id)。改進查詢:select  file.*  from film  inner join  film_actor using(film_id)  where  actor =  1;

63、分割槽CREATE TABLE sales (
    id INT AUTO_INCREMENT,
    amount DOUBLE NOT NULL,
    order_day DATETIME NOT NULL,
    PRIMARY KEY(id, order_day)
) ENGINE=Innodb PARTITION BYRANGE(YEAR(order_day)) (
    PARTITION p_2010 VALUES LESS THAN(2010),
    PARTITION p_2011 VALUES LESS THAN(2011),
    PARTITION p_2012 VALUES LESS THAN(2012),
    PARTITION p_catchall VALUES LESSTHAN MAXVALUE);

64、Explain partitions select *from  test;通過explain來顯示查詢所用到的分割槽。MySQL在使用分割槽函式的列本身進行比較才能過濾分割槽,而不是根據表示式的值去過濾分割槽。

Explain partition  select  * from test  where  Year(day)=2010\G;

65、查詢快取:MySQL在某些場景下直接快取完整的SELECT查詢結構,也就是“查詢快取”。

66、伺服器調優中,InnoDB最重要的選項是:innodb_buffer_pool_size和innodb_log_file_size.。innodb_log_buffer_size表示InnoDB寫入到磁碟上的日誌檔案時使用的緩衝區的位元組數,預設值為8M。一個大的日誌緩衝區允許大量的事務在提交之前不寫日誌到磁碟。因此,如果你有很多事務的更新,插入或刪除很操作,通過這個引數會大量的節省了磁碟I / O。innodb_log_file_size表示在一個日誌組每個日誌檔案的位元組大小。日誌檔案的總大小(innodb_log_file_size* innodb_log_files_in_group)。innodb_buffer_pool_size引數表示緩衝池位元組大小,InnoDB快取表和索引資料的記憶體區域