MySql高級(一)

MySql高級(一)

一、MySQL邏輯架構

首先,mysql的查詢流程大體是:mysql

mysql客戶端經過協議與mysql服務器建鏈接,發送查詢語句,先檢查查詢緩存,若是命中,直接返回結果,不然進行語句解析,也就是說,在解析查詢以前,服務器會先訪問查詢緩存(query cache)——它存儲SELECT語句以及相應的查詢結果集。若是某個查詢結果已經位於緩存中,服務器就不會再對查詢進行解析、優化、以及執行。它僅僅將緩存中的結果返回給用戶便可,這將大大提升系統的性能。sql

語法解析器和預處理:首先mysql經過關鍵字將SQL語句進行解析,並生成一顆對應的「解析樹」。mysql解析器將使用mysql語法規則驗證和解析查詢;預處理器則根據一些mysql規則進一步檢查解析數是否合法。shell

查詢優化器當解析樹被認爲是合法的了,而且由優化器將其轉化成執行計劃。一條查詢能夠有不少種執行方式,最後都返回相同的結果。優化器的做用就是找到這其中最好的執行計劃。。緩存

而後,mysql默認使用的BTREE索引,而且一個大體方向是:不管怎麼折騰sql,至少在目前來講,mysql最多隻用到表中的一個索引。服務器

二、存儲引擎

#查看mysql存儲引擎
show engines;

#查看mysql當前默認的存儲引擎
show variables like '%storage_engine%';

2.一、MyISAM和InnoDB對比

對比項 MyISAM InnoDB
外鍵 只緩存索引,不緩存真實數據 不只緩存索引還要緩存真實數據,對內存要求較高,並且內存大小對性能有決定性的影響
事務 不支持 支持
行表鎖 表鎖,即便操做一條記錄也會鎖住整個表,不適合高併發的操做 行鎖,操做時只鎖某一行,不對其它行有影響,適合高併發的操做
緩存 只緩存索引,不緩存真實數據 不只緩存索引還要緩存真實數據,對內存要求較高,並且內存大小對性能有決定性的影響
關注點 性能 事務
默認安裝
默認使用
自帶系統表使用

三、索引優化

3.一、SQL性能降低的緣由

(1)索引失效架構

(2)關聯查詢太多join併發

(3)服務器調優及各個參數設置高併發

3.二、SQL的加載順序

3.2.一、手寫

3.2.二、機讀

3.三、七種Join

四、SQL預熱

4.一、建立表

CREATE TABLE `t_dept` (
 `id` INT(11) NOT NULL AUTO_INCREMENT,
 `deptName` VARCHAR(30) DEFAULT NULL,
 `address` VARCHAR(40) DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
 
CREATE TABLE `t_emp` (
 `id` INT(11) NOT NULL AUTO_INCREMENT,
 `name` VARCHAR(20) DEFAULT NULL,
  `age` INT(3) DEFAULT NULL,
 `deptId` INT(11) DEFAULT NULL,
empno int  not null,
 PRIMARY KEY (`id`),
 KEY `idx_dept_id` (`deptId`)
 #CONSTRAINT `fk_dept_id` FOREIGN KEY (`deptId`) REFERENCES `t_dept` (`id`)
) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
 
 
 
INSERT INTO t_dept(deptName,address) VALUES('華山','華山');
INSERT INTO t_dept(deptName,address) VALUES('丐幫','洛陽');
INSERT INTO t_dept(deptName,address) VALUES('峨眉','峨眉山');
INSERT INTO t_dept(deptName,address) VALUES('武當','武當山');
INSERT INTO t_dept(deptName,address) VALUES('明教','光明頂');
 INSERT INTO t_dept(deptName,address) VALUES('少林','少林寺');
 
INSERT INTO t_emp(NAME,age,deptId,empno) VALUES('風清揚',90,1,100001);
INSERT INTO t_emp(NAME,age,deptId,empno) VALUES('嶽不羣',50,1,100002);
INSERT INTO t_emp(NAME,age,deptId,empno) VALUES('令狐沖',24,1,100003);
 
 INSERT INTO t_emp(NAME,age,deptId,empno) VALUES('洪七公',70,2,100004);
INSERT INTO t_emp(NAME,age,deptId,empno) VALUES('喬峯',35,2,100005);
 
INSERT INTO t_emp(NAME,age,deptId,empno) VALUES('滅絕師太',70,3,100006);
INSERT INTO t_emp(NAME,age,deptId,empno) VALUES('周芷若',20,3,100007);
 
 
 
INSERT INTO t_emp(NAME,age,deptId,empno) VALUES('張三丰',100,4,100008);
 
INSERT INTO t_emp(NAME,age,deptId,empno) VALUES('張無忌',25,5,100009);
 
INSERT INTO t_emp(NAME,age,deptId,empno) VALUES('韋小寶',18,null,100010);

4.二、預熱題目

#全部門派的人員信息(A、B兩表共有)
SELECT * FROM t_dept INNER JOIN t_emp ON t_dept.`id` = t_emp.`deptId`;

#列出全部用戶,並顯示其機構信息 (A的全集)
SELECT * FROM t_emp LEFT JOIN t_dept  ON  t_emp.`deptId`=t_dept.`id`;

#列出全部門派 (B的全集)
SELECT * FROM t_dept

# 全部不入門派的人員 (A的獨有)
SELECT * FROM t_emp LEFT JOIN t_dept ON t_emp.`deptId`=t_dept.`id` WHERE t_emp.`deptId` IS NULL

#全部沒人入的門派 (B的獨有)
SELECT * FROM t_dept LEFT JOIN t_emp ON t_dept.`id`=t_emp.`deptId` WHERE t_emp.`deptId` IS NULL 

#列出全部人員和機構的對照關係(AB全有) 
#MySQL Full Join的實現 由於MySQL不支持FULL JOIN,下面是替代方法
#left join + union(可去除重複數據)+ right join
SELECT * FROM t_emp A LEFT JOIN t_dept B ON A.deptId = B.id
UNION
SELECT * FROM t_emp A RIGHT JOIN t_dept B ON A.deptId = B.id

#列出全部沒入派的人員和沒人入的門派(A的獨有+B的獨有)
SELECT * FROM t_emp LEFT JOIN t_dept ON t_emp.`deptId`=t_dept.`id` WHERE t_emp.`deptId` IS NULL
UNION
SELECT * FROM t_dept LEFT JOIN t_emp ON t_dept.`id`=t_emp.`deptId` WHERE t_emp.`deptId` IS NULL
相關文章
相關標籤/搜索