Mysql性能優化二

来源:http://www.cnblogs.com/jiekzou/archive/2016/04/12/5380073.html
-Advertisement-
Play Games

接上一篇Mysql性能優化一 建立適當的索引 說起提高資料庫性能,索引是最物美價廉的東西了。不用加記憶體,不用改程式,不用調sql,只要執行個正確的'create index',查詢速度就可能提高百倍千倍,這可真有誘惑力。可是天下沒有免費的午餐,查詢速度的提高是以插入、更新、刪除的速度為代價的,這些寫 ...


接上一篇Mysql性能優化一

建立適當的索引     

說起提高資料庫性能,索引是最物美價廉的東西了。不用加記憶體,不用改程式,不用調sql,只要執行個正確的'create index',查詢速度就可能提高百倍千倍,這可真有誘惑力。可是天下沒有免費的午餐,查詢速度的提高是以插入、更新、刪除的速度為代價的,這些寫操作,增加了大量的I/O。

是不是建立一個索引就能解決所有的問題?ename上沒有建立索引會怎樣?

select * from emp where ename='研發部';

---測試案例命令如下 (最好以 select * from emp e,dept d where e.empno=123451 )

*添加主鍵

ALTER TABLE emp ADD PRIMARY KEY(empno);

*刪除主鍵

alter table emp drop primary key;

索引的原理說明     

沒有索引為什麼會慢?

使用索引為什麼會快?

btree類型的索引,就是使用的二分查找法,肯定快啊,演算法複雜度是log2N,也就是說16條數據查4次,32條數據查5次,64條數據查6次....依次類推

索引的代價

1、磁碟占用

2、對dml(update delete insert)語句的效率影響

btree 方式檢索,演算法複雜度: log2N 次數

 

哪些列上適合添加索引       

1、較頻繁的作為查詢條件欄位應該創建索引

select * from emp where empno = 1;

2、唯一性太差的欄位不適合單獨創建索引,即使頻繁作為查詢條件

   select * from emp where sex = '男'

3、更新非常頻繁的欄位不適合創建索引

select * from emp where logincount = 1

4、不會出現在WHERE子句中的欄位不該創建索引

索引的類型             

  • 主鍵索引,主鍵自動的為主索引 (類型Primary)
  • 唯一索引 (UNIQUE)
  • 普通索引 (INDEX)
  • 全文索引 (FULLTEXT) [適用於MyISAM] ——》sphinx + 中文分詞    coreseek [sphinx 的中文版 ]
  • 綜合使用=>複合索引

簡述mysql四種索引的區別

lPRIMARY 索引 =》在主鍵上自動創建

lUNIQUE 索引=> 只要是UNiQUE 就是Unique索引.(只能在欄位內容不重覆的情況下,才能創建唯一索引)

lINDEX 索引=>就是普通索引

lFULLTEXT => 只在MYISAM 存儲引擎支持, 目的是全文索引,在內容系統中用的多, 在全英文網站用多(英文詞獨立). 中文數據不常用,意義不大,國內全文索引通常使用 sphinx來完成,全文索引只能在 char varchar text欄位創建.

全文索引案例

1.創建表

create table news(id int , title varchar(32),con varchar(1024)) engine=MyISAM;

2.建立全文索引

create fulltext index ful_inx on news (con);

3.插入數據

這裡要註意,對於常見的英文 fulltext 不會匹配,而且插入的語句本身是正確的.

'but it often happens that they are not above supporting themselves by dishonest means.which should be more disreputable.Cultivate poverty like a garden herb'

4.看看匹配度

mysql> select match(con) against('poverty') from news;

+-------------------------------+

| match(con) against('poverty') |

+-------------------------------+

|                             0 |

|                             0 |

|                             0 |

|            0.9853024482727051 |

+-------------------------------+

0表示沒有匹配到,或者你的詞是停止詞,是不會建立索引的.

使用全文索引,不能使用like語句,這樣就不會使用到全文索引了.

複合索引

create index 索引名 on 表名(列1,列2);

索引的使用             

建立索引

create [UNIQUE|FULLTEXT]  index index_name on tbl_name (col_name [(length)] [ASC | DESC] , …..);
alter table table_name ADD INDEX [index_name]  (index_col_name,...)

添加主鍵(索引) ALTER TABLE 表名 ADD PRIMARY KEY(列名,..); 聯合主鍵

刪除索引

DROP INDEX index_name ON tbl_name;
alter table table_name drop index index_name;

刪除主鍵(索引)比較特別: alter table t_b drop primary key;

查詢索引(均可)

show index(es) from table_name;
show keys from table_name;
desc table_Name;

修改索引,我們一般是先刪除在重新創建.

查詢要使用索引最重要的條件是查詢條件中需要使用索引。

下列幾種情況下有可能使用到索引:
1,對於創建的多列索引,只要查詢條件使用了最左邊的列,索引一般就會被使用。
2,對於使用like的查詢,查詢如果是  '%aaa' 不會使用到索引, 'aaa%' 會使用到索引。

下列的表將不使用索引:
1,如果條件中有or,即使其中有條件帶索引也不會使用。
2,對於多列索引,不是使用的第一部分,則不會使用索引。
3,like查詢是以%開頭
4,如果列類型是字元串,那一定要在條件中將數據使用引號引用起來。否則不使用索引。(添加時,字元串必須'')
5,如果mysql估計使用全表掃描要比使用索引快,則不使用索引。

測試案例(就在前面的dept表上做演示.)

CREATE TABLE dept(
deptno MEDIUMINT   UNSIGNED  NOT NULL  DEFAULT 0,
dname VARCHAR(20)  NOT NULL  DEFAULT "",
loc VARCHAR(13) NOT NULL DEFAULT ""
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ;

--放入數據,前面應該已經添加了,如果沒有則需要重新添加

--測試開始.

添加一個主鍵索引

alter table dept add primary key (deptno)

--測試語句

explain select * from dept where deptno=1;

結果是:

mysql> explain select * from dept where deptno=1;
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: dept
         type: const
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 3
          ref: const
         rows: 1
        Extra:
1 row in set (0.00 sec)

--創建多列索引

alter table dept add index myind (dname,loc);

--證明對於創建的多列索引,只要查詢條件使用了最左邊的列,索引一般就會被使用

explain select * from dept where dname='研發部'; 會顯示使用到了索引myind

explain select * from dept where loc='MsBDpMRX'; 不會顯示使用到了索引myind

--對於使用like的查詢

explain select * from dept where dname like '%研發部'; 不會顯示使用到了索引myind

explain select * from dept where dname like '研發部%'; 會顯示使用到了索引myind

--如果條件中有or,即使其中有條件帶索引也不會使用

--為了演示,我們把複合索引刪除,然後只在dname上加入索引.

alter table dept drop index myind
alter table dept add index myind (dname)
explain select * from dept where dname='研發部' or loc='aa';-- 就不會使用到dname列上的

--如果列類型是字元串,那一定要在條件中將數據使用引號引用起來。否則不使用索引

select * from dept from dname=1234; //不會使用到索引

select * from dept from dname='1234'; //會使用到索引

查看索引的使用情況
show status like 'Handler_read%';
大家可以註意:
handler_read_key:這個值越高越好,越高表示使用索引查詢到的次數。

handler_read_rnd_next:這個值越高,說明查詢低效。

* 這時我們會看到handler_read_rnd_next值很高,為什麼,這是因為我們前面沒有加索引的時候,做過多次查詢的原因.

常用SQL優化            

大批量插入數據(MySql管理員) 瞭解
對於MyISAM:

alter table table_name disable keys;
loading data//insert語句;
alter table table_name enable keys;

對於Innodb:
1,將要導入的數據按照主鍵排序
2,set unique_checks=0,關閉唯一性校驗。
3,set autocommit=0,關閉自動提交。

優化group by 語句
預設情況,MySQL對所有的group by col1,col2進行排序。這與在查詢中指定order by col1, col2類似。如果查詢中包括group by但用戶想要避免排序結果的消耗,則可以使用order by null禁止排序

有些情況下,可以使用連接來替代子查詢。
因為使用join,MySQL不需要在記憶體中創建臨時表。(講解)

如果想要在含有or的查詢語句中利用索引,則or之間的每個條件列都必須用到索引,如果沒有索引,則應該考慮增加索引(與環境相關 講解)

 select * from 表名 where 條件1='' or 條件2='tt'

explaine select * from dept group by dname; =>這時顯示 extra: using filesort 說明會進行排序

explaine select * from dept group by dname order by null =>這時不含有顯示 extra: using filesort 說明不會進行排序

***有些情況下,可以使用連接來替代子查詢。因為使用join,MySQL不需要在記憶體中創建臨時表。

explain select * from emp , dept where emp.deptno=dept.deptno;

和下麵比較就可以說明問題!!

explain select * from emp left join dept on emp.deptno=dept.deptno;

選擇合適的存儲引擎           

MyISAM:預設的MySQL存儲引擎。如果應用是以讀操作和插入操作為主,只有很少的更新和刪除操作,並且對事務的完整性要求不是很高。其優勢是訪問的速度快。

InnoDB:提供了具有提交、回滾和崩潰恢復能力的事務安全。但是對比MyISAM,寫的處理效率差一些並且會占用更多的磁碟空間。

Memory:數據存在記憶體中,服務重啟時,數據丟失

MyISAM: 在插入數據時,預設放在最後. ,刪除數據後,空間不回收.(不支持事務和外鍵)

InnoDB 支持事務和外鍵

對應我們程式員說,常用的存儲引擎主要是 myisam / innodb / memory,heap 表

如果選用小原則:

1.如果追求速度,不在乎數據是否一直把保存,也不考慮事務,請選擇 memory 比如存放用戶線上狀態.

2.如果表的數據要持久保存,應用是以讀操作和插入操作為主,只有很少的更新和刪除操作,並且對事務的完整性要求不是很高。選用MyISAM

3.如果需要數據持久保存,並提供了具有提交、回滾和崩潰恢復能力的事務安全,請選用Innodb

選擇合適的數據類型           

在精度要求高的應用中,建議使用定點數來存儲數值,以保證結果的準確性。deciaml 不要用float

對於存儲引擎是MyISAM的資料庫,如果經常做刪除和修改記錄的操作,要定時執行optimize table table_name;功能對錶進行碎片整理。

日期類型要根據實際需要選擇能夠滿足應用的最小存儲的早期類型

create table bbs(id int ,con varchar(1024) , pub_time int);

date('Ymd',時間-3*24*60*60); 2038年-1-19

對於使用浮點數和定點數的案例說明

create table temp1( t1 float(10,2), t2 decimal(10,2));

insert into temp1 values(1000000.32,1000000,32); 發現 t1 成了 1000000.31 所以有問題.

對於optimize table 表名 演示

create table temp2( id int) engine=MyISAM;
insert into temp2 values(1); insert into temp2 values(2); insert into temp2 values(3);
insert into temp2 select * from temp2;--複製
delete from temp2 where id=1; 發現 該表對於的數據文件沒有變小

定期執行 optimize table temp2 發現表大小變化,碎片整理完畢

&&對於InnoDB它的數據會存在data/ibdata1目錄下,在data/資料庫/只有一個 *.frm表結構文件.


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 我們的項目用到了spring框架和mongdb資料庫,隨著mongodb升級到3.0已有半年時間,我們也開始隨之升級,但是3.0的用戶驗證有所更改,導致原來的很多配置無法再用。 經過幾天的嘗試後,終於成功的用spring配置驗證。 升級用了兩個新的jar包,分別是pring-data-mongodb ...
  • 簡介: Mysql 中提供了多種類型的日誌文件,分別反映 Mysql 的不同信息,瞭解它們很有必要。 1、Error log ( 錯誤日誌 ) 錯誤日誌記錄了 Mysql Server 運行過程中所有較為嚴重的警告和錯誤信息,以及 Mysql Server 每次啟動和關閉的詳細信息。 在預設情況下, ...
  • CHAR char (M) M字元,長度是M*字元編碼長度,M最大255。 驗證如下: VARCHAR VARCHAR(M),M同樣是字元,長度是M*字元編碼長度。它的限制比較特別,行的總長度不能超過65535位元組。 註意,以上表的預設字元集是latin1,字元長度是1個位元組,所以對於varchar ...
  • 一、 是否支持多線程? SQLite官網上的“Is SQLite threadsafe?”這個問答。 簡單來說,從3.3.1版本開始,它就是線程安全的了。而iOS的SQLite版本沒有低於這個版本的,當然,你也可以自己編譯最新版本。 不過這個線程安全仍然是有限制的,在這篇《Is SQLite thr ...
  • 回到目錄 redis的客戶端有很多,這次用它的pub/sub發佈與訂閱我選擇了StackExchange.Redis,發佈與訂閱大家應該很清楚了,首先一個訂閱者,訂閱一個服務,服務執行一些處理程式(可能是寫個日誌,插入個數據,發個email)然後當另一個項目的某個業務發佈這個服務後,被訂閱的程式將會 ...
  • 問題現象:使用綠色版PL/SQL工具進行登錄時報如下截圖錯誤: 問題描述:初始化失敗,無法鎖定oci.dll 解決方法:在PLSQL的菜單欄里依次選擇 工具—>首選項,在OCI庫(自動檢測為空)項中手動更改其位置,指向bin目錄中的oci.dll的位置,問題即可解決。 註意:絕對路徑,如D:\Pro... ...
  • HBase是一種資料庫:HadoopDatabase顧名思義就是Hadoop資料庫,它是一種基於hadoop文件系統HDFS的一種分散式資料庫,專門設計用來快速隨機讀寫大規模數據。本文介紹HBase的下載與安裝的整個過程。 一、HBase的下載 1.登錄HBase官網http://hbase.apa ...
  • 一、選擇Percona Server、MariaDB還是MYSQL mysql應用源碼:http://www.jinhusns.com/Products/Download/?type=xcj 1、Mysql三種存儲引擎 MySQL提供了兩種存儲引擎:MyISAM和 InnoDB,MySQL4和5使用 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...