mysql構架:
connection pool:因爲單進程多線程,所以需要一個線程池接收請求提供併發,線程重用,還能完成認證
SQL interface:接收並分析SQL語句
Parser:分析器,翻譯sql語句,驗證用戶權限,執行響應指令,生成執行樹
Optimizer:優化器,通過分析索引結構,統計情況等衡量多個訪問路徑哪個開銷最小,生成統計數據,查詢語句改寫
Cache & Buffer:熱點數據裝入內存,實現查詢時加速,查詢時不需要每次都調用存儲引擎
存儲引擎:與數據塊上的數據交互,實現物理層(文件系統層面)和邏輯層(數據庫層面)映射。mariadb支持自定義引擎,默認使用innodb
MySQL數據文件類型:
數據文件、索引文件
重做日誌、撤消日誌、二進制日誌、錯誤日誌、查詢日誌、慢查詢日誌、(中繼日誌)
請求處理實現流程:
基本法則:索引應該構建在被用作查詢條件的字段上;
索引類型:
B+ Tree索引:順序存儲,每一個葉子節點到根結點的距離是相同的;左前綴索引,適合查詢範圍類的數據;
可以使用B-Tree索引的查詢類型:全鍵值、鍵值範圍或鍵前綴查找;
全值匹配:精確某個值, "Jinjiao King";
匹配最左前綴:只精確匹配起頭部分,"Jin%"
匹配範圍值:
精確匹配某一列並範圍匹配另一列:
只訪問索引的查詢
不適合使用B-Tree索引的場景:
如果不從最左列開始,索引無效; (Age,Name)
不能跳過索引中的列;(StuID,Name,Age)
如果查詢中某個列是爲範圍查詢,那麼其右側的列都無法再使用索引優化查詢;(StuID,Name)
Hash索引:基於哈希表實現,特別適用於精確匹配索引中的所有列;
注意:只有Memory存儲引擎支持顯式hash索引;
適用場景:
只支持等值比較查詢,包括=, IN(), <=>;
不適合使用hash索引的場景:
存儲的非爲值的順序,因此,不適用於順序查詢;
不支持模糊匹配;
空間索引(R-Tree):
MyISAM支持空間索引;
全文索引(FULLTEXT):
在文本中查找關鍵詞;
索引優點:
索引可以降低服務需要掃描的數據量,減少了IO次數;
索引可以幫助服務器避免排序和使用臨時表;
索引可以幫助將隨機I/O轉爲順序I/O;
高性能索引策略:
獨立使用列,儘量避免其參與運算;
左前綴索引:索引構建於字段的左側的多少個字符,要通過索引選擇性來評估
索引選擇性:不重複的索引值和數據表的記錄總數的比值;
多列索引:
AND操作時更適合使用多列索引;
選擇合適的索引列次序:將選擇性最高放左側;
冗餘和重複索引:
不好的索引使用策略
索引管理:按特定數據結構存儲的數據; 索引類型: 聚集索引、非聚集索引:數據是否與索引存儲在一起;多級形式一般前幾級非聚集,最後一級聚集,非聚集索引索引到數據塊上,找到元數據進而找到數據 主鍵索引、輔助索引 稠密索引、稀疏索引:是否索引了每一個數據項; B+ TREE、HASH、R TREE 簡單索引、組合索引:在一個字段還是多個字段上創建索引 左前綴索引:只針對某個字段的最左邊部分做索引 覆蓋索引:無需查找源數據,直接通過查找索引即可得到結果 管理索引的途徑: 創建索引:創建表時指定;CREATE INDEX 創建或刪除索引:也可以使用修改表的命令實現創建和刪除索引 刪除索引:DROP INDEX 查看錶上的索引: SHOW {INDEX | INDEXES | KEYS} {FROM | IN} tbl_name [{FROM | IN} db_name] [WHERE expr] 示例: MariaDB [hellodb]> SHOW INDEXES FROM students; +----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | +----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | students | 0 | PRIMARY | 1 | StuID | A | 25 | NULL | NULL | | BTREE | | | +----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 1 row in set (0.00 sec) 使用EXPLAIN分析出查詢過程中是否用到索引,以及如何獲取數據索引 id: 當前查詢語句中,每個SELECT語句的編號; 複雜類型的查詢有三種: 簡單子查詢; 用於FROM中的子查詢; 聯合查詢:UNION; 注意:UNION查詢的分析結果會出現一外額外匿名臨時表; select_type: 簡單查詢爲SIMPLE 全表掃描ALL 範圍查詢RANGE 複雜查詢: SUBQUERY: 簡單子查詢; DERIVED: 用於FROM中的子查詢; UNION:UNION語句的第一個之後的SELECT語句; UNION RESULT: 匿名臨時表; table:SELECT語句關聯到的表; type:關聯類型,或訪問類型,即MySQL決定的如何去查詢表中的行的方式; ALL: 全表掃描; index:根據索引的次序進行全表掃描;如果在Extra列出現“Using index”表示了使用覆蓋索引,而非全表掃描; range:有範圍限制的根據索引實現範圍掃描;掃描位置始於索引中的某一點,結束於另一點; ref: 根據索引返回表中匹配某單個值的所有行; eq_ref:僅返回一個行,但與需要額外與某個參考值做比較; const, system: 直接返回單個行; possible_keys:查詢可能會用到的索引; key: 查詢中使用了的索引; key_len: 在索引使用的字節數; ref: 在利用key字段所表示的索引完成查詢時所有的列或某常量值; rows:MySQL估計爲找所有的目標行而需要讀取的行數; Extra:額外信息 Using index:MySQL將會使用覆蓋索引,以避免訪問表; Using where:MySQL服務器將在存儲引擎檢索後,再進行一次過濾; Using temporary:MySQL對結果排序時會使用臨時表; Using filesort:對結果使用一個外部索引排序; MariaDB [hellodb]> EXPLAIN SELECT * FROM students WHERE StuID=3; 如下:利用索引的主鍵實現了一對一查詢 +------+-------------+----------+-------+---------------+---------+---------+-------+------+-------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +------+-------------+----------+-------+---------------+---------+---------+-------+------+-------+ | 1 | SIMPLE | students | const | PRIMARY | PRIMARY | 4 | const | 1 | | +------+-------------+----------+-------+---------------+---------+---------+-------+------+-------+ 1 row in set (0.00 sec) 如下:沒使用索引,就是取得所有行,一行一行查詢,效率較低 MariaDB [hellodb]> EXPLAIN SELECT * FROM students WHERE AGE=53; +------+-------------+----------+------+---------------+------+---------+------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +------+-------------+----------+------+---------------+------+---------+------+------+-------------+ | 1 | SIMPLE | students | ALL | NULL | NULL | NULL | NULL | 25 | Using where | +------+-------------+----------+------+---------------+------+---------+------+------+-------------+ 1 row in set (0.00 sec) 爲AGE字段添加索引: MariaDB [hellodb]> ALTER TABLE students ADD INDEX(Age); Query OK, 25 rows affected (0.00 sec) Records: 25 Duplicates: 0 Warnings: 0 Age字段也有了索引: MariaDB [hellodb]> SHOW INDEXES FROM students; +----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | +----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | students | 0 | PRIMARY | 1 | StuID | A | 25 | NULL | NULL | | BTREE | | | | students | 1 | Age | 1 | Age | A | NULL | NULL | NULL | | BTREE | | | +----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 爲Name字段創建一個索引: MariaDB [hellodb]> CREATE INDEX name ON students (Name); Query OK, 25 rows affected (0.01 sec) Records: 25 Duplicates: 0 Warnings: 0 查看: MariaDB [hellodb]> SELECT * FROM students WHERE Name LIKE 'X%'; +-------+-------------+-----+--------+---------+-----------+ | StuID | Name | Age | Gender | ClassID | TeacherID | +-------+-------------+-----+--------+---------+-----------+ | 7 | Xi Ren | 19 | F | 3 | NULL | | 22 | Xiao Qiao | 20 | F | 1 | NULL | | 3 | Xie Yanke | 53 | M | 2 | 16 | | 24 | Xu Xian | 27 | M | NULL | NULL | | 16 | Xu Zhu | 21 | M | 1 | NULL | | 19 | Xue Baochai | 18 | F | 6 | NULL | +-------+-------------+-----+--------+---------+-----------+ 查看語句執行分析:是一個基於範圍的查詢,查詢了6個 MariaDB [hellodb]> EXPLAIN SELECT * FROM students WHERE Name LIKE 'X%'; +------+-------------+----------+-------+---------------+------+---------+------+------+-----------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +------+-------------+----------+-------+---------------+------+---------+------+------+-----------------------+ | 1 | SIMPLE | students | range | name | name | 152 | NULL | 6 | Using index condition | +------+-------------+----------+-------+---------------+------+---------+------+------+-----------------------+ 1 row in set (0.00 sec) 全表掃描式查詢:查詢了25個 MariaDB [hellodb]> EXPLAIN SELECT * FROM students WHERE Name LIKE '%X%'; +------+-------------+----------+------+---------------+------+---------+------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +------+-------------+----------+------+---------------+------+---------+------+------+-------------+ | 1 | SIMPLE | students | ALL | NULL | NULL | NULL | NULL | 25 | Using where | +------+-------------+----------+------+---------------+------+---------+------+------+-------------+ 1 row in set (0.00 sec)
視圖:view虛表,一個select語句得到的結果保存爲虛表,可以對這個虛表繼續執行查詢作,修改 創建方法: CREATE VIEW view_name [(column_list)] AS select_statement [WITH [CASCADED | LOCAL] CHECK OPTION] 創建一個視圖: MariaDB [hellodb]> CREATE VIEW test AS SELECT StuID,Name,Age FROM students; Query OK, 0 rows affected (0.05 sec) 查看發現出現了視圖表test: MariaDB [hellodb]> SHOW TABLES; +-------------------+ | Tables_in_hellodb | +-------------------+ | classes | | coc | | courses | | scores | | students | | teachers | | test | | toc | +-------------------+ 8 rows in set (0.00 sec) 查看虛表狀態: MariaDB [hellodb]> SHOW TABLE STATUS LIKE 'test'\G; *************************** 1. row *************************** Name: test Engine: NULL Version: NULL Row_format: NULL Rows: NULL Avg_row_length: NULL Data_length: NULL Max_data_length: NULL Index_length: NULL Data_free: NULL Auto_increment: NULL Create_time: NULL Update_time: NULL Check_time: NULL Collation: NULL Checksum: NULL Create_options: NULL Comment: VIEW 1 row in set (0.00 sec) ERROR: No query specified 查詢一下發現只有3個字段,因爲我們創建時指定了這3個字段 MariaDB [hellodb]> SELECT * FROM test WHERE Age=22; +-------+---------------+-----+ | StuID | Name | Age | +-------+---------------+-----+ | 1 | Shi Zhongyu | 22 | | 2 | Shi Potian | 22 | | 21 | Huang Yueying | 22 | +-------+---------------+-----+ 3 rows in set (0.00 sec) 查看執行分析: MariaDB [hellodb]> EXPLAIN SELECT * FROM test WHERE Age=22\G; *************************** 1. row *************************** id: 1 select_type: SIMPLE table: students type: ref possible_keys: Age key: Age key_len: 1 ref: const rows: 2 Extra: 1 row in set (0.00 sec) ERROR: No query specified #視圖中的數據事實上存儲於“基表”中,因此,其修改操作也會針對基表實現;其修改操作受基表限制; 刪除視圖: DROP VIEW [IF EXISTS] view_name [, view_name] ... [RESTRICT | CASCADE]
mysql中SELECT專題:
查詢執行路徑中的組件:查詢緩存、解析器、預處理器、優化器、查詢執行引擎、存儲引擎;
SELECT FROM ORDER BY 查詢後做排序
SELECT FROM GROUP BY HAVING 查詢後分組,分組後指明過濾條件做過濾
SELECT FROM WHERE
SELECT FROM WHERE GROUP BY LIMIT 查詢後分組,然後僅顯示一部分內容
SELECT FROM HAING
GROUP和HAVING,LIMIT是可選的
總結:FROM Clause --> WHERE Clause --> GROUP BY --> HAVING Clause --> ORDER BY --> SELECT --> LIMIT
典型的不使用緩存查詢:(因爲時間一直在變) MariaDB [(none)]> SELECT now(); +---------------------+ | now() | +---------------------+ | 2015-11-03 09:37:24 | +---------------------+ 1 row in set (0.00 sec)
1.單表查詢:
去重使用DESTINCT: MariaDB [hellodb]> SELECT GENDER FROM students; +--------+ | GENDER | +--------+ | M | | M | | M | | M | | M | | M | | F | | F | | F | | F | | M | | F | | M | | F | | M | | M | | M | | M | | F | | F | | F | | F | | M | | M | | M | | M | +--------+ 發現變化了麼嗎:DISTINCT查詢後數據去重 MariaDB [hellodb]> SELECT DISTINCT GENDER FROM students; +--------+ | GENDER | +--------+ | M | | F | +--------+ 2 rows in set (0.00 sec) SQL_CACHE: 顯式指定存儲查詢結果於緩存之中; SQL_NO_CACHE: 顯式查詢結果不予緩存; MariaDB [hellodb]> SELECT SQL_CACHE DISTINCT Gender FROM students; +--------+ | Gender | +--------+ | M | | F | +--------+ 2 rows in set (0.00 sec) query_cache_type的值爲'ON'時,查詢緩存功能打開;SELECT的結果符合緩存條件即會緩存,否則,不予緩存;如果顯示指定SQL_NO_CACHE: 顯式查詢結果不予緩存; query_cache_size值爲0也不會緩存,想緩存就需要調整大於0 query_cache_type的值爲'DEMAND'時,查詢緩存功能按需進行;顯式指定SQL_CACHE的SELECT語句纔會緩存;其它均不予緩存 MariaDB [hellodb]> SHOW GLOBAL VARIABLES LIKE 'query%'; +------------------------------+---------+ | Variable_name | Value | +------------------------------+---------+ | query_alloc_block_size | 8192 | | query_cache_limit | 1048576 | | query_cache_min_res_unit | 4096 | | query_cache_size | 0 | | query_cache_strip_comments | OFF | | query_cache_type | ON | | query_cache_wlock_invalidate | OFF | | query_prealloc_size | 8192 | +------------------------------+---------+ 8 rows in set (0.00 sec) 查看緩存狀態屬性: MariaDB [hellodb]> SHOW GLOBAL STATUS LIKE 'Qcache%'; +-------------------------+-------+ | Variable_name | Value | +-------------------------+-------+ | Qcache_free_blocks | 0 | | Qcache_free_memory | 0 | | Qcache_hits | 0 | #命中次數 | Qcache_inserts | 0 | | Qcache_lowmem_prunes | 0 | | Qcache_not_cached | 0 | | Qcache_queries_in_cache | 0 | | Qcache_total_blocks | 0 | +-------------------------+-------+ 8 rows in set (0.01 sec) MariaDB [hellodb]> SHOW GLOBAL STATUS LIKE 'Com_select'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | Com_select | 8 | #查詢總次數 +---------------+-------+ 1 row in set (0.00 sec) 緩存命中率的評估:Qcache_hits命中次數/(Qcache_hits+Com_select)總次數 字段顯示可以使用別名: col1 AS alias1, col2 AS alias2, ... MariaDB [hellodb]> SELECT Name AS StuName FROM students; +---------------+ | StuName | +---------------+ | Diao Chan | | Ding Dian | WHERE子句: 指明過濾條件以實現“選擇”的功能: 過濾條件:布爾型表達式; 算術操作符:+, -, *, /, % 比較操作符:=, !=, <>, <=>, >, >=, <, <= !=和<>都表示不等於 <==>:在做比較時如果對方方出現空值沒法比較,這個表示跟空值比較時也可安全執行 BETWEEN min_num AND max_num IN (element1, element2, ...)等值或條件表達式 IS NULL IS NOT NULL 示例: MariaDB [hellodb]> SELECT Name,Age FROM students WHERE Age IN (18,100); +-------------+-----+ | Name | Age | +-------------+-----+ | Xue Baochai | 18 | | Sun Dasheng | 100 | +-------------+-----+ 2 rows in set (0.03 sec) MariaDB [hellodb]> SELECT Name,ClassID FROM students WHERE ClassID IS NULL; +--------------+---------+ | Name | ClassID | +--------------+---------+ | Xu Xian | NULL | | Sun Dasheng | NULL | | Yinjiao King | NULL | +--------------+---------+ 3 rows in set (0.00 sec) LIKE: %: 任意長度的任意字符; _:任意單個字符; RLIKE:基於正則表達式匹配 REGEXP:匹配字符串可用正則表達式書寫模式; 邏輯操作符:組合多個條件進行查詢NOT,AND,OR,XOR GROUP字句:根據指定的條件把查詢結果進行“分組”以用於做“聚合”運算: avg(), max(), min(), count(), sum() 統計男女同志的平均年齡: MariaDB [hellodb]> SELECT avg(Age),Gender FROM students GROUP BY Gender; +----------+--------+ | avg(Age) | Gender | +----------+--------+ | 19.0000 | F | | 37.0625 | M | +----------+--------+ 2 rows in set (0.00 sec) HAVINGD對group後的結果作過濾: MariaDB [hellodb]> SELECT avg(Age)as AAge,Gender FROM students GROUP BY Gender HAVING AAge>20; +---------+--------+ | AAge | Gender | +---------+--------+ | 37.0625 | M | +---------+--------+ 1 row in set (0.00 sec) count()函數可以計算總數 MariaDB [hellodb]> SELECT count(StuID) AS NOS,ClassID FROM students GROUP BY ClassID HAVING NOS >2; +-----+---------+ | NOS | ClassID | +-----+---------+ | 3 | NULL | | 4 | 1 | | 3 | 2 | | 4 | 3 | | 4 | 4 | | 4 | 6 | | 3 | 7 | +-----+---------+ 7 rows in set (0.00 sec) 3.ORDER BY: 根據指定的字段對查詢結果進行排序; 升序:ASC 降序:DESC MariaDB [hellodb]> SELECT count(StuID) AS NOS,ClassID FROM students GROUP BY ClassID HAVING NOS >2 ORDER BY NOS DESC; +-----+---------+ | NOS | ClassID | +-----+---------+ | 4 | 6 | | 4 | 1 | | 4 | 4 | | 4 | 3 | | 3 | NULL | | 3 | 2 | | 3 | 7 | +-----+---------+ 7 rows in set (0.00 sec) 4.LIMIT [[offset,]row_count]:對查詢的結果進行輸出行數數量限制; 顯示第11到20個,第一個10表示偏移量,第二個做計數 MariaDB [hellodb]> SELECT Name,Age FROM students ORDER BY Age DESC LIMIT 10,10; +---------------+-----+ | Name | Age | +---------------+-----+ | Hua Rong | 23 | | Yuan Chengzhi | 23 | | Huang Yueying | 22 | | Shi Zhongyu | 22 | | Shi Potian | 22 | | Xu Zhu | 21 | | Ren Yingying | 20 | | Xiao Qiao | 20 | | Xi Ren | 19 | | Duan Yu | 19 | +---------------+-----+ 10 rows in set (0.00 sec) 對查詢結果中的數據請求施加“鎖”: FOR UPDATE: 寫鎖,排他鎖; LOCK IN SHARE MODE: 讀鎖,共享鎖
2.多表查詢:
交叉連接:笛卡爾乘積;
內連接:
等值連接:讓表之間的字段以“等值”建立連接關係;讓兩張表中表示同一意義的字段建立等值連接關係
不等值連接
自然連接
自連接
外連接:
左外連接:
FROM tb1 LEFT JOIN tb2 ON tb1.col=tb2.col
右外連接
FROM tb1 RIGHT JOIN tb2 ON tb1.col=tb2.col
笛卡爾乘積:不建議已使用,效率很差 SELECT * FROM students; 26 rows in set (0.00 sec) MariaDB [hellodb]> SELECT * FROM teachers; +-----+---------------+-----+--------+ | TID | Name | Age | Gender | +-----+---------------+-----+--------+ | 1 | Song Jiang | 45 | M | | 2 | Zhang Sanfeng | 94 | M | | 3 | Miejue Shitai | 77 | F | | 4 | Lin Chaoying | 93 | F | +-----+---------------+-----+--------+ 4 rows in set (0.00 sec) SELECT * FROM students,teachers; 104 rows in set (0.00 sec) #是前面兩個錶行數之積 等值連接:讓表之間的字段以“等值”建立連接關係 MariaDB [hellodb]> SELECT * FROM students,teachers WHERE students.TeacherID=teachers.TID; +-------+-------------+-----+--------+---------+-----------+-----+---------------+-----+--------+ | StuID | Name | Age | Gender | ClassID | TeacherID | TID | Name | Age | Gender | +-------+-------------+-----+--------+---------+-----------+-----+---------------+-----+--------+ | 5 | Yu Yutong | 26 | M | 3 | 1 | 1 | Song Jiang | 45 | M | | 1 | Shi Zhongyu | 22 | M | 2 | 3 | 3 | Miejue Shitai | 77 | F | | 4 | Ding Dian | 32 | M | 4 | 4 | 4 | Lin Chaoying | 93 | F | +-------+-------------+-----+--------+---------+-----------+-----+---------------+-----+--------+ 兩張表中按照指定字段字段進行等值連接 MariaDB [hellodb]> SELECT s.Name AS StuName,t.Name AS TeaName FROM students AS s,teachers AS t WHERE s.TeacherID=t.T; +-------------+---------------+ | StuName | TeaName | +-------------+---------------+ | Yu Yutong | Song Jiang | | Shi Zhongyu | Miejue Shitai | | Ding Dian | Lin Chaoying | +-------------+---------------+ 3 rows in set (0.00 sec) 看下分析結果: MariaDB [hellodb]> EXPLAIN SELECT s.Name AS StuName,t.Name AS TeaName FROM students AS s,teachers AS t WHERE s.TeacherID=t.TID\G; *************************** 1. row *************************** id: 1 select_type: SIMPLE table: s type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 26 Extra: *************************** 2. row *************************** id: 1 select_type: SIMPLE table: t type: ALL possible_keys: PRIMARY key: NULL key_len: NULL ref: NULL rows: 4 Extra: Using where; Using join buffer (flat, BNL join) 2 rows in set (0.00 sec) 左外連接: MariaDB [hellodb]> SELECT s.Name,c.Class FROM students AS s LEFT JOIN classes AS c ON s.ClassID=c.ClassID; +---------------+----------------+ | Name | Class | +---------------+----------------+ | Shi Zhongyu | Emei Pai | | Shi Potian | Shaolin Pai | | Xie Yanke | Emei Pai | | Ding Dian | Wudang Pai | | Yu Yutong | QingCheng Pai | | Shi Qing | Riyue Shenjiao | | Xi Ren | QingCheng Pai | | Lin Daiyu | Ming Jiao | | Ren Yingying | Lianshan Pai | | Yue Lingshan | QingCheng Pai | | Yuan Chengzhi | Lianshan Pai | | Wen Qingqing | Shaolin Pai | | Tian Boguang | Emei Pai | | Lu Wushuang | QingCheng Pai | | Duan Yu | Wudang Pai | | Xu Zhu | Shaolin Pai | | Lin Chong | Wudang Pai | | Hua Rong | Ming Jiao | | Xue Baochai | Lianshan Pai | | Diao Chan | Ming Jiao | | Huang Yueying | Lianshan Pai | | Xiao Qiao | Shaolin Pai | | Ma Chao | Wudang Pai | | Xu Xian | NULL | | Sun Dasheng | NULL | | Yinjiao King | NULL | +---------------+----------------+ 26 rows in set (0.03 sec) 自連接: MariaDB [hellodb]> SELECT s.Name,t.Name FROM students AS s,students AS t WHERE s.TeacherID=t.StuID; +-------------+-------------+ | Name | Name | +-------------+-------------+ | Shi Zhongyu | Xie Yanke | | Shi Potian | Xi Ren | | Xie Yanke | Xu Zhu | | Ding Dian | Ding Dian | | Yu Yutong | Shi Zhongyu | +-------------+-------------+ 5 rows in set (0.00 sec)
子查詢:在查詢語句嵌套着查詢語句,基於某語句的查詢結果再次進行的查詢
用在WHERE子句中的子查詢: (1) 用於比較表達式中的子查詢;子查詢僅能返回單個值; MariaDB [hellodb]> SELECT Name,Age FROM students WHERE Age>(SELECT avg(Age) FROM students); +--------------+-----+ | Name | Age | +--------------+-----+ | Ding Dian | 32 | | Tian Boguang | 33 | | Shi Qing | 46 | | Xie Yanke | 53 | | Yinjiao King | 98 | | Sun Dasheng | 100 | +--------------+-----+ 6 rows in set (0.00 sec) MariaDB [hellodb]> EXPLAIN SELECT Name,Age FROM students WHERE Age>(SELECT avg(Age) FROM students); +------+-------------+----------+-------+---------------+------+---------+------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +------+-------------+----------+-------+---------------+------+---------+------+------+-------------+ | 1 | PRIMARY | students | range | Age | Age | 1 | NULL | 7 | Using where | | 2 | SUBQUERY | students | index | NULL | Age | 1 | NULL | 26 | Using index | +------+-------------+----------+-------+---------------+------+---------+------+------+-------------+ 2 rows in set (0.00 sec) (2) 用於IN中的子查詢:子查詢應該單鍵查詢並返回一個或多個值從構成列表; SELECT Name,Age FROM students WHERE Age IN (SELECT Age FROM teachers); (3) 用於EXISTS; 用於FROM子句中的子查詢; 使用格式:SELECT tb_alias.col1,... FROM (SELECT clause) AS tb_alias WHERE Clause; 示例: 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; +---------+---------+ | aage | ClassID | +---------+---------+ | 36.0000 | 2 | | 46.0000 | 5 | +---------+---------+ 2 rows in set (0.00 sec) 聯合查詢:UNION SELECT Name,Age FROM students UNION SELECT Name,Age FROM teachers; MariaDB [hellodb]> EXPLAIN SELECT Name,Age FROM students UNION SELECT Name,Age FROM teachers; +------+--------------+------------+------+---------------+------+---------+------+------+-------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +------+--------------+------------+------+---------------+------+---------+------+------+-------+ | 1 | PRIMARY | students | ALL | NULL | NULL | NULL | NULL | 26 | | | 2 | UNION | teachers | ALL | NULL | NULL | NULL | NULL | 4 | | | NULL | UNION RESULT | <union1,2> | ALL | NULL | NULL | NULL | NULL | NULL | | +------+--------------+------------+------+---------------+------+---------+------+------+-------+
查詢緩存:
如何判斷是否命中:
通過查詢語句的哈希值判斷:哈希值考慮的因素包括
查詢本身、要查詢的數據庫、客戶端使用協議版本,...
查詢語句任何字符上的不同,都會導致緩存不能命中;
哪此查詢可能不會被緩存?
查詢中包含UDF、存儲函數、用戶自定義變量、臨時表、mysql庫中系統表、或者包含列級權限的表、有着不確定值的函數(Now());
查詢緩存相關的服務器變量:
query_cache_min_res_unit: 查詢緩存中內存塊的最小分配單位;
較小值會減少浪費,但會導致更頻繁的內存分配操作;
較大值會帶來浪費,會導致碎片過多;
query_cache_limit:能夠緩存的最大查詢結果;
對於有着較大結果的查詢語句,建議在SELECT中使用SQL_NO_CACHE
query_cache_size:查詢緩存總共可用的內存空間;單位是字節,必須是1024的整數倍;
query_cache_type: ON, OFF, DEMAND
query_cache_wlock_invalidate:如果某表被其它的連接鎖定,是否仍然可以從查詢緩存中返回結果;默認值爲OFF,表示可以在表被其它連接鎖定的場景中繼續從緩存返回數據;ON則表示不允許;
查詢相關的狀態變量 SHOW GLOBAL STATUS LIKE 'Qcache%'; +-------------------------+----------+ | Variable_name | Value | +-------------------------+----------+ | Qcache_free_blocks | 1 | | Qcache_free_memory | 16759688 | | Qcache_hits | 0 | | Qcache_inserts | 0 | | Qcache_lowmem_prunes | 0 | | Qcache_not_cached | 0 | | Qcache_queries_in_cache | 0 | | Qcache_total_blocks | 1 | +-------------------------+----------+