mysql 性能優化索引、緩存、分表、分布式實現方式。


系統針對5000台終端測試結果

索引

目標:優化查詢速度3秒以內 需要優化。盡量避免使用select * 來查詢對象。使用到哪些屬性值就查詢出哪些使用即可

首頁頁面:

設備-組織查詢 優化 避免使用select * 來查詢device對象 優化前耗時 200毫秒 優化后耗時19毫秒

設備-在線 優化 避免使用select * 來查詢device對象 優化前耗時 210毫秒 優化后耗時11毫秒

設備-版本 優化 避免使用select * 來查詢device對象 優化前耗時 230毫秒 優化后耗時10毫秒

 

終端檢查報告頁面:

查看報告詳細報告 優化前耗時3603毫秒 優化后耗1103毫秒

優化方式:

1:ccp_infraction 建立聯合索引 checkItemId和reportId

create index ccp_infraction_index on  ccp_infraction (reportId,checkItemId) ;

 

查看報告所有結果和人工判定 優化前耗時10300毫秒 優化后耗時1973毫秒

優化方式:添加聯系索引

create index idx_1 on ccp_artificial (reportId,isInfraction);

create index idx_2 on ccp_terminalinfo(reportId);

create index idx_3 on ccp_currenttimerep(reportId);

create index idx_4 on ccp_hostrep (reportId);

create index idx_5 on ccp_currentaccountrep(reportId);

create index idx_6 on ccp_accountrep(reportId,isInfraction);

create index idx_7 on ccp_hardwarerep(reportId,isInfraction);

create index idx_8 on ccp_networkrep (reportId);

create index idx_9 on ccp_softwarerep(reportId,isInfraction);

create index idx_10 on ccp_diskrep (reportId,isInfraction);

create index idx_11 on ccp_partitioninforep(reportId);

create index idx_12 on ccp_oneKeyInforep(reportId,isInfraction);

create index idx_13 on ccp_usbinforep(reportId,isInfraction);

create index idx_14 on ccp_printerrep (reportId,isInfraction);

create index idx_15 on ccp_cdromrep(reportId,isInfraction);

create index idx_16 on ccp_wpdrep (reportId);

create index idx_17 on ccp_usedNetSoftWarerep(reportId,isInfraction);

create index idx_18 on ccp_dialingrep(reportId,isInfraction);

create index idx_19 on ccp_browserrep(reportId,isInfraction);

create index idx_20 on ccp_emailrep(reportId,isInfraction);

create index idx_21 on ccp_downloadrep(reportId,isInfraction);

create index idx_22 on ccp_imrep(reportId,isInfraction);

create index idx_23 on ccp_cloudDiskInforep(reportId,isInfraction);

create index idx_24 on ccp_sharefolderrep(reportId,isInfraction);

create index idx_25 on ccp_secsoftwarerep(reportId,isInfraction);

create index idx_26 on ccp_patchrep (reportId);

create index idx_27 on ccp_noPatchRep(reportId,isInfraction);

create index idx_28 on ccp_securitymanagementrep(reportId,isInfraction);

create index idx_29 on ccp_osrep(reportId,isInfraction);

create index idx_30 on ccp_vmwarerep(reportId,isInfraction);

create index idx_31 on ccp_wirelessrep(reportId,isInfraction);

create index idx_32 on ccp_monitorProtectrep(reportId,isInfraction);

create index idx_33 on ccp_firewarerep(reportId,isInfraction);

create index idx_34 on ccp_remoteInfo(reportId);

create index idx_35 on ccp_autoPlay(reportId,isInfraction);

create index idx_36 on ccp_autoUpdate(reportId,isInfraction);

create index idx_37 on ccp_portinforep(reportId,isInfraction);

create index idx_38 on ccp_procedurerep(reportId,isInfraction);

create index idx_39 on ccp_servicerep(reportId,isInfraction);

create index idx_40 on ccp_systemlogrep(reportId,isInfraction);

create index idx_41 on ccp_poweronandoffrep(reportId);

create index idx_42 on ccp_accountsecurityrep(reportId,isInfraction);

create index idx_43 on ccp_pwandacpolicyrep(reportId,isInfraction);

create index idx_44 on ccp_seclogrep(reportId,isInfraction);

create index idx_45 on ccp_userrightrep(reportId,isInfraction);

create index idx_46 on ccp_userpolicyrep(reportId);

create index idx_47 on ccp_grouppolicyrep(reportId);

create index idx_48 on ccp_fileinforep(reportId,isInfraction);

create index idx_49 on ccp_fileencryptrep(reportId);

create index idx_50 on ccp_delFile (reportId);

create index idx_51 on ccp_delFileCheck (reportId,isInfraction);

create index idx_52 on ccp_deepUSBCheck(reportId,isInfraction);

create index idx_53 on ccp_deepURLCheck(reportId,isInfraction);

create indexidx_54 on ccp_sectorCheck (reportId,isInfraction);

 

任務檢查報告:查看報告;優化前耗時7660毫秒,優化后耗時3370毫秒

優化方式:

1:添加索引

create index index_ccp_device_policy on  ccp_device_policy(policyId,mark);

 

create indexindex_ccp_checkreport on ccp_checkreport(policyId,planReportTime);

 

查詢檢查項數據:優化前耗時8300毫秒 優化后耗時2073毫秒

優化方式:數據表中添加索引,引用上面sql索引語句

注意:聯合索引reportId,isInfraction其實是支持2個索引,reportId和reportId,isINfraction

 

緩存

MySQL查詢緩存的使用

開啟查詢緩存:

 

 

 

 

set global query_cache_type = 1;   使用命令開啟查詢緩存
setglobal query_cache_size = 134217728; 緩存區的大小 設置太小不會生效

 

 

show variables like "%query_cache%";

 

 

根據query_cache_type這個變量來決定的。

這個變量有三個取值:0,1,2,分別代表了off、on、demand。
mysql默認為開啟on

 

查詢 SHOW STATUS LIKE'Qcache_hits'; value為0

查詢后Qcache_hits變化

 

ex:

關閉查詢緩存:

C:\Program Files(x86)\MySQL\MySQL Server 5.0 中 my.ini配置

query_cache_type = 0

query_cache_size = 0

或者

set global query_cache_type = 0;   使用命令關閉查詢緩存
setglobal query_cache_size = 0;

 

 

查詢 SHOW STATUS LIKE'Qcache_hits'; value為0

 

使用查詢:select count(*) fromccp_printerrep;

SHOW STATUS LIKE 'Qcache_hits';value值還是為0

show status like"%Qcache%";

 

開啟查詢緩存測試

select * from ccp_softwarerep;

第一次查詢耗時:1.434s

 

第二次查詢耗時:0.629s

 

mysql默認 query_cache 是打開的
你使用 show global variables like '%query_cache%';

確認一下有沒有打開,如果打開了。第一次查詢讀數據文件,第二次就會走query_cache,所以就會很快。當然 ,如果數據更新了,要重新再緩存。

第二種情況 ,表引擎使用innodb.第一次查詢也會走數據文件,第二次直接走buffer_pool,也比直接查詢數據文件要快

上面的說法是否正確。
本人測試:
--開啟查詢緩存 在my.ini文件中配置 並重啟服務
 query_cache_type = 1;  
 query_cache_size = 134217728;

select * from ccp_usbinforep 語句條數:145011條
--第一次執行語句用時1.181s; 第二次執行用時0.265s
Qcache_hits 為 211 而且會增加說明是在使用查詢緩存

--關閉查詢緩存 在my.ini 中配置
query_cache_size=0;
query_cache_type = 0;
select * from ccp_usbinforep 語句條數:145011條
第一次執行語句用時0.294s;第二次執行用時0.283s
Qcache_hits為0
以上實驗說明,好像mysql緩存不管怎么配置對sql查詢的影響時間影響不大,那么配置的意義在於什么呢。
或者以上我哪些配置和理解錯誤?

如果緩存起作用,就用緩存,緩存關閉就是要表引擎 那么有沒緩存影響大么。請大家簡單說下自己的理解

查詢時,數據庫引擎會判斷,如果數據在內存中,則會從內存讀取數據,如果數據不在內存在,則先從硬盤讀到內存,然后再供查詢。
所以第一次查的時候,根據你的語句,數據庫引擎會把一些數據從硬盤讀到內存,第二次再查的時候,就從內存讀數據,就快了很多了搜索。

如果這是正確的,那么mysql的緩存有什么意義。。。

網友意見:query cache是第一道緩存,命中則直接返回,否則進入存儲引擎層面處理
關掉query cache,直接進入到存儲引擎層面,innodb本身也是有緩存機制的
都是從內存中取結果,執行效率差別不大。我的數據庫引擎是innodb的,所以不好測試。如果是其他的可以測試看看

 

分表

mysql數據庫中分表優化。

 

 

1:使用Mysql的Merge存儲引擎實現分表查詢

 

CREATE TABLE t1 (  a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,  message CHAR(20));
 CREATE TABLE t2 (  a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,  message CHAR(20));

INSERT INTO t1 (message) VALUES ('Testing'),('table'),('t1');

 INSERT INTO t2 (message) VALUES ('Testing'),('table'),('t2');

 CREATE TABLE total (a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, message CHAR(20)) ENGINE=MERGE UNION=(t1,t2)INSERT_METHOD=LAST;

 

對應定期分表的情況下,只要定期相應的增加一個基礎表,再修改merge表中的 union 就行了(ALTER TABLE tbl_name  UNION=(...))。

如在增加一個表(需和其他基礎表一樣的結構):

定期增加表邏輯;可以使用MySQL定時創建表的SQL語句

資料網站:       http://blog.csdn.NET/qingtian2002/article/details/23825113

 

mysql中每隔一段時間自動執行一次sql語句

 

 

如:table201606        然后執行ALTER TABLE total  UNION=(t1,t2,t3,table201606);注意INSERT_METHOD=LAST;

表示新來的數據會插入到生成的新表中。

 CREATE TABLE t3(  a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,  message CHAR(20));

ALTER TABLE total  UNION=(t1,t2,t3)

INSERT_METHOD=LAST;表示插入的方法,INSERT_METHOD的值可以是 FIRST(插入第一個表),LAST(最后一個表),NO(不能插入)

 

查詢的時候,和平常一樣

select * from total where ....

merge表會自動找到相應的基礎表進行查詢。

 

注意問題:id可能重復問題

 

mysql版本必須高於5.0版本

 

ex:定時創建表

 

drop event e_createuser;

drop PROCEDURE create_user;

 

show variables like '%sche%';

 

set global event_scheduler =1;

 

create procedure create_user()

 BEGIN

set @sql_create_table = concat(

 'CREATE TABLE IF NOT EXISTS user', date_format(now(),'%Y%m'),

 "( 

   `id` int(11) NOT NULL AUTO_INCREMENT, 

  `name` varchar(50) DEFAULT NULL, 

   `sex` int(1) NOT NULL DEFAULT '0', 

                   PRIMARYKEY (`id`) 

                   )ENGINE=MyISAM  DEFAULT CHARSET=utf8AUTO_INCREMENT=1");

 

 PREPARE sql_create_table FROM @sql_create_table;  

 EXECUTE sql_create_table;

END

 

 

create event if not existse_createuser 

on schedule every 30 second 

on completion preserve 

do call create_user();

 

%Y%m%d%H%i%s 表示年月日時分秒20160630102310

 

每隔30秒將執行存儲過程test,將當前時間更新到examinfo表中id=14的記錄的endtime字段中去.

 

關閉事件任務

 

alter event e_createuser ON  

COMPLETION PRESERVE DISABLE;

開戶事件任務

 

alter event e_createuser ON  

COMPLETION PRESERVE ENABLE;

以上測試均成功,測試環境為mysql 5.1

 

分布式集群

2: 做mysql集群,例如:利用mysql cluster ,mysql proxy,mysql replication,drdb等等

有人會問mysql集群,根分表有什么關系嗎?雖然它不是實際意義上的分表,但是它啟到了分表的作用,做集群的意義是什么呢?為一個數據庫減輕負擔,說白了就是減少sql排隊隊列中的sql的數量,舉個例子:有10個sql請求,如果放在一個數據庫服務器的排隊隊列中,他要等很長時間,如果把這10個sql請求,分配到5個數據庫服務器的排隊隊列中,一個數據庫服務器的隊列中只有2個,這樣等待時間是不是大大的縮短了呢?這已經很明顯了。所以我把它列到了分表的范圍以內,我做過一些mysql的集群:

Linux mysql proxy 的安裝,配置,以及讀寫分離

mysql replication 互為主從的安裝及配置,以及數據同步

優點:擴展性好,沒有多個分表后的復雜操作(PHP代碼)

缺點:單個表的數據量還是沒有變,一次操作所花的時間還是那么多,硬件開銷大。

 

集群資料:http://www.th7.cn/db/mysql/201409/72633.shtml

 


免責聲明!

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



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