Query Cache

   查询执行路径中的组件:查询缓存、解析器、预处理器、优化器、查询执行引擎、存储引擎;

SELECT语句的执行流程:

wKiom1Y2DAKy7IZpAAEzJcpM-do468.jpg


   FROM Clause --> WHERE Clause --> GROUP BY --> HAVING Clause --> ORDER BY --> SELECT --> LIMIT

wKioL1Y2DFHDKhG9AAGEVXWpf0s774.jpg


①、数据去重,相同数据只显示一次

MariaDB [hellodb]> SELECT DISTINCT Gender FROM students;
#DISTINCT: 数据去重。SQL_CACHE: 显式指定存储查询结果于缓存之中。SQL_NO_CACHE: 显式查询结果不予缓存

MariaDB [hellodb]> SHOW GLOBAL VARIABLES LIKE 'query_cache_type'\G
*************************** 1. row ***************************
Variable_name: query_cache_type       
        Value: ON
#ON,查询缓存开启。OFF,查询缓存不开启。DEMAND,查询缓存按需进行,显式指定SQL_CACHE的SELECT语句才会缓存,其它均不予缓存
MariaDB [hellodb]> SHOW GLOBAL VARIABLES LIKE 'query_cache_size'\G


②、字段显示可以使用别名

MariaDB [hellodb]> SELECT DISTINCT Gender AS Gder FROM students;
+------+
| Gder |
+------+
| M    |
| F    |
+------+


③、WHERE子句:指明过滤条件(布尔型表达式)以实现“选择”的功能

  算术操作符:+, -, *, /, %

MariaDB [hellodb]> SELECT Name,Age FROM students WHERE Age+10 > 20;

 比较操作符:=, !=, <>, <=>, >, >=, <, <=

MariaDB [hellodb]> SELECT Name,Age FROM students WHERE Age = 20;

 确定范围闭区间:BETWEEN min_num AND max_num。NOT BETWEEN min_num AND max_num

MariaDB [hellodb]> SELECT Name,Age FROM students WHERE Age BETWEEN 32 AND 50; 
MariaDB [hellodb]> SELECT Name,Age FROM students WHERE Age NOT BETWEEN 32 AND 50;

 确定集合:IN(element1, element2, ...)。NOT IN(element1, element2, ...)

MariaDB [hellodb]> SELECT Name,Age FROM students WHERE Age IN (32,50); 
MariaDB [hellodb]> SELECT Name,Age FROM students WHERE Age NOT IN (32,50);

 空值查询:IS NULL。IS NOT NULL。

MariaDB [hellodb]> SELECT Name,ClassID FROM students WHERE ClassID IS NULL; 
MariaDB [hellodb]> SELECT Name,ClassID FROM students WHERE ClassID IS NOT NULL;

 字符模糊匹配:LIKE:(%: 任意长度的任意字符。_:任意单个字符)

MariaDB [hellodb]> SELECT Name,ClassID FROM students WHERE Name LIKE 'X%';
MariaDB [hellodb]> SELECT Name,ClassID FROM students WHERE Name LIKE 'X_ Z%';

 逻辑操作符:NOT、AND、OR、XOR

MariaDB [hellodb]> SELECT * FROM students WHERE Gender = 'F' AND ClassID = 3;


④、GROUP:根据指定的条件把查询结果进行“分组”以用于做“聚合”运算

 “聚合”运算:avg(), max(), min(), count(), sum()

MariaDB [hellodb]> SELECT AVG(Age),Gender FROM students GROUP BY Gender;
#对性别进行分组,然后计算出各组员的平均年龄
MariaDB [hellodb]> SELECT MAX(Age),Gender FROM students GROUP BY Gender;
#对性别进行分组,然后计算出各组员的最大年龄


⑤、HAVING: 对分组聚合运算后的结果指定过滤条件

MariaDB [hellodb]> SELECT AVG(Age) AS Ages,Gender FROM students GROUP BY Gender HAVING Ages > 20;
#对性别进行分组,然后计算出各组员的平均年龄,并值显示Ags大于20的
MariaDB [hellodb]> SELECT COUNT(StuID) AS SID,ClassID FROM students GROUP BY ClassID HAVING SID > 2;
#对班级进行分组,然后计算出各组员的个数,并显示组员个数大于2的


⑥、ORDER BY: 根据指定的字段对查询结果进行排序;

 升序:ASC、降序:DESC

MariaDB [hellodb]> SELECT * FROM students ORDER BY Age DESC;


⑦、LIMIT [[offset,]row_count]:对查询的结果进行输出行数数量限制;

MariaDB [hellodb]> SELECT * FROM students ORDER BY Age DESC LIMIT 1,3;
#对查询的结果偏移一个后取三个


⑧、对查询结果中的数据请求施加“锁”:

 FOR UPDATE: 写锁,排他锁、LOCK IN SHARE MODE: 读锁,共享锁



⑨、多表查询

 交叉连接:笛卡尔乘积。一般不会使用到,很消耗资源

MariaDB [hellodb]> SELECT * FROM students,classes;

 内连接:等值连接,让表之间的字段以“等值”建立连接关系、不等值连接、自然连接、自连接

MariaDB [hellodb]> SELECT * FROM students,teachers WHERE students.TeacherID = teachers.TID;
MariaDB [hellodb]> SELECT s.Name AS StuName,t.Name AS TeaName  FROM students AS s,teachers AS t WHERE s.TeacherID = t.TID;
#等值连接
MariaDB [hellodb]> SELECT s.Name,t.Name FROM students AS s,students AS t WHERE s.TeacherID = t.StuID;
#自连接

 外连接:左外连接,FROM tb1 LEFT JOIN tb2 ON tb1.col=tb2.col、右外连,FROM tb1 RIGHT JOIN tb2 ON tb1.col=tb2.col

MariaDB [hellodb]> SELECT s.Name,c.Class FROM students AS s RIGHT JOIN classes AS c ON s.ClassID = c.ClassID;
MariaDB [hellodb]> SELECT s.Name,c.Class FROM students AS s LEFT JOIN classes AS c ON s.ClassID = c.ClassID;


⑩、子查询:在查询语句嵌套着查询语句,基于某语句的查询结果再次进行的查询,Mysql对子查询优化不是很好,建议少用

 用在WHERE子句中的子查询:(1) 用于比较表达式中的子查询;子查询仅能返回单个值;

MariaDB [hellodb]> SELECT Name,Age FROM students WHERE Age>(SELECT avg(Age) FROM students);
#显示大于平均年龄的同学

(2) 用于IN中的子查询:子查询应该单键查询并返回一个或多个值从构成列表;

MariaDB [hellodb]> SELECT Name,Age FROM students WHERE Age IN (SELECT Age FROM teachers);


 用于FROM子句中的子查询;

MariaDB [hellodb]> SELECT s.aage,s.ClassID FROM (SELECT avg(Age) AS aage,ClassID FROM students WHERE ClassID IS NOT NULL GROUP BY ClassID) AS s WHERE s.aage>30;


⑩①、联合查询:UNION

MariaDB [hellodb]> SELECT Name,Age FROM students UNION SELECT Name,Age FROM teachers;