真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Mysql高級(jí)

1 MySQL 的架構(gòu)介紹

1.1 sql_mode

sql_mode 是一個(gè)容易忽視的變量,默認(rèn)情況下為空,可以忍耐一些非法操作,在生產(chǎn)環(huán)境中,必須將其設(shè)置為嚴(yán)格模式,在開發(fā)測(cè)試環(huán)境中配該變量也是很有必要的,因?yàn)檫@樣可以在生產(chǎn)之前發(fā)現(xiàn)問題。

創(chuàng)新互聯(lián)基于成都重慶香港及美國等地區(qū)分布式IDC機(jī)房數(shù)據(jù)中心構(gòu)建的電信大帶寬,聯(lián)通大帶寬,移動(dòng)大帶寬,多線BGP大帶寬租用,是為眾多客戶提供專業(yè)服務(wù)器托管報(bào)價(jià),主機(jī)托管價(jià)格性價(jià)比高,為金融證券行業(yè)川西大數(shù)據(jù)中心,ai人工智能服務(wù)器托管提供bgp線路100M獨(dú)享,G口帶寬及機(jī)柜租用的專業(yè)成都idc公司。

sql_mode 常用值如下:

  • ONLY_FULL_GROUP_BY:對(duì)于 GROUP BY 聚合操作,如果在 SELECT 中的列沒有在 GROUP BY 中出現(xiàn),那么這個(gè) sql 是不合法的
  • NO_AUTO_VALUE_ON_ZERO:該值影響自增列的插入,默認(rèn)情況下,插入 0 或 NULL 代表生成下一個(gè)增長值,如果用戶希望插入的主鍵 ID 為0,就可以配置這個(gè)值
  • STRICT_TRANS_TABLES:如果一個(gè)值不能插入到一個(gè)事務(wù)表中,則中斷當(dāng)前的操作,非事務(wù)表不限制
  • NO_ZERO_IN_DATE:在嚴(yán)格模式下,不允許日期和月份為零
  • NO_ZERO_DATE:不允許插入零日期,否則拋出異常
  • ERROR_FOR_DIVISION_BY_ZERO:在插入或更新過程中,如果數(shù)據(jù)被零除,則產(chǎn)生錯(cuò)誤,如果未配置該參數(shù),那么數(shù)據(jù)被零除時(shí)返回 NULL
  • NO_AUTO_CREATE_USER:禁止創(chuàng)建密碼為空的用戶
  • NO_ENGINE_SUBSTITUTION:如果需要的存儲(chǔ)引擎未編譯或被禁用,則拋出錯(cuò)誤
  • PIPES_AS_CONCAT:將 || 視為字符串連接操作符
  • ANSI_QUOTES:配置該參數(shù)后,不能用 “” 引用字符串

1.2 MySQL 邏輯架構(gòu)

和其它數(shù)據(jù)庫相比,MySQL 有點(diǎn)與眾不同,它的架構(gòu)可以在多種不同場(chǎng)景中應(yīng)用并發(fā)揮良好作用,主要體現(xiàn)在存儲(chǔ)引擎的架構(gòu)上,插件式的存儲(chǔ)引擎架構(gòu)將查詢處理和其它的系統(tǒng)任務(wù)以及數(shù)據(jù)的存儲(chǔ)提取相分離,這種架構(gòu)可以根據(jù)業(yè)務(wù)的需求和實(shí)際需要選擇合適的存儲(chǔ)引擎。

Mysql 高級(jí)

連接層

最上層是客戶端和連接服務(wù),包含本地 socket 通信和 tcp/ip 通信,主要完成連接處理、授權(quán)認(rèn)證及相關(guān)的安全方案,該層引入了線程池,為授權(quán)用戶提供線程,還實(shí)現(xiàn)了 ssl 安全鏈接。

服務(wù)層

  • Management Serveices & Utilities:系統(tǒng)管理和控制工具
  • SQL Interface:SQL 接口,接收 SQL 命令,并返回查詢結(jié)果
  • Parser:解析器,對(duì) SQL 命令進(jìn)行驗(yàn)證和解析
  • Optimizer:查詢優(yōu)化器,在查詢之前對(duì)語句進(jìn)行優(yōu)化
  • Cache 和 Buffer:查詢緩存,如果查詢緩存有命中的查詢結(jié)果,查詢語句就可以直接去查詢緩存中取數(shù)據(jù),這個(gè)緩存機(jī)制是由一系列小緩存組成的,比如表緩存,記錄緩存,key緩存,權(quán)限緩存等

引擎層

存儲(chǔ)引擎層,負(fù)責(zé)了數(shù)據(jù)的存儲(chǔ)和提取,服務(wù)器通過 API 與存儲(chǔ)引擎進(jìn)行通信。

存儲(chǔ)層

數(shù)據(jù)存儲(chǔ)層,主要是將數(shù)據(jù)存儲(chǔ)在運(yùn)行于裸設(shè)備的文件系統(tǒng)之上,并完成與存儲(chǔ)引擎的交互。

1.2.1 SQL 的執(zhí)行周期

開啟診斷分析工具

set profiling=1;

顯示最近的幾條查詢

show profiles;

查看 SQL 的執(zhí)行步驟

show profile cpu,block io for query 1;

1.2.2 查詢流程
  • 客戶端和 MySQL 建立連接,發(fā)送查詢語句,先查詢緩存,如果緩存有命中,直接返回結(jié)果,否則進(jìn)行語句解析
  • 也就是說,解析之前先訪問緩存,解析器將對(duì)語句進(jìn)行語法規(guī)則校驗(yàn)和解析查詢,然后會(huì)生成一顆解析樹
  • 之后由優(yōu)化器將解析器轉(zhuǎn)換成執(zhí)行計(jì)劃,最后執(zhí)行計(jì)劃,返回結(jié)果
1.2.3 SQL 執(zhí)行順序
FROM 
ON 
 JOIN 
WHERE 
GROUP BY
HAVING 
SELECT
DISTINCT 
ORDER BY 
LIMIT 

1.3 MySQL 存儲(chǔ)引擎

查看支持的存儲(chǔ)引擎

show engines;

查看當(dāng)前默認(rèn)的存儲(chǔ)引擎

show variables like '%storage_engine%';

1.3.1 各個(gè)引擎簡(jiǎn)介

InnoDB

InnoDB 是 MySQL 默認(rèn)的事務(wù)型引擎,用來處理大量的短期事務(wù),除非有特別的原因需要用到其他存儲(chǔ)引擎,否則優(yōu)先考慮 InnoDB。

MyISAM

MyISAM 提供了大量的特性,包括全文檢索、壓縮、空間函數(shù)等,但 MyISAM 不支持事務(wù)和行級(jí)鎖,缺點(diǎn)是崩潰后無法安全恢復(fù)。

Archive

Archive 檔案存儲(chǔ)引擎只支持 INSERT 和 SELECT 操作,在 MySQL5.1 之前不支持索引;

Archive 表適合日志和數(shù)據(jù)采集類應(yīng)用;

根據(jù)英文的測(cè)試結(jié)論來看,Archive 表比 MyISAM 表要小大約 75%,比支持事務(wù)處理的 InnoDB 表小大約 83%。

Blackhole

Blackhole 引擎沒有實(shí)現(xiàn)任何存儲(chǔ)機(jī)制,它會(huì)丟棄所有插入的數(shù)據(jù),不做任何保存。但服務(wù)器會(huì)記錄Blackhole表的日志,所以可以用于復(fù)制數(shù)據(jù)到備庫,或者簡(jiǎn)單地記錄到日志。但這種應(yīng)用方式會(huì)碰到很多問題,因此并不推薦。

CSV

CSV 引擎可以將普通的 CSV 文件作為 MySQL 表來處理,但不支持索引, CSV 可以作為一種數(shù)據(jù)交換的機(jī)制,CSV 引擎存儲(chǔ)的數(shù)據(jù)可以被文本編輯器、execl 讀取。

Memory

如果需要快速地訪問數(shù)據(jù),并且這些數(shù)據(jù)不會(huì)被修改,重啟以后丟失也沒有關(guān)系,那么使用Memory表是非常有用,Memory 表至少比 MyISAM 表要快一個(gè)數(shù)量級(jí)。

Federated

Federated 引擎是訪問其他 MySQL 服務(wù)器的一個(gè)代理,盡管該引擎看起來提供了一種很好的跨服務(wù)器的靈活性,但也經(jīng)常帶來問題,因此默認(rèn)是禁用的。

1.3.2 InnoDB 和 MyISAM
對(duì)比項(xiàng)InnoDBMyISAM
外鍵 支持 不支持
事務(wù) 支持 不支持
行表鎖 行鎖,操作時(shí)只鎖定操作的那一行,不會(huì)對(duì)其他行產(chǎn)生影響,適合于高并發(fā) 表鎖,即使只操作一行也會(huì)鎖定整個(gè)表,不適合高并發(fā)
緩存 不僅緩存索引還要緩存真實(shí)數(shù)據(jù),對(duì)內(nèi)存要求較高,而且內(nèi)存大小對(duì)性能有決定性的影響 只緩存索引,不緩存真實(shí)數(shù)據(jù)
關(guān)注點(diǎn) 并發(fā)寫、事務(wù)、更大資源 節(jié)省資源、消耗少、簡(jiǎn)單業(yè)務(wù)
默認(rèn)安裝 Y Y
默認(rèn)使用 Y N
自帶系統(tǒng)表使用 N Y

2 索引優(yōu)化分析

2.1 優(yōu)化步驟

分庫分表

SQL 優(yōu)化

建立索引

調(diào)整 my.cnf 優(yōu)化服務(wù)器及配置參數(shù)

2.2 索引簡(jiǎn)介

2.2.1 什么是索引?

數(shù)據(jù)本身之外,數(shù)據(jù)庫還維護(hù)著一個(gè)滿足特定查找算法的數(shù)據(jù)結(jié)構(gòu),這些數(shù)據(jù)結(jié)構(gòu)以某種方式指向數(shù)據(jù),這樣就可以在這些數(shù)據(jù)結(jié)構(gòu)的基礎(chǔ)上實(shí)現(xiàn)高級(jí)查找算法,這種數(shù)據(jù)結(jié)構(gòu)就是索引;

一般來說索引本身也很大,不可能全部存儲(chǔ)在內(nèi)存中,因此索引往往以索引文件的形式存儲(chǔ)的磁盤上;

雖然索引提高了查詢的效率,但是也降低了更新的效率,因?yàn)楦卤頃r(shí),不僅要插入數(shù)據(jù),同時(shí)還要保存一下索引文件每次更新添加了的索引列的字段,都會(huì)調(diào)整因?yàn)楦滤鶐淼逆I值變化后的索引信息;

實(shí)際上索引也是一張表,該表保存了主鍵與索引字段,并指向?qū)嶓w表的記錄,所以索引列也是要占用空間的。

2.2.2 MySQL 索引結(jié)構(gòu)
2.2.2.1 BTree 索引

Mysql 高級(jí)

如圖所示,磁盤塊 1 包含數(shù)據(jù)項(xiàng) 17 和 35,包含指針 P1、P2、P3

P1 表示小于 17 的磁盤塊,P2 表示介于 17 和 35 之間的磁盤塊,35 表示大于 35 的磁盤塊

查找過程

如果要查找數(shù)據(jù)項(xiàng) 29,首先將磁盤塊 1 加載到內(nèi)存,此時(shí)發(fā)生一次 IO,利用二分查找確定 29 在 17 和 35 之間,鎖定磁盤塊 1 的 P2 指針,通過磁盤塊 1 的 P2 指針的磁盤地址把磁盤塊 3 加載到內(nèi)存,此時(shí)發(fā)生一次 IO,利用二分查找確定 29 在26 和 30 之間,鎖定磁盤塊 3 的 P2 指針,通過磁盤塊 3 的 P2 指針的磁盤地址把磁盤塊 8 加載到內(nèi)存,此時(shí)發(fā)生一次 IO,同時(shí)利用二分查找到 29,查詢結(jié)束。

2.2.2.2 B+Tree 索引

Mysql 高級(jí)

B+ 樹的非葉子節(jié)點(diǎn)只是存儲(chǔ) key,占用空間非常小,因此每一層的節(jié)點(diǎn)能索引到的數(shù)據(jù)范圍更加的廣,換句話說,每次 IO 操作可以觀看更多的數(shù)據(jù);

葉子節(jié)點(diǎn)兩兩相連,符合磁盤的預(yù)讀特性。如圖存儲(chǔ) 5、8 、9 的葉子節(jié)點(diǎn),它有個(gè)指針指向了 10、15、18 這個(gè)葉子節(jié)點(diǎn),那么當(dāng)我們從磁盤讀取5、8、9 對(duì)應(yīng)的數(shù)據(jù)的時(shí)候,由于磁盤的預(yù)讀特性,會(huì)順便把 10、15、18 對(duì)應(yīng)的數(shù)據(jù)讀取出來,這個(gè)時(shí)候?qū)儆陧樞蜃x取,而不是磁盤尋道了,加快了速度;

支持范圍查詢,而且部分范圍查詢非常高效,原因是數(shù)據(jù)都是存儲(chǔ)在葉子節(jié)點(diǎn)這一層,并且有指針指向其他葉子節(jié)點(diǎn),這樣范圍查詢只需要遍歷葉子節(jié)點(diǎn)這一層,無需整棵樹遍歷。

2.2.2.3 聚簇索引與非聚簇索引

聚簇索引并不是一種單獨(dú)的索引類型,而是一種數(shù)據(jù)存儲(chǔ)方式,聚簇表示數(shù)據(jù)行和相鄰的鍵值聚簇的存儲(chǔ)在一起;

按照聚簇索引排列順序,查詢顯示一定范圍數(shù)據(jù)的時(shí)候,由于數(shù)據(jù)都是緊密相連,數(shù)據(jù)庫不不用從多個(gè)數(shù)據(jù)塊中提取數(shù)據(jù),所以節(jié)省了大量的 IO 操作;

對(duì)于 MySQL 數(shù)據(jù)庫目前只有 InnoDB 數(shù)據(jù)引擎支持聚簇索引,而 MyISAM 并不支持聚簇索引;

由于數(shù)據(jù)物理存儲(chǔ)排序方式只能有一種,所以每個(gè) MySQL 的表只能有一個(gè)聚簇索引,一般情況下就是該表的主鍵;

為了充分利用聚簇索引的聚簇的特性,所以 InnoDB 表的主鍵列盡量選用有序的順序 ID,而不建議用無序的 ID,比如 UUID這種。

2.2.3 MySQL 索引分類
2.2.2.3.1 單值索引

即一個(gè)索引只包含單個(gè)列,一個(gè)表可以有多個(gè)單列索引

隨表一起建索引: 
CREATE TABLE customer (
    id INT (10) UNSIGNED AUTO_INCREMENT,
    customer_no VARCHAR (200),
    customer_name VARCHAR (200),
    PRIMARY KEY (id),
    KEY (customer_name)
);

單獨(dú)建單值索引: 
CREATE INDEX idx_customer_name ON customer (customer_name);

刪除索引: 
DROP INDEX idx_customer_name ON customer;
2.2.3.2 唯一索引

索引列的值必須唯一,但可以為空

隨表一起建索引: 
CREATE TABLE customer (
    id INT (10) UNSIGNED AUTO_INCREMENT,
    customer_no VARCHAR (200),
    customer_name VARCHAR (200),
    PRIMARY KEY (id),
    KEY (customer_name),
    UNIQUE (customer_no)
);

單獨(dú)建唯一索引: 
CREATE UNIQUE INDEX idx_customer_no ON customer (customer_no);

刪除索引: 
DROP INDEX idx_customer_no ON customer;
2.2.3.3 主鍵索引

設(shè)為主鍵后自動(dòng)創(chuàng)建主鍵索引

隨表一起建索引: 
CREATE TABLE customer (
    id INT (10) UNSIGNED AUTO_INCREMENT,
    customer_no VARCHAR (200),
    customer_name VARCHAR (200),
    PRIMARY KEY (id)
);

單獨(dú)建主鍵索引: 
ALTER TABLE customer ADD PRIMARY KEY customer (customer_no);

刪除建主鍵索引: 
ALTER TABLE customer DROP PRIMARY KEY;

修改建主鍵索引: 必須先刪除掉 (DROP) 原索引,再新建 (ADD) 索引
2.2.3.4 復(fù)合索引

一個(gè)索引包含單個(gè)列

隨表一起建索引: 
CREATE TABLE customer (
    id INT (10) UNSIGNED AUTO_INCREMENT,
    customer_no VARCHAR (200),
    customer_name VARCHAR (200),
    PRIMARY KEY (id),
    KEY (customer_name),
    UNIQUE (customer_name),
    KEY (customer_no, customer_name)
);

單獨(dú)建索引: 
CREATE INDEX idx_no_name ON customer (customer_no, customer_name);

刪除索引: 
DROP INDEX idx_no_name ON customer;
2.2.4 創(chuàng)建索引的時(shí)機(jī)

哪些情況需要?jiǎng)?chuàng)建索引?

  • 主鍵自動(dòng)創(chuàng)建唯一索引
  • 頻繁作為查詢條件的字段應(yīng)該創(chuàng)建索引
  • 查詢中與其他表關(guān)聯(lián)的字段,外鍵關(guān)系建立索引
  • 組合索引比單值索引性價(jià)比更高
  • 查詢排序的字段,排序字段若通過索引去訪問將大大提高排序速度
  • 查詢中統(tǒng)計(jì)或分組字段

哪些情況不需要?jiǎng)?chuàng)建索引?

  • 表記錄太少
  • 經(jīng)常更新的表
  • where 條件里用不到的字段不需要?jiǎng)?chuàng)建索引
  • 過濾性不好的字段不需要?jiǎng)?chuàng)建索引

2.3 性能分析

2.3.1 EXPLAN

使用 EXPLAIN 關(guān)鍵字可以模擬優(yōu)化器執(zhí)行 SQL 查詢語句,從而知道 MySQL 是如何處理 SQL 語句的,分析查詢語句或是表結(jié)構(gòu)的性能瓶頸。

EXPLAN 的作用:

查看表的讀取順序

查看哪些索引可以被使用

數(shù)據(jù)讀取操作的操作類型

哪些索引被實(shí)際使用

表之間的引用

使用方式:

Explain + SQL

Explain SELECT * FROM t_emp A LEFT JOIN t_dept B ON A.deptId = B.id WHERE B.`id` IS NULL
    -> UNION
    -> SELECT * FROM t_emp A RIGHT JOIN t_dept B ON A.deptId = B.id WHERE A.`deptId` IS NULL;
2.3.2 各字段解釋
  • id:

    SELECT 查詢的序列號(hào),包含一組數(shù)字,表示查詢中執(zhí)行 SELECT 子句或操作表的順序

    • id 相同:執(zhí)行順序由上至下

    • id 不同:如果是子查詢,id 的序號(hào)會(huì)遞增,id 值越大優(yōu)先級(jí)越高,越先被執(zhí)行

    • id 相同不同,同時(shí)存在:id如果相同,可以認(rèn)為是一組,從上往下順序執(zhí)行;在所有組中,id值越大,優(yōu)先級(jí)越高,越先執(zhí)行

    每個(gè) id 表示一趟獨(dú)立的查詢,一個(gè) SQL 的查詢趟數(shù)越少越好

  • select_type

    查詢的類型,主要是用于區(qū)別普通查詢、聯(lián)合查詢、子查詢等的復(fù)雜查詢

    • SIMPLE:最簡(jiǎn)單的查詢,不包含 UNION 和子查詢

    • PRIMARY:查詢中若包含復(fù)雜的子部分,最外層查詢被標(biāo)記為 PRIMARY

    • DERIVED:在 FROM 列表中包含的子查詢被標(biāo)記為 DERIVED,MySQL 會(huì)遞歸執(zhí)行這些子查詢, 把結(jié)果放在臨時(shí)表里

    • SUBQUERY:在 SELECT 或 WHERE 列表中包含子查詢

    • DEPENDENT SUB:在 SELECT 或 WHERE 列表中包含子查詢,子查詢基于外層

    • UNCACHEABLE SUBQUREY:結(jié)果集不能被緩存的子查詢,必須重新為外層查詢的每一行進(jìn)行評(píng)估

    • UNION:若第二個(gè) SELECT 出現(xiàn)在 UNION 之后,則被標(biāo)記為 UNION

    • UNION RESULT:從 UNION 表獲取結(jié)果的 SELECT
  • table

    顯示這一行的數(shù)據(jù)是關(guān)于哪張表的

  • type

    顯示連接使用的類型,按最優(yōu)到最差的類型排序

    • system:表只有一行記錄

    • const:表示通過索引一次就找到了,const 用于比較 primary key 或者 unique 索引,因?yàn)橹黄ヅ湟恍袛?shù)據(jù),所以很快
      如將主鍵置于 where 列表中,MySQL 就能將該查詢轉(zhuǎn)換為一個(gè)常量

    • eq_ref:唯一性索引掃描,對(duì)于每個(gè)索引鍵,表中只有一條記錄與之匹配,常見于主鍵或唯一索引掃描

    • ref:非唯一性索引掃描,返回匹配某個(gè)單獨(dú)值的所有行,本質(zhì)上也是一種索引訪問,它返回所有匹配某個(gè)單獨(dú)值的行,然而,它可能會(huì)找到多個(gè)符合條件的行,所以它應(yīng)該屬于查找和掃描的混合體

    • range:只檢索給定范圍的行,使用一個(gè)索引來選擇行,key 列顯示使用了哪個(gè)索引,一般就是在 where 語句中出現(xiàn)了 between、<、>、in 等的查詢,這種范圍掃描索引掃描比全表掃描要好,因?yàn)樗恍枰_始于索引的某一點(diǎn),而結(jié)束語另一點(diǎn),不用掃描全部索引

    • index:出現(xiàn) index 是 SQL 使用了索引但是沒用通過索引進(jìn)行過濾,一般是使用了覆蓋索引或者是利用索引進(jìn)行了排序分組

    • all:Full Table Scan,將遍歷全表以找到匹配的行

    • index_merge:在查詢過程中需要多個(gè)索引組合使用,通常出現(xiàn)在有 or 的關(guān)鍵字的 SQL 中

    • ref_or_null:對(duì)于某個(gè)字段既需要關(guān)聯(lián)條件,也需要 null 值的情況下,查詢優(yōu)化器會(huì)選擇用 ref_or_null 連接查詢

    • index_subquery:利用索引來關(guān)聯(lián)子查詢,不再全表掃描

    • unique_subquery:該聯(lián)接類型類似于 index_subquery,子查詢中的唯一索引

    一般來說,得保證查詢至少達(dá)到 range 級(jí)別,最好能達(dá)到 ref

  • possible_keys

    顯示可能應(yīng)用在這張表中的索引,一個(gè)或多個(gè),查詢涉及到的字段上若存在索引,則該索引將被列出,但不一定被查詢實(shí)際使用

  • key

    實(shí)際使用的索引,如果為NULL,則沒有使用索引,查詢中若使用了覆蓋索引,則該索引和查詢的 select 字段重疊

  • key_len

    表示索引中使用的字節(jié)數(shù),可通過該列計(jì)算查詢中使用的索引的長度, key_len 字段能夠檢查是否充分的利用上了索引

  • ref

    顯示索引的哪一列被使用了,如果可能的話,是一個(gè)常數(shù),哪些列或常量被用于查找索引列上的值

  • rows

    rows 列顯示 MySQL 認(rèn)為它執(zhí)行查詢時(shí)必須檢查的行數(shù)

  • Extra

    包含不適合在其他列中顯示但十分重要的額外信息

    • Using filesort:說明 mysql 會(huì)對(duì)數(shù)據(jù)使用一個(gè)外部的索引排序,而不是按照表內(nèi)的索引順序進(jìn)行讀取,MySQL 中無法利用索引完成的排序操作稱為文件排序
    • Using temporary:使了用臨時(shí)表保存中間結(jié)果,MySQL 在對(duì)查詢結(jié)果排序時(shí)使用臨時(shí)表,常見于排序 order by 和分組查詢 group by
    • USING index:表示相應(yīng)的 select 操作中使用了覆蓋索引(Covering Index),避免訪問了表的數(shù)據(jù)行,效率不錯(cuò),如果同時(shí)出現(xiàn) using where,表明索引被用來執(zhí)行索引鍵值的查找,如果沒有同時(shí)出現(xiàn) using where,表明索引只是用來讀取數(shù)據(jù)而非利用索引執(zhí)行查找
    • Using where:表明使用了 where 過濾
    • using join buffer:使用了連接緩存:
    • impossible where:where 子句的值總是 false,不能用來獲取任何元組
    • select tables optimized away:在沒有 GROUP BY 子句的情況下,基于索引優(yōu)化 MIN/MAX 操作或者對(duì)于MyISAM 存儲(chǔ)引擎優(yōu)化 COUNT(*) 操作,不必等到執(zhí)行階段再進(jìn)行計(jì)算,查詢執(zhí)行計(jì)劃生成的階段即完成優(yōu)化。

2.4 查詢優(yōu)化

2.4.1 單表使用索引失效問題

index(a,b,c)

Where語句索引是否被使用
WHERE a = 3 y,使用到 a
WHERE a = 3 AND b = 5 y,使用到 a、b
WHERE a = 3 AND b = 5 AND c = 4 y,使用到 a、b、c
WHERE b = 3、WHERE b = 3 AND c = 4、WHERE c = 4 n
WHERE a = 3 AND c = 5 y,使用到 a,b中斷了
WHERE a = 3 AND b > 4 AND c = 5 y,使用到 a,b 中斷了
WHERE a IS NULL AND b IS NOT NULL is null 支持索引 但是is not null 不支持,所以 a 可以使用索引,b 不可以使用索引
WHERE a <> 3 <> 不能使用索引
WHERE abs(a) = 3 abs 不能使用索引
WHERE a = 3 AND b LIKE 'kk%' AND c = 4 y,使用到 a、b、c
WHERE a = 3 AND b LIKE '%kk' AND c = 4 y,使用到 a
WHERE a = 3 AND b LIKE '%kk%' AND c = 4 y,使用到 a
WHERE a = 3 AND b LIKE 'k%kk%' AND c = 4 y,使用到 a、b、c

創(chuàng)建索引的建議:

對(duì)于單值索引,盡量選擇針對(duì)當(dāng)前查詢過濾性更高的字段

選擇組合索引,當(dāng)前查詢過濾性最高的字段在索引的位置越靠前越好

選擇組合索引,盡量選擇可以能夠包含當(dāng)前查詢中的 where 字句中更多字段的索引

在選擇組合索引的時(shí)候,如果某個(gè)字段可能出現(xiàn)范圍查詢時(shí),盡量把這個(gè)字段放在索引次序的最后面

2.4.2 關(guān)聯(lián)查詢優(yōu)化

保證被驅(qū)動(dòng)表的 join 字段已經(jīng)被索引

left join 時(shí),選擇小表作為驅(qū)動(dòng)表,大表作為被驅(qū)動(dòng)表

inner join 時(shí),MySQL 會(huì)自己把小結(jié)果集的表選為驅(qū)動(dòng)表

子查詢盡量不要放在被驅(qū)動(dòng)表,有可能使用不到索引

能夠直接多表關(guān)聯(lián)的盡量直接關(guān)聯(lián),不用子查詢

2.4.3 子查詢優(yōu)化

盡量不要使用not in 或者 not exists,用 left join on xxx is null 替代

2.4.4 排序分組優(yōu)化

ORDER BY子句,盡量使用Index方式排序,避免使用FileSort方式排序

如果不在索引列上,filesort 有兩種算法:

雙路排序

  • MySQL 4.1 之前是使用雙路排序,字面意思就是兩次掃描磁盤,最終得到數(shù)據(jù),讀取行指針和 order by 列,對(duì)他們進(jìn)行排序,然后掃描已經(jīng)排序好的列表,按照列表中的值重新從列表中讀取對(duì)應(yīng)的數(shù)據(jù)輸出
  • 從磁盤取排序字段,在 buffer 進(jìn)行排序,再從磁盤取其他字段
  • 取一批數(shù)據(jù),要對(duì)磁盤進(jìn)行了兩次掃描,眾所周知,IO 是很耗時(shí)的,所以在 MySQL 4.1 之后,出現(xiàn)了第二種改進(jìn)的算法,就是單路排序

單路排序:

  • 從磁盤讀取查詢需要的所有列,按照 order by 列在 buffer 對(duì)它們進(jìn)行排序,然后掃描排序后的列表進(jìn)行輸出,它的效率更快一些,避免了第二次讀取數(shù)據(jù),并且把隨機(jī) IO 變成了順序 IO,但是它會(huì)使用更多的空間,因?yàn)樗衙恳恍卸急4嬖趦?nèi)存中了
  • 單路排序是把所有的字段都取出,所以有可能取出的數(shù)據(jù)的總大小超過了 sort_buffer 的容量,導(dǎo)致每次只能取 sort_buffer 容量大小的數(shù)據(jù)進(jìn)行排序,排序完再取一部分,反而增大了 IO
  • 優(yōu)化策略
    • 增大sort_buffer_size參數(shù)的設(shè)置
    • 增大max_length_for_sort_data參數(shù)的設(shè)置
    • 減少 select 后面的查詢的字段
    • 禁止使用 select *

group by 使用索引的原則幾乎跟 order by 一致 ,唯一區(qū)別是 group by 即使沒有過濾條件用到索引,也可以直接使用索引

3 查詢截取分析

什么是慢查詢?nèi)罩荆?/p>

慢查詢?nèi)罩臼?MySQL 提供的一種日志記錄,它用來記錄在 MySQL 中響應(yīng)時(shí)間超過閾值的語句,具體指運(yùn)行時(shí)間超過long_query_time 值的 SQL,則會(huì)被記錄到慢查詢?nèi)罩局校?/p>

long_query_time 的默認(rèn)值為10,意思是運(yùn)行10秒以上的語句。

默認(rèn)慢查詢?nèi)罩臼顷P(guān)閉的,需要手動(dòng)開啟

查看慢查詢?nèi)罩臼欠耖_啟
SHOW VARIABLES LIKE '%slow_query_log%';
開啟慢查詢?nèi)罩?set global slow_query_log=1;

查看并配置 long_query_time

查看long_query_time
SHOW VARIABLES LIKE 'long_query_time%';
set  long_query_time=1

日志分析工具 mysqldumpslow

Mysql 高級(jí)

常用參考:

hadoop100得到返回記錄集最多的10個(gè)SQL
mysqldumpslow -s r -t 10 /var/lib/mysql/hadoop100-slow.log

得到訪問次數(shù)最多的10個(gè)SQL
mysqldumpslow -s c -t 10 /var/lib/mysql/hadoop100-slow.log

得到按照時(shí)間排序的前10條里面含有左連接的查詢語句
mysqldumpslow -s t -t 10 -g "left join" /var/lib/mysql/hadoop100-slow.log

另外建議在使用這些命令時(shí)結(jié)合 | 和more 使用 ,否則有可能出現(xiàn)爆屏情況
mysqldumpslow -s r -t 10 /var/lib/mysql/hadoop100-slow.log | more

4 主從復(fù)制

復(fù)制的基本原理

master 將改變記錄到二進(jìn)制日志(binary log),這些記錄過程叫做二進(jìn)制日志事件,binary log events;

slave 將 master 的 binary log events 拷貝到它的中繼日志(relay log);

slave 重做中繼日志中的事件,將改變應(yīng)用到自己的數(shù)據(jù)庫中,MySQL 復(fù)制是異步的且串行化的。

復(fù)制的基本原則

每個(gè) slave 只有一個(gè) master

每個(gè) slave 只能有一個(gè)唯一的服務(wù)器 ID

每個(gè) master 可以有多個(gè)salve

4.1 配置主從復(fù)制

1、配置主數(shù)據(jù)庫

vim /etc/my.cnf

server-id=1
log-bin=mysql-bin
binlog_format=mixed

為從服務(wù)分配賬號(hào)

Mysql 高級(jí)

查看主服務(wù)器 BIN 日志的信息

show master status;

重啟主數(shù)據(jù)庫

systemctl restart mariadb

2、配置從數(shù)據(jù)庫

連接主數(shù)據(jù)庫

CHANGE MASTER TO 
    -> MASTER_HOST="192.168.10.100",
    -> MASTER_USER="slave",
    -> MASTER_PASSWORD="123456",
    -> MASTER_LOG_FILE="mysql-bin.000001",
    -> MASTER_LOG_POS=388;

啟動(dòng)從數(shù)據(jù)庫

start slave;

新聞名稱:Mysql高級(jí)
本文來源:http://weahome.cn/article/jigpeh.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部