一///MySQL
MySQL的複製原理以及流程
基本原理流程,3個線程以及之間的關聯;
1. 主:binlog線程——記錄下全部改變了數據庫數據的語句,放進master上的binlog中;
2. 從:io線程——在使用start slave 以後,負責從master上拉取 binlog 內容,放進 本身的relay log中;
3. 從:sql執行線程——執行relay log中的語句;mysql
MySQL存儲引擎--MyISAM與InnoDB區別
MyISAM: 不支持事務,適合OLAP應用(大量查詢)。
存儲結構:數據文件(.MYD),索引文件(.MYI),結構文件(.frm),特色:能夠在不一樣的服務器上拷貝數據文件和索引文件。
加鎖和併發:加鎖:對整張表進行加鎖,而不是行。併發:在讀數據的時候,全部的表上均可以得到共享鎖(讀鎖),每一個鏈接都不互相干擾。在
寫數據的時候,得到排他鎖,會把整個表進行加鎖,而其餘的鏈接請求(讀,寫請求)都處於等待中。
延遲更新索引。MYISAM 默認把DELAY_KEY_WRITE開啓,(show global variables like '%delay_key%';)整個選項是MYISAM引擎獨有的。 在查詢結束後,不會將索引的改變數據寫入磁盤,而是改變內存中的索引數據。只有在清理緩衝區或關閉表時纔將索引塊轉儲到磁盤。
InnoDB:支持事務和外鍵。
innodb引擎的4大特性 插入緩衝(insert buffer),二次寫(double write),自適應哈希索引(ahi),預讀(read ahead)
區別:
MyISAM類型的表強調的是性能,其執行數度比InnoDB類型更快,可是不提供事務支持,而InnoDB提供事務支持以及外部鍵等高級數據庫功能。
MyISAM不支持事務,而InnoDB支持。InnoDB的AUTOCOMMIT默認是打開的,即每條SQL語句會默認被封裝成一個事務,自動提交,這樣會影響速度,因此最好是把多條SQL語句顯示放在begin和commit之間,組成一個事務去提交。
InnoDB支持數據行鎖定,MyISAM不支持行鎖定,只支持鎖定整個表。即 MyISAM同一個表上的讀鎖和寫鎖是互斥的,MyISAM併發讀寫時若是等待隊列中既有讀請求又有寫請求,默認寫請求的優先級高,即便讀請求先到,因此 MyISAM不適合於有大量查詢和修改並存的狀況,那樣查詢進程會長時間阻塞。由於MyISAM是鎖表,因此某項讀操做比較耗時會使其餘寫進程餓死。
InnoDB支持外鍵,MyISAM不支持。
InnoDB不支持全文索引,而MyISAM支持。全文索引是指對char、 varchar和text中的每一個詞(停用詞除外)創建倒排序索引。MyISAM的全文索引其實沒啥用,由於它不支持中文分詞,必須由使用者分詞後加入空 格再寫到數據表裏,並且少於4個漢字的詞會和停用詞同樣被忽略掉。(SHOW VARIABLES LIKE 'ft_min_word_len' 可修改使用幾個漢字作分詞。)
MyISAM支持GIS數據(空間地圖數據),InnoDB不支持。即MyISAM支持如下空間數據對象:Point,Line,Polygon,Surface等。
沒有where的count(*)使用MyISAM要比InnoDB快得多。因 爲MyISAM內置了一個計數器,count(*)時它直接從計數器中讀,而InnoDB必須掃描全表。因此在InnoDB上執行count(*)時通常 要伴隨where,且where中要包含主鍵之外的索引列。爲何這裏特別強調「主鍵之外」?由於InnoDB中primary index是和raw data存放在一塊兒的,而secondary index則是單獨存放,而後有個指針指向primary key。因此只是count(*)的話使用secondary index掃描更快,而primary key則主要在掃描索引同時要返回raw data時的做用較大。
InnoDB表的行鎖也不是絕對的,若是在執行一個SQL語句時MySQL不能肯定要掃描的範圍,InnoDB表一樣會鎖全表,例如update table set num=1 where name like 「%aaa%」sql
使用MySQL的用戶角度出發,Innodb和MyISAM都是比較喜歡的,可是從我目前運維的數據庫平臺要達到需求:99.9%的穩定性,方便的擴展性和高可用性來講的話,MyISAM絕對是個人首選。
緣由以下:
一、首先我目前平臺上承載的大部分項目是讀多寫少的項目,而MyISAM的讀性能是比Innodb強很多的。
二、MyISAM的索引和數據是分開的,而且索引是有壓縮的,內存使用率就對應提升了很多。能加載更多索引,而Innodb是索引和數據是緊密捆綁的,沒有使用壓縮從而會形成Innodb比MyISAM體積龐大不小。
三、從我接觸的應用邏輯來講,select count(*) 和order by 是最頻繁的,大概能佔了整個sql總語句的60%以上的操做,而這種操做Innodb其實也是會鎖表的,不少人覺得Innodb是行級鎖,那個只是where對它主鍵是有效,非主鍵的都會鎖全表的。
四、還有就是常常有不少應用部門須要我給他們按期某些表的數據,MyISAM的話很方便,只要發給他們對應那表的frm.MYD,MYI的文件,讓他們本身在對應版本的數據庫啓動就行,而Innodb就須要導出xxx.sql了,由於光給別人文件,受字典數據文件的影響,對方是沒法使用的。數據庫
若是須要把日誌紀錄不停的錄入MySQL數據庫,而且天天、每週或者每月都建立一個單一的表,並且要時常進行來自多個表的合計查詢,MERGE(引擎)表這時會很是簡單有效。
Merge表的優勢:
A:分離靜態的和動態的數據
B:利用結構接近的的數據來優化查詢
C:查詢時能夠訪問更少的數據
D:更容易維護大數據集
E: 能夠經過修改.mrg文件來修改Merge表,固然也能夠用alter進行修改,修改後要經過FLUSH TABLES刷新表緩存,此法能夠動態增長減小子表vim
外鍵約束:
create table city( city_id int not null auto_increment,city varchar(50),country_id int not null,primary key(city_id),constraint `fk_city_country` foreign key(country_id) references country(country_id) on delete restrict on update cascade) engine = innodb,ddefault charset=utf8;緩存
restrict+No action: 子表有關聯記錄的時候,不許許更新父表;
cascade : 對父表的更新或者刪除,對子表進行更新或者刪除;
set null:父表更新或者刪除數據的時候,字表相關字段set null ;服務器
key
是數據庫的物理結構,它包含兩層意義,一是約束(偏重於約束和規範數據庫的結構完整性),二是索引(輔助查詢用的)
index是數據庫的物理結構,它只是輔助查詢的,它建立時會在另外的表空間(mysql中的innodb表空間)以一個相似目錄的結構存儲。索引要分類的話,分爲前綴索引、全文本索引等;所以,索引只是索引,它不會去約束索引的字段的行爲。
key的用途:主要是用來加快查詢速度的。
UNIQUE KEY的用途:主要是用來防止數據插入的時候重複的。session
各類引擎對比:
MyISAM:讀和插入爲主,不多更新和刪除;並對事務的完整性,併發性要求不高 ;
InnoDB:事務處理提交和回滾,支持外鍵。插入查詢,更新刪除。相似的計費系統財務系統;
MEMORY:快速定位記錄;
MERGE:突破對單個MyISAM表大小的限制,使用VLDB;併發
臨時表的表結構和數據都是儲存在內存中的,session開始到結束是它的生命週期。
內存表的表結構是存儲到數據庫上的,數據放在內存中,網上推薦使用內存表,但我以爲個人應用場景更合適臨時表。運維
如今設置mysql數據庫也是手動提交事務。方法有兩種:①臨時生效(只對當前客戶端有效),②永久生效
①臨時生效(只對當前客戶端有效)
set @@autocommit=0 (0爲關閉狀態,1爲開啓狀態)
②永久生效(經過修改配置文件參數設置)
經過修改配置文件my.cnf文件,經過vim編輯my.cnf文件,在[mysqld](服務器選項下)添加:
autocommit=0
保存,而後重啓mysql服務便可生效。數據庫設計
針對InnoDB來講(插入數據),影響性能的主要是 innodb_flush_log_at_trx_commit 這個選項,若是設置爲1的話,那麼每次插入數據的時候都會自動提交,致使性能急劇降低,應該是跟刷新日誌有關係,設置爲0效率可以看到明顯提高,固然,同 樣你能夠SQL中提交「SET AUTOCOMMIT = 0」來設置達到好的性能。innodb_buffer_pool_size 提升也有助於提升性能。innodb_buffer_pool_size=2G innodb_buffer_pool_instances=1
Mysql 中 CHAR的長度是固定的,而VARCHAR2的長度是能夠變化的。
VARCHAR2比CHAR節省空間,在效率上比CHAR會稍微差一些,即要想得到效率,就必須犧牲必定的空間,這也就是咱們在數據庫設計上常說的‘以空間換效率’。
對於MyISAM表,儘可能使用Char,對於那些常常須要修改而容易造成碎片的myisam和isam數據表就更是如此,它的缺點就是佔用磁盤空間;
對於InnoDB表,由於它的數據行內部存儲格式對固定長度的數據行和可變長度的數據行不加區分(全部數據行共用一個表頭部分,這個標頭部分存放着指向各有關數據列的指針),因此使用char類型不見得會比使用varchar類型好。事實上,由於char類型一般要比varchar類型佔用更多的空間,因此從減小空間佔用量和減小磁盤i/o的角度,使用varchar類型反而更有利.
1)varchar與char的區別
Varchar存儲可變長字符串,小於255字節時須要1個額外字節(大於255須要2個額外字節)存儲長度,最大長度爲65532字節(全部列總和);
char存儲定長(right padding),讀取時會截斷末尾空格,長度最大爲255字符;
mysql 4.0版本如下,varchar(50), 指的是50字節,若是存放utf8漢字時,只能存放16個(每一個漢字3字節)
mysql 5.0版本以上,varchar(50), 指的是50字符,不管存放的是數字、字母仍是UTF8漢字(每一個漢字3字節),均可以存放50個。
int(M) M表示顯示寬度,最大255. 佔4個字節。
經過explain能夠知道mysql是如何處理語句,分析出查詢或是表結構的性能瓶頸。經過expalin能夠獲得:
1. 表的讀取順序
2.表的讀取操做的操做類型
3.哪些索引可使用
4. 哪些索引被實際使用
5.表之間的引用
6.每張表有多少行被優化器查詢
MYSQL的事務配置項
innodb_flush_log_at_trx_commit=1
表示事務提交時當即把事務日誌寫入磁盤,同時數據和索引也更新。
innodb_flush_log_at_trx_commit=0
事務提交時,不當即把事務日誌寫入磁盤,每隔1秒寫一次
innodb_flush_log_at_trx_commit=2
事務提交時,當即寫入磁盤文件(這裏只是寫入到內核緩衝區,但不當即刷新到磁盤,而是每隔1秒刷新到盤,同時更新數據和索引
mysql使用profile分析語句性能消耗
--查看profile是否開啓 show variables like '%profil%';
set profiling = 1; --關閉則用set profiling = off
--顯示緩存的profile show profiles;
具體的消耗,進行詳細的列出 show profile for query 1; --1是query_id (由show profiles產生。)
查看cpu的消耗狀況 show profile cpu for query 1;
查看內存消耗 show profile memory for query 1;
查看io及cpu的消耗 show profile block io,cpu for query 1;
查看sql1相關的全部分析【主要看i/o與cpu,下邊分析中有各項意義介紹】 show profile ALL for query 1;
(1)、explain出來的各類item的意義;
select_type
表示查詢中每一個select子句的類型
type
表示MySQL在表中找到所需行的方式,又稱「訪問類型」
possible_keys
指出MySQL能使用哪一個索引在表中找到行,查詢涉及到的字段上若存在索引,則該索引將被列出,但不必定被查詢使用
key
顯示MySQL在查詢中實際使用的索引,若沒有使用索引,顯示爲NULL
key_len
表示索引中使用的字節數,可經過該列計算查詢中使用的索引的長度
ref
表示上述表的鏈接匹配條件,即哪些列或常量被用於查找索引列上的值
Extra
包含不適合在其餘列中顯示但十分重要的額外信息
(2)、profile的意義以及使用場景;查詢到 SQL 會執行多少時間, 並看出 CPU/Memory 使用量, 執行過程當中 Systemlock, Table lock 花多少時間等等