insert into select 优化_数据库优化总结
第一部分:SQL語句優化
1、盡量避免使用select *,使用具體的字段代替*,只返回使用到的字段。
2、盡量避免使用in 和not in,會導致數據庫引擎放棄索引進行全表掃描。
SELECT * FROM t WHERE id IN (2,3)SELECT * FROM t1 WHERE username IN (SELECT username FROM t2)優化方式:如果是連續數值,可以用between代替。如下:
SELECT * FROM t WHERE id BETWEEN 2 AND 3如果是子查詢,可以用exists代替。如下:
SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t2 WHERE t1.username = t2.username)3、盡量避免在字段開頭模糊查詢,會導致數據庫引擎放棄索引進行全表掃描。如下:
SELECT * FROM t WHERE username LIKE '%li%'優化方式:盡量在字段后面使用模糊查詢。如下:
SELECT * FROM t WHERE username LIKE 'li%'4、盡量避免進行null值的判斷,會導致數據庫引擎放棄索引進行全表掃描。如下:
SELECT * FROM t WHERE score IS NULL優化方式:可以給字段添加默認值0,對0值進行判斷。如下:
SELECT * FROM t WHERE score = 05、盡量避免在where條件中等號的左側進行表達式、函數操作,會導致數據庫引擎放棄索引進行全表掃描。如下:
SELECT * FROM t2 WHERE score/10 = 9SELECT * FROM t2 WHERE SUBSTR(username,1,2) = 'li'優化方式:可以將表達式、函數操作移動到等號右側。如下:
SELECT * FROM t2 WHERE score = 10*9SELECT * FROM t2 WHERE username LIKE 'li%'6.當只要一行數據時使用LIMIT 1
加上LIMIT 1可以增加性能。MySQL數據庫引擎會在查找到一條數據后停止搜索,而不是繼續往后查詢下一條符合條件的數據記錄
7、使用連接(JOIN)來代替子查詢(Sub-Queries)
8、在建有索引的字段上盡量不要使用函數進行操作
例如,在一個DATE類型的字段上使用YEAE()函數時,將會使索引不能發揮應有的作用。
9、排序的索引問題
mysql查詢只使用一個索引,因此如果where子句中已經使用了索引的話,那么order by中的列是不會使用索引的。因此數據庫默認排序可以符合要求的情況下不要使用排序操作;盡量不要包含多個列的排序,如果需要最好給這些列創建復合索引。
10、應盡量避免在 where 子句中使用 != 或 <> 操作符,否則將引擎放棄使用索引而進行全表掃描。
11、應盡量避免在 where 子句中使用 or 來連接條件,如果一個字段有索引,一個字段沒有索引,將導致引擎放棄使用索引而進行全表掃描,如:
select id from t where num=10 or Name = 'admin'可以這樣查詢:
select id from t where num = 10union allselect id from t where Name = 'admin'12、索引應建立在那些將用于JOIN,WHERE判斷和ORDERBY排序的字段上。盡量不要對數據庫中某個含有大量重復的值的字段建立索引。
比如性別可能就只有兩個值,建索引不僅沒什么優勢,還會影響到更新速度,這被稱為過度索引。
第二部分:數據庫索引
1、索引的創建、查看、刪除
//創建索引有兩種方式:1.CREATE TABLE語句時可以創建索引 2.單獨用CREATE INDEX或ALTER TABLE來為表增加索引//?1、ALTER?TABLE?用來創建普通索引、唯一索引、主鍵索引和全文索引ALTER TABLE table_name ADD INDEX index_name (column_list);ALTER TABLE table_name ADD UNIQUE (column_list);ALTER TABLE table_name ADD PRIMARY KEY (column_list);ALTER TABLE table_name ADD FULLTEXT (column_list);//?2、CREATE?INDEX可對表增加普通索引或UNIQUE索引以及全文索引,但是不可以對表增加主鍵索引CREATE INDEX index_name ON table_name (column_list);CREATE UNIQUE index_name ON table_name (column_list);CREATE?FULLTEXT?index_name?ON?table_name?(column_list);查看索引mysql> show index from tblname;mysql> show keys from tblname;刪除索引刪除索引的mysql格式 :DORP INDEX IndexName ON tab_name;2、使用索引的優缺點
創建索引可以大大提高系統的性能,?可以大大加快數據的檢索速度。
索引并不是越多越好,索引固然可以提高相應的 select 的效率,但同時也降低了 insert 及 update 的效率,因為 insert 或 update 時有可能會重建索引,所以怎樣建索引需要慎重考慮,視具體情況而定。一個表的索引數最好不要超過6個,若太多則應考慮一些不常使用到的列上建的索引是否有 必要。
第一,?? 創建索引和維護索引要耗費時間,這種時間隨著數據量的增加而增加。第二,?? 索引需要占物理空間,除了數據表占數據空間之外,每一個索引還要占一定的物理空間,如果要建立聚簇索引,那么需要的空間就會更大。第三,?? 當對表中的數據進行增加、刪除和修改的時候,索引也要動態的維護,這樣就降低了數據的維護速度。
一般來說,應該在這些列上創建索引。第一,?? 在經常需要搜索的列上,可以加快搜索的速度;第二,?? 在作為主鍵的列上,強制該列的唯一性和組織表中數據的排列結構;第三,?? 在經常用在連接的列上,這些列主要是一些外鍵,可以加快連接的速度;第四,?? 在經常需要根據范圍進行搜索的列上創建索引,因為索引已經排序,其指定的范圍是連續的;第五,?? 在經常需要排序的列上創建索引,因為索引已經排序,這樣查詢可以利用索引的排序,加快排序查詢時間;第六,?? 在經常使用在WHERE子句中的列上面創建索引,加快條件的判斷速度。
一般來說,不應該創建索引的的這些列具有下列特點:第一,在查詢中很少使用列不應該創建索引。第二,對于只有很少數據值的列也不應該增加索引。這是因為,由于這些列的取值很少,例如人事表的性別列,在查詢的結果中,結果集的數據行占了表中數據行的很大比例,即需要在表中搜索的數據行的比例很大。增加索引,并不能明顯加快檢索速度。第三,對于那些定義為text, image和bit數據類型的列不應該增加索引。這是因為,這些列的數據量要么相當大,要么取值很少。第四,當修改性能遠遠大于檢索性能時,不應該創建索引。這是因為,修改性能和檢索性能是互相矛盾的。當增加索引時,會提高檢索性能,但是會降低修改性能。當減少索引時,會提高修改性能,降低檢索性能。因此,當修改性能遠遠大于檢索性能時,不應該創建索引。
3、組合索引
????組合索引的生效原則是? 從前往后依次使用生效,如果中間某個索引沒有使用,那么斷點前面的索引部分起作用,斷點后面的索引沒有起作用;
造成斷點的原因:
????前邊的任意一個索引沒有參與查詢,后邊的全部不生效。
????前邊的任意一個索引字段參與的是范圍查詢,后面的不會生效。
????斷點跟索引字字段在SQL語句中的位置前后無關,只與是否存在有關。
where a=3 and b=45 and c=5 .... #這種三個索引順序使用中間沒有斷點,全部發揮作用;where a=3 and c=5... #這種情況下b就是斷點,a發揮了效果,c沒有效果where b=3 and c=4... #這種情況下a就是斷點,在a后面的索引都沒有發揮作用,這種寫法聯合索引沒有發揮任何效果;where?b=45?and?a=3?and?c=5?....?#這個跟第一個一樣,全部發揮作用,abc只要用上了就行,跟寫的順序無關?
(a,b,c) 三個列上加了聯合索引(是聯合索引 不是在每個列上單獨加索引)而是建立了a,(a,b),(a,b,c)三個索引,另外(a,b,c)多列索引和 (a,c,b)是不一樣的。
(0) select * from mytable where a=3 and b=5 and c=4;#abc三個索引都在where條件里面用到了,而且都發揮了作用(1) select * from mytable where c=4 and b=6 and a=3;#這條語句為了說明 組合索引與在SQL中的位置先后無關,where里面的條件順序在查詢之前會被mysql自動優化,效果跟上一句一樣(2) select * from mytable where a=3 and c=7;#a用到索引,b沒有用,所以c是沒有用到索引效果的(3) select * from mytable where a=3 and b>7 and c=3;#a用到了,b也用到了,c沒有用到,這個地方b是范圍值,也算斷點,只不過自身用到了索引(4) select * from mytable where b=3 and c=4;#因為a索引沒有使用,所以這里 bc都沒有用上索引效果(5) select * from mytable where a>4 and b=7 and c=9;#a用到了??b沒有使用,c沒有使用(a使用的是范圍查詢)(6) select * from mytable where a=3 order by b;#a用到了索引,b在結果排序中也用到了索引的效果,前面說了,a下面任意一段的b是排好序的(7) select * from mytable where a=3 order by c;#a用到了索引,但是這個地方c沒有發揮排序效果,因為中間斷點了,使用 explain 可以看到 filesort(8) select * from mytable where b=3 order by a;#b沒有用到索引,排序中a也沒有發揮索引效果?
在查詢時,MYSQL只能使用一個索引,如果建立的是多個單列的普通索引,在查詢時會根據查詢的索引字段,從中選擇一個限制最嚴格的單例索引進行查詢。別的索引都不會生效。
第三部分:MySQL優化:explain分析
Explain是Mysql的自帶查詢優化器,負責select語句的優化器模塊,可以模擬優化器執行SQL查詢語句,從而知道Mysql是如何處理SQL的,語法也很簡單:Explain + SQL
1、id:反映的是表的讀取的順序,或查詢中執行select子句的順序。
小表永遠驅動大表,三種情況:
(1)id相同,執行順序是由上至下的
(2)id不同,如果是子查詢,id序號會遞增,id值越大優先級越高,越先被執行
(3)id存在相同的,也存在不同的,所有組中,id越大越先執行,如果id相同的,從上往下順序執行
derived是衍生虛表的意思,derived2中的2對應id2
2、select_type:反映的是Mysql理解的查詢類型
(1)simple:簡單的select查詢,查詢中不包含子查詢或union。
(2)primary:查詢中若包含任何復雜的字部分,最外層查詢標記為primary。
(3)subquery:select或where列表中的子查詢。
(4)derived(衍生):在from列表中包含的子查詢,Mysql會遞歸執行這些子查詢,把結果放在臨時表里。
(5)union:若第二個select出現在union后,則被標記為union,若union包含在from字句的子查詢中,外層select將被標記為derived
(6)union result:union后的結果集
3、table:反映這一行數據是關于哪張表的
4、type:訪問類型排序
反映sql優化的狀態,至少達到range級別,最好能達到ref
查詢效率:system > const > eq_ref > ref > range > index > all
(完整的排序:system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index >all)
(1)system:從單表只查出一行記錄(等于系統表),這是const類型的特例,一般不會出現
(2)const:查詢條件用到了常量,通過索引一次就找到,常在使用primary key或unique索引中出現。
?
where id=1寫死,所以類型是const
(3)eq_ref:唯一性索引掃描,對于每個索引鍵,表中只有一條記錄與之匹配,常見于主鍵或唯一索引掃描。
(4)ref:非唯一性索引掃描,返回匹配某個單獨值的所有行,本質上也是一種索引訪問,它可能會找到多個符合條件的行,與eq_ref的差別是eq_ref只匹配了一條記錄。
(5)range:只檢索給定范圍的行,使用一個索引來選擇行。key列顯示使用了哪個索引,一般是在where語句中出現了between、、in等的查詢。
? 這種范圍掃描索引掃描比全表掃描要好,因為它只需要開始于索引的某一點,而結束于另一點,不用掃描全部索引。與eq_ref和ref的區別在于篩選條件不是固定值,是范圍。
(6)index:full Index scan,index和all的區別為index類型只遍歷索引樹。這通常比all快,因為索引文件通常比數據文件小。
要獲得的id信息,剛好id在索引上,從索引中讀取
? (all和index都是讀全表,但index是從索引中讀取的,而all是從硬盤中讀的)
(7)all:全表掃描,如果查詢數據量很大時,全表掃描效率是很低的。
5、possible_keys、key、key_len:反映實際用到了哪個索引,索引是否失效
(1)possible_keys:Mysql推測可能用到的索引有哪些,但不一定被查詢實際使用
(2)key:實際使用的索引,若為null,則可能沒建索引或索引失效。
??
(查詢中若使用了覆蓋索引,則該索引僅出現在key列表中。
覆蓋索引:select后面的字段和所建索引的個數、順序一致)
(3)key_len:表示索引中使用的字節數,可通過該列計算查詢中使用的索引的長度。同樣的查詢結果下,長度越短越好。
?? key_len顯示的值為索引字段的最大可能長度,并非實際使用長度,即key_len是根據表定義計算而得,不是通過表內檢索出的。
6、ref:反映哪些列或常量被用于查找索引列上的值
?
7、rows:根據表統計信息及索引選用情況,大致估算出找到所需的記錄所需要讀取的行數
僅通過主鍵索引查找是641行
?
建完相關的復合索引再查,需要查詢的行數就變少了
8、Extra
(1)using filesort:mysql中無法利用索引完成的排序,這時會對數據使用一個外部的索引排序,而不是按照表內的索引順序進行讀取。
?
創建索引時就會對數據先進行排序,出現using filesort一般是因為order by后的條件導致索引失效,最好進行優化。
?
order by的排序最好和所建索引的順序和個數一致
(2)using temporary:使用了臨時表保存中間結果,mysql在對查詢結果排序時使用臨時表。常見于排序order by和分組查詢group by。
?
影響更大,所以要么不建索引,要么group by的順序要和索引一致
?
(3)using index:表示相應的select操作中使用了覆蓋索引,避免訪問了表的數據行,效率好
覆蓋索引:select后的數據列只從索引就能取得,不必讀取數據行,且與所建索引的個數(查詢列小于等于索引個數)、順序一致。
所以如果要用覆蓋索引,就要注意select的列只取需要用到的列,不用select *,同時如果將所有字段一起做索引會導致索引文件過大,性能會下降。
出現using where,表明索引被用來執行索引鍵值的查找
?
如果沒有同時出現using where,表明索引用來讀取數據而非執行查找動作。
(4)using where:表明使用了where過濾
(5)using join buffer:使用了連接緩存
(6)impossible where:where子句的值是false
(7)select tables optimized away
(8)distinct:優化distinct操作,在找到第一匹配的元組后即停止找同樣值的動作
第四部分:數據庫性能優化
一方面可以單臺運行多個MySQL實例讓服務器性能發揮到最大化,另一方面是對數據庫進行優化,往往操作系統和數據庫默認配置都比較保守,會對數據庫發揮有一定限制,可對這些配置進行適當的調整。
4.1 數據庫配置優化
MySQL常用有兩種存儲引擎,一個是MyISAM,不支持事務處理,讀性能處理快,表級別鎖。另一個是InnoDB,支持事務處理(ACID),設計目標是為處理大容量數據發揮最大化性能,行級別鎖。
? 表鎖:開銷小,鎖定粒度大,發生死鎖概率高,相對并發也低。
? 行鎖:開銷大,鎖定粒度小,發生死鎖概率低,相對并發也高。
使用InnoDB存儲引擎是最好的選擇。
?InnoDB參數默認值:
innodb_buffer_pool_size = 128M#索引和數據緩沖區大小,一般設置物理內存的60%-70%innodb_buffer_pool_instances = 1 #緩沖池實例個數,推薦設置4個或8個innodb_flush_log_at_trx_commit = 1 #關鍵參數,0代表大約每秒寫入到日志并同步到磁盤,數據庫故障會丟失1秒左右事務數據。1為每執行一條SQL后寫入到日志并同步到磁盤,I/O開銷大,執行完SQL要等待日志讀寫,效率低。2代表只把日志寫入到系統緩存區,再每秒同步到磁盤,效率很高,如果服務器故障,才會丟失事務數據。對數據安全性要求不是很高的推薦設置2,性能高,修改后效果明顯。innodb_file_per_table = OFF #默認是共享表空間,共享表空間idbdata文件不斷增大,影響一定的I/O性能。推薦開啟獨立表空間模式,每個表的索引和數據都存在自己獨立的表空間中,可以實現單表在不同數據庫中移動。innodb_log_buffer_size = 8M#日志緩沖區大小,由于日志最長每秒鐘刷新一次,所以一般不用超過16M?4.2 系統內核優化
? 大多數MySQL都部署在linux系統上,所以操作系統的一些參數也會影響到MySQL性能,以下對linux內核進行適當優化。
net.ipv4.tcp_fin_timeout = 30#TIME_WAIT超時時間,默認是60snet.ipv4.tcp_tw_reuse = 1 #1表示開啟復用,允許TIME_WAIT socket重新用于新的TCP連接,0表示關閉net.ipv4.tcp_tw_recycle = 1 #1表示開啟TIME_WAIT socket快速回收,0表示關閉net.ipv4.tcp_max_tw_buckets = 4096 #系統保持TIME_WAIT socket最大數量,如果超出這個數,系統將隨機清除一些TIME_WAIT并打印警告信息net.ipv4.tcp_max_syn_backlog = 4096#進入SYN隊列最大長度,加大隊列長度可容納更多的等待連接在linux系統中,如果進程打開的文件句柄數量超過系統默認值1024,就會提示“too many files open”信息,所以要調整打開文件句柄限制。
# vi /etc/security/limits.conf #加入以下配置,*代表所有用戶,也可以指定用戶,重啟系統生效* soft nofile 65535* hard nofile 65535# ulimit -SHn 65535 #立刻生效4.3 硬件配置
? 加大物理內存,提高文件系統性能。linux內核會從內存中分配出緩存區(系統緩存和數據緩存)來存放熱數據,通過文件系統延遲寫入機制,等滿足條件時(如緩存區大小到達一定百分比或者執行sync命令)才會同步到磁盤。也就是說物理內存越大,分配緩存區越大,緩存數據越多。當然,服務器故障會丟失一定的緩存數據。
? SSD硬盤代替SAS硬盤,將RAID級別調整為RAID1+0,相對于RAID1和RAID5有更好的讀寫性能(IOPS),畢竟數據庫的壓力主要來自磁盤I/O方面。
第五部分:數據庫架構擴展
5.1 主從復制
分為同步復制和異步復制,實際復制架構中大部分為異步復制。復制的基本過程如下:
1)Slave上面的IO進程連接上Master,并請求從指定日志文件的指定位置(或者從最開始的日志)之后的日志內容;
2)Master接收到來自Slave的IO進程的請求后,通過負責復制的IO進程根據請求信息讀取制定日志指定位置之后的日志信息,返回給Slave 的IO進程。返回信息中除了日志所包含的信息之外,還包括本次返回的信息已經到Master端的bin-log文件的名稱以及bin-log的位置;?
3)Slave的IO進程接收到信息后,將接收到的日志內容依次添加到Slave端的relay-log文件的最末端,并將讀取到的Master端的 bin-log的文件名和位置記錄到master-info文件中,以便在下一次讀取的時候能夠清楚的告訴Master“我需要從某個bin-log的哪個位置開始往后的日志內容,請發給我”;?
4)Slave的Sql進程檢測到relay-log中新增加了內容后,會馬上解析relay-log的內容成為在Master端真實執行時候的那些可執行的內容,并在自身執行。
主要搭建配置步驟:
? ? (1)修改master,slave服務器
vi /usr/local/mysql/etc/my.cnf
[mysqld]
server-id=202 #設置服務器唯一的id,默認是1,我們設置ip最后一段,slave設置203
log-bin=mysql-bin # 啟用二進制日志
#binlog-ignore-db = mysql,information_schema #忽略寫入binlog的庫
slave服務器配置:
vi /usr/local/mysql/etc/my.cnf
[mysqld]
server-id=203
replicate-do-db = abc #只同步abc庫
slave-skip-errors = all #忽略因復制出現的所有錯誤
(2)在主服務器上建立帳戶并授權slave
? ? (3)配置從數據庫
mysql>?change?master?to?->?master_host='192.168.0.202',
?->?master_user='sync',
?->?master_password='1234.com',
?->?master_log_file='mysql-bin.000002',
?->?master_log_pos=263;
#Log和pos是master上隨機獲取的。這段也可以寫到my.cnf里面。
? ? (4)啟動slave同步進程并查看狀態
mysql> start slave;????
其中Slave_IO_Running 與 Slave_SQL_Running 的值都必須為YES,才表明狀態正常。
? (5)查看主數據庫狀態
mysql> show master status;+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000002 | 263 | | |
+------------------+----------+--------------+------------------+
(6)驗證主從同步
在主mysql創建數據庫abc,再從mysql查看已經同步成功。
5.2??MySQL Proxy 實現讀寫分離
大多數企業是在代碼層面實現讀寫分離,另一個種方式通過代理程序實現讀寫分離,常見代理程序有MySQL Proxy、Amoeba。在這樣數據庫集群架構中,大大增加數據庫高并發能力,解決單臺性能瓶頸問題。如果從數據庫一臺從庫能處理2000 QPS,那么5臺就能處理1w QPS。
基本原理是讓主數據庫處理寫方面事務,讓從庫處理SELECT查詢。
主服務器Master:192.168.0.202
從服務器Slave:192.168.0.203
調度服務器MySQL-Proxy:192.168.0.204
(1)安裝mysql-proxy
????下載:http://dev.mysql.com/downloads/mysql-proxy/
(2)配置mysql-proxy,創建主配置文件
cd /usr/local/mysql-proxymkdir lua #創建腳本存放目錄mkdir logs #創建日志目錄cp share/doc/mysql-proxy/rw-splitting.lua ./lua #復制讀寫分離配置文件cp share/doc/mysql-proxy/admin-sql.lua ./lua #復制管理腳本vi /etc/mysql-proxy.cnf #創建配置文件[mysql-proxy]user=root #運行mysql-proxy用戶admin-username=proxy #主從mysql共有的用戶admin-password=123.com #用戶的密碼proxy-address=192.168.0.204:4000 #mysql-proxy運行ip和端口,不加端口,默認4040proxy-read-only-backend-addresses=192.168.0.203 #指定后端從slave讀取數據proxy-backend-addresses=192.168.0.202 #指定后端主master寫入數據proxy-lua-script=/usr/local/mysql-proxy/lua/rw-splitting.lua #指定讀寫分離配置文件位置admin-lua-script=/usr/local/mysql-proxy/lua/admin-sql.lua #指定管理腳本log-file=/usr/local/mysql-proxy/logs/mysql-proxy.log #日志位置log-level=info #定義log日志級別,由高到低分別有(error|warning|info|message|debug)daemon=true #以守護進程方式運行keepalive=true #mysql-proxy崩潰時,嘗試重啟保存退出!chmod 660 /etc/mysql-porxy.cnf(3)修改讀寫分離配置文件
vi /usr/local/mysql-proxy/lua/rw-splitting.luaif not proxy.global.config.rwsplit then proxy.global.config.rwsplit = {??min_idle_connections?=?4,?#默認超過4個連接數時,才開始讀寫分離 max_idle_connections = 8, #默認8 is_debug = false }end(4)啟動mysql-proxy
/usr/local/mysql-proxy/bin/mysql-proxy --defaults-file=/etc/mysql-proxy.cnfnetstat -tupln | grep 4000 #已經啟動tcp 0 0 192.168.0.204:4000 0.0.0.0:* LISTEN 1264/mysql-proxy關閉mysql-proxy使用:killall -9 mysql-proxy(5)在主服務器創建proxy用戶用于mysql-proxy使用,從服務器也會同步這個操作
mysql> grant all on *.* to 'proxy'@'192.168.0.204' identified by '123.com';(6)測試讀寫分離
????使用客戶端連接mysql-proxy
mysql -u proxy -h 192.168.0.204 -P 4000 -p123.com5.3?MySQL-MMM 實現主主復制
有時,面對大量寫操作的應用時,單臺寫性能達不到業務需求。如果做雙主,就會遇到數據庫數據不一致現象,產生這個原因是在應用程序不同的用戶會有可能操作兩臺數據庫,同時的更新操作造成兩臺數據庫數據庫數據發生沖突或者不一致。在單庫時MySQL利用存儲引擎機制表鎖和行鎖來保證數據完整性,怎樣在多臺主庫時解決這個問題呢?有一套基于perl語言開發的主從復制管理工具,叫MySQL-MMM(Master-Master replication managerfor Mysql,Mysql主主復制管理器),這個工具最大的優點是在同一時間只提供一臺數據庫寫操作,有效保證數據一致性。
mmm_mond:監控進程,負責所有的監控工作,決定和處理所有節點角色活動。此腳本需要在監管機上運行。
mmm_agentd:運行在每個mysql服務器上的代理進程,完成監控的探針工作和執行簡單的遠端服務設置。此腳本需要在被監管機上運行。
mmm_control:一個簡單的腳本,提供管理mmm_mond進程的命令。
mysql-mmm的監管端會提供多個虛擬IP(VIP),包括一個可寫VIP,多個可讀VIP,通過監管的管理,這些IP會綁定在可用mysql之上,當某一臺mysql宕機時,監管會將VIP遷移至其他mysql。
在整個監管過程中,需要在mysql中添加相關授權用戶,以便讓mysql可以支持監理機的維護。授權的用戶包括一個mmm_monitor用戶和一個mmm_agent用戶,如果想使用mmm的備份工具則還要添加一個mmm_tools用戶。
5.4?增加緩存
?給數據庫增加緩存系統,把熱數據緩存到內存中,如果緩存中有要請求的數據就不再去數據庫中返回結果,提高讀性能。緩存實現有本地緩存和分布式緩存,本地緩存是將數據緩存到本地服務器內存中或者文件中。分布式緩存可以緩存海量數據,擴展性好,主流的分布式緩存系統有memcached、redis,memcached性能穩定,數據緩存在內存中,速度很快,QPS可達8w左右。如果想數據持久化就選擇用redis,性能不低于memcached。
5.5 分庫
? 分庫是根據業務不同把相關的表切分到不同的數據庫中,比如web、bbs、blog等庫。如果業務量很大,還可將切分后的庫做主從架構,進一步避免單個庫壓力過大。
5.6 分表
? 數據量的日劇增加,數據庫中某個表有幾百萬條數據,導致查詢和插入耗時太長,怎么能解決單表壓力呢?你就該考慮是否把這個表拆分成多個小表,來減輕單個表的壓力,提高處理效率,此方式稱為分表。
? 分表技術比較麻煩,要修改程序代碼里的SQL語句,還要手動去創建其他表,也可以用merge存儲引擎實現分表,相對簡單許多。分表后,程序是對一個總表進行操作,這個總表不存放數據,只有一些分表的關系,以及更新數據的方式,總表會根據不同的查詢,將壓力分到不同的小表上,因此提高并發能力和磁盤I/O性能。
??分表分為垂直拆分和水平拆分:
? 垂直拆分:把原來的一個很多字段的表拆分多個表,解決表的寬度問題。你可以把不常用的字段單獨放到一個表中,也可以把大字段獨立放一個表中,或者把關聯密切的字段放一個表中。
? 水平拆分:把原來一個表拆分成多個表,每個表的結構都一樣,解決單表數據量大的問題。
第六部分:開啟慢查詢日志
一旦開啟慢日志查詢會增加數據庫的壓力。
mysql> set global slow-query-log=on #開啟慢查詢功能mysql> set global slow_query_log_file='/var/log/mysql/mysql-slow.log'; #指定慢查詢日志文件位置mysql> set global log_queries_not_using_indexes=on; #記錄沒有使用索引的查詢mysql> set global long_query_time=1; #只記錄處理時間1s以上的慢查詢第七部分:數據庫備份
總結
以上是生活随笔為你收集整理的insert into select 优化_数据库优化总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: new出来的对象怎么回收_JVM的内存模
- 下一篇: html玫瑰花效果代码,html5渲染3