1. 程式人生 > >【JAVA秒會技術之玩轉SQL】MySQL優化技術(一)

【JAVA秒會技術之玩轉SQL】MySQL優化技術(一)

MySQL優化技術(一)

        開發的路上,總會碰到一些老系統,越用越慢“慢”的原因也許有很多,但是,博主個人覺得,資料庫的設計和sql語句寫的好壞,對系統效率的影響是最直接,最顯而易見的!所以,學習一下MySQL的優化,還是很有必要的。當然,博主能力有限,沒那麼多經驗,更多的是“道聽途說”和“紙上談兵”。如有不正之處,望大神開後給予指正,不勝感激!

(一)MySQL優化技術概述

表的設計合理化(符合3NF,即符合“三正規化”。當然也要照顧“反正規化”,要靈活);

新增適當索引(index)(主要包括:普通索引主鍵索引唯一索引unique全文索引);

SQL語句本身的優化

(主要包括:避免全表掃描避免巢狀子查詢等);

分表技術(水平分割垂直分割);

讀寫分離(其中寫包括:update/delete/add);

儲存過程模組化程式設計,可以提高速度,但是遷移性差,對伺服器壓力也會逐漸增大);

mysql配置優化(主要是修改my.ini配置檔案的引數資訊)

mysql伺服器硬體升級

定時的去清除不需要的資料,定時進行碎片整理(特別是使用了MyISAM)

(二)表的設計合理化

1.“三正規化”(3NF)的概念

第一正規化:1NF是對屬性的原子性約束,要求屬性(列)具有原子性,不可再分解;(只要是關係型資料庫都滿足1NF) ;

第二正規化:2NF是在1NF滿足的基礎上,對記錄的惟一性約束

,要求記錄有惟一標識,即實體的惟一性;

第三正規化:3NF是在2NF滿足的基礎上,對欄位冗餘性的約束,要求欄位沒有冗餘,也可以稱為消除依賴傳遞

2.“反正規化”(3NF)的概念

反正規化:是通過增加冗餘資料來提高資料庫讀效能的過程。

反正規化出現的原因:當我們的業務所涉及的表非常多,經常會有多表聯查,這樣它的效率就會大打折扣,這時我們就可以考慮使用“反正規化”。增加必要的,有效的冗餘欄位,用空間來換取時間,在查詢時減少或者是避免過多表之間的聯查。

3.舉例

傳智部落格視訊教程(業內良心,某寶2元錢買能一堆)中一個老專案為例,當時聽得時候,覺得老師講得神乎其神,列舉其中的幾個關鍵詞,大家聽聽:三正規化與反三正規化

分散計算思想打斷設計新增冗餘跳躍查詢資料搬家等等。咋一聽很能蒙人”,後來博主畫圖總結了一下,其實,一說就破,很簡單。

 

 


(三)Sql語句自身的優化

1.SHOW [ SESSION|GLOBAL ] STATUS指令的應用

#1.累計啟動多少秒

SHOW STATUS LIKE 'uptime'

#2.累計查詢/新增/修改/刪除多少次

SHOW STATUS LIKE 'com_select'

SHOW STATUS LIKE 'com_insert'

SHOW STATUS LIKE 'com_update'

SHOW STATUS LIKE 'com_delete'

#注意:預設是SESSION當前會話級別的統計,全域性的需要加上GLOBAL關鍵字

#預設的,當前會話級別的統計

SHOW SESSION STATUS LIKE 'com_select'

#全域性的,統計從始至終

SHOW GLOBAL STATUS LIKE 'com_select'

#3.顯示慢查詢次數

SHOW GLOBAL STATUS LIKE 'slow_queries'

#顯示當前慢查詢時間,預設10秒

SHOW VARIABLES LIKE 'long_query_time'

#修改慢查詢時間

SET long_query_time = 5

2.如何記錄及定位慢查詢

在預設情況下,我們的mysql不會記錄慢查詢,需要在啟動mysql時候,指定記錄慢查詢才可以:

bin\mysqld.exe - -safe-mode  - -slow-query-log

[mysql5.5 以上可以在my.ini指定]

先關閉mysql,再啟動, 如果啟用了慢查詢日誌,預設把這個檔案放在my.ini 檔案中記錄的位置:

#Path to the database root

datadir="C:/ProgramData/MySQL/MySQL Server 5.5/Data/"

檢視慢查詢日誌:預設為資料目錄data中的host-name-slow.log

(四)建立適當的索引

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

索引主要分為:普通索引、主鍵索引、唯一索引、全文索引四大類,下面進行逐一說明:

1.索引新增

1)主鍵索引新增

當一張表,把某個列設為主鍵的時候,則該列就是主鍵索引

create table aaa

(id int unsigned primary key auto_increment ,name varchar(32) not null defaul ‘’);

這時id 列就是主鍵索引。

如果你建立表時,沒有指定主鍵索引,也可以在建立表後,再新增(不常用), 指令:

alter table 表名 add primary key (列名)

2)普通索引

一般來說,普通索引的建立,是先建立表,然後再建立普通索引,比如:

create table 表名(

     id int unsigned,

     name varchar(32)

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

3)建立全文索引

全文索引,主要是針對檔案文字的檢索, 比如文章,全文索引針對MyISAM有用

建立

CREATE TABLE articles (

       id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,

       title VARCHAR(200),

       body TEXT,

       FULLTEXT (title,body)

     )engine=myisam charset utf8;

INSERT INTO articles (title,body) VALUES

     ('MySQL Tutorial','DBMS stands for DataBase ...'),

     ('How To Use MySQL Well','After you went through a ...'),

     ('Optimizing MySQL','In this tutorial we will show ...'),

     ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),

     ('MySQL vs. YourSQL','In the following database comparison ...'),

     ('MySQL Security','When configured properly, MySQL ...');

如何使用全文索引:

錯誤用法:

select * from articles where body like%mysql%;【不會使用到全文索引】

證明:

explain  select * from articles where body like %mysql%

正確的用法是:

select * from articles where match(title,body) against(database);

*注意事項:

1.mysql中fulltext 索引只針對MyISAM生效

2.mysql自己提供的fulltext針對英文生效->sphinx (coreseek) 技術處理中文

3.使用方法是 match(欄位名..) against(‘關鍵字’)

4.全文索引一個叫停止詞,  因為在一個文字中,建立索引是一個無窮大的數,因此,對一些常用詞和字元,就不會建立,這些詞,稱為停止詞。

4)唯一索引

①當表的某列被指定為unique約束時,這列就是一個唯一索引。

create table ddd(id int primary key auto_increment , name varchar(32)unique);

這時, name 列就是一個唯一索引。

注意:unique欄位可以為NULL,並可以有多NULL, 但是如果是具體內容,則不能重複

主鍵欄位,不能為NULL,也不能重複。

②在建立表後,再去建立唯一索引。

create table eee(id int primary key auto_increment, name varchar(32));

create unique index 索引名  on表名 (列表..);

2.查詢索引

desc 表名 【該方法的缺點是:不能夠顯示索引名.】

show index(es) from 表名\G

show keys from 表名\G

3.刪除

alter table 表名 drop index 索引名;

如果刪除主鍵索引。

alter table 表名 drop primary key       [這裡有一個小問題]

4.修改

先刪除,再重新建立.

5.索引的原理

1)資料庫的三層結構簡圖

 

2)原始的查詢圖解

     

     原始的查詢方法,查到number = 3後,仍然會往後查詢,以為不確保後面是否有重複資料,所以是全表檢索。至少要查詢8次。

2)對number建立索引後的查詢圖解

       

建立索引後,資料庫會將索引欄位,進行基於二叉樹(B Tree / B+ Tree的形式改造,並存儲在表名.MYI”的檔案中。其後,再次查詢時,只需查詢2次即可,而且樹節點記錄的是實體地址,可以直接定位到元素,這樣它的效率就大大的提高了。

6.索引的代價

①佔用磁碟空間;

②對DML操作有影響,變慢;

7.何時建立索引

①較頻繁的作為查詢條件欄位應該建立索引

select * from emp where empno = 1

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

select * from emp where sex = ‘男’

③更新非常頻繁的欄位不適合建立索引

select * from emp where logincount = 1

④不會出現在WHERE子句中欄位不該建立索

8.使用索引時的注意事項

建立如下複合索引:

    alter table dept add index my_ind (dname,loc);   # dname 左邊的列,loc就是右邊的列

如果我們的表中有複合索引(索引作用在多列上), 此時我們注意:

①對於建立的複合索引,只要查詢條件使用了最左邊的列,索引一般就會被使用

    explain select * from dept where loc= 'aaa'; #不會使用到索引

②對於使用like的查詢,查詢如果是‘%aaa’/‘_aaa’ 不會使用到索引,‘aaa%’/‘aaa_’ 會使用到索引

    explain select * from dept where dname like '%aaa'; #不會使用到索引

如果一定要前面有變化的值,則考慮使用全文索引->sphinx.

③如果條件中有or,即使其中有條件帶索引也不會使用。換言之,就是要求使用的所有欄位,都必須建立索引, 我們建議大家儘量避免使用or 關鍵字

   select * from dept where dname=’xxx’ or loc=’xx’ or deptno=45; #不會使用到索引

④如果列型別是字串,那一定要在條件中將資料使用引號引用起來。否則不使用索引。(新增時,字串必須’’), 也就是,如果列是字串型別,就一定要用 ‘’ 把他包括起來。

⑤如果mysql估計使用全表掃描要比使用索引快,則不使用索引。

8.explain的應用

explain可以幫助我們在不真正執行某個sql語句時,就執行mysql怎樣執行,這樣利用我們去分析sql指令。


如何檢視索引使用的情況:

   show status like ‘Handler_read%’;

注意:

handler_read_key:這個值越高越好,越高表示使用索引查詢到的次數。

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

相關推薦

JAVA技術SQLMySQL優化技術

MySQL優化技術(一)         開發的路上,總會碰到一些老系統,越用越慢。“慢”的原因也許有很多,但是,博主個人覺得,資料庫的設計和sql語句寫的好壞,對系統效率的影響是最直接,最顯而易見的!所以,學習一下MySQL的優化,還是很有必要的。當然,博主能力有限,沒那

跟我一起Sencha Touch 移動 WebApp 開發

1.目錄 移動框架簡介,為什麼選擇Sencha Touch?環境搭建建立專案框架,框架檔案簡介建立簡單Tabpanel案例自定義圖示的方式WebApp產品測試和釋出HTML5離線快取釋出成Android/IOS本地app應用 移動框架簡介,為什麼選擇Sencha Touch? 目前市面上,移動應用web框

Java 集合系列16 Spring Boot 配置文件 選項配置

writer) face 學習 apach .sql logs aspectj via threshold springboot配置選項(一) =================================================================

虛擬化技術kvm管理工具virsh常用基礎命令

  在上一篇部落格中,我們瞭解了KVM基礎架構和部署以及圖形管理工具virt-manager安裝虛擬機器的過程,回顧請參考https://www.cnblogs.com/qiuhom-1874/p/13499801.html;今天我們來聊一下kvm的命令列工具virsh;virsh工具功能非常豐富,它可以全生

筆記篇斜率優化dp HNOI2008玩具裝箱

公式 現在 getchar() 就是 clu cst 差距 直接 source 斜率優化dp 本來想直接肝這玩意的結果還是被忽悠著做了兩道數論現在整天渾渾噩噩無心學習甚至都不是太想頹廢是不是藥丸的表現各位要知道我就是故意要打刪除線並不是因為排版錯亂反正就是一個del標簽嘛

JAVA技術多執行緒多執行緒那些事兒

多執行緒那些事兒(一) 現在只要出去面試,關於“Java多執行緒”的問題,幾乎沒有一家單位不問的,可見其重要性。於是博主抽空研究了一下,確實很有意思!以下是我綜合整理了網上的各種資料,和個人的一些理解,寫的一篇總結博文,僅供學習、交流。 (一)多執行緒的概念      

JAVA技術殺面試官Java面試官——集合篇

tails category tail java cat 秒殺 試題 面試官 java面試 【JAVA秒會技術之秒殺面試官】秒殺Java面試官——集合篇(一) 【JAVA秒會技術之秒殺面試官】JavaEE常見面試題(三) http://blog.csdn.net/qq296

轉載JAVA技術圖片上傳基於Nginx及FastDFS,完成圖片的上傳及展示

相互 沒有 con 性能 ext 存儲服務器 網絡 管理 代理配置 基於Nginx及FastDFS,完成商品圖片的上傳及展示 一、傳統圖片存儲及展示方式 存在問題: 1)大並發量上傳訪問圖片時,需要對web應用做負載均衡,但是會存在圖片共享問題 2)web應

JAVA技術殺面試官JavaEE常見面試題

parameter 和數 程序 配置 except 查詢 解析 list 就會 1.Struts2中,Action通過什麽方式獲取用戶從頁面輸入的數據,又是通過什麽方法把數據傳給視圖層顯示的? 答:(1)Action從頁面獲取數據的方式有三種: ①通過Act

JAVA技術殺面試官JavaSE常見面試題

方法 變量 dir 步驟 註解 無法 t對象 面試 線程 21.在Java中,如何跳出當前的多重嵌套循環? 答:在最外層循環前加一個標記如A,然後用break A;可以跳出多重循環。(Java中支持帶標簽的break和continue語句,作用有點類似於C和C++中的go

JAVA技術殺面試官JavaSE常見面試題

mark error 對象創建 事件 算法 pool ret sync 數量 41..比較一下Java和JavaSciprt? 答:其實Java和JavaScript最重要的區別是一個是靜態語言,一個是動態語言: (1)基於對象和面向對象:Java是一種真正的面向對象的語言

JAVA技術殺面試官JavaEE常見面試題

裝配 配置文件 action getpara 表達 程序員 錯誤頁面 產生 創建 46.Request對象的主要方法? 答:(1)setAttribute(String name,Object):設置名字為name的request的參數值 (2)getAttribute(S

JAVA技術殺面試官JavaEE常見面試題

內存溢出 不可重復讀 cad struts2的 pro 單線程 映射 指定 log 51.事務的特性? 答:①原子性(Atomicity) 指事務是一個不可分割的工作單位,事務中的操作要麽全都發生,要麽全不發生; ②一致性(Consistency) 事務前後數據的完成性必須

JAVA技術殺面試官JavaEE常見面試題

行處理 周期 3年 struts 處理 isp java對象 date 代碼 62.談一談你對Mybatis的理解? MyBatis 本是apache的一個開源項目iBatis, 2010年這個項目由apache software foundation 遷移到了google

JAVA技術Java8新特性利用流快速處理集合的常見操作

例子1:對集合進行排序 List<Integer> list = Lists.newArrayList(1,1,2,2,5,3,4,6,6,5,2,7); list.sort(null); list.forEach(e -> System.out.prin

JAVA技術殺面試官JavaSE常見面試題

【前言】別人都在你看不到的地方暗自努力,在你看得到的地方,他們也和你一樣顯得遊手好閒,和你一樣會抱怨,而只有你自己相信這些都是真的,最後,也只有你一個人繼續不思進取 ……   【下載】本人剛學習Java時總結的一些JavaSE常見面試題,偶爾在電腦中翻出,重新整理一下

JAVA技術隨意切換資料庫Spring如何高效的配置多套資料來源

Spring如何高效的配置多套資料來源     真正的開發中,難免要使用多個數據庫,進行不同的切換。無論是為了實現“讀寫分離”也好,還是為了使用不同的資料庫(“MySQL”或“Oracle”或“SQLServer”)。傳統的方法,是配置多套Spring配置檔案與Mysql配

JAVA技術LinuxLinux系統中安裝中文字型方法微軟雅黑或宋體

Linux系統中安裝中文字型方法 本例子以安裝微軟雅黑和黑體為例,其他的同理; 0.準備工作:     沒有的可以先下載字型,或是到C:\Windows\Fonts目錄下找 1.建立本地字型資料夾:    mkdir /usr/share/fonts/local 2.

深入K8S業務彈性伸縮和滾動更新操作

nginx 副本 mil 容器 history 博客 limit 新的 ima 在實際應用場景中避免不了因為業務的壓力而增加容器數量以及業務應用版本叠代更新,那麽本篇文章我們來學習下簡單的業務彈性伸縮、滾動更新操作,滾動操作的好處在於零停機更新,也就是說每次更新一小部分副本

JAVA POI匯入技術EXCEL模板中製作下拉列表

        在專案系統中,經常會用到POI匯入匯出EXCEL的功能。在進行POI進行匯入EXCEL的時候,經常會涉及到EXCEL模板的問題,匯入EXCEL的模板大部分都會涉及到下拉列表的選項值。今