21、MySQL 聯結器
首先需要在
MySQL
客戶端登入才能使用,所以需要一個聯結器來連線使用者和
MySQL
資料庫,我們一般是使用如下命令:
mysql -u 使用者名稱 -p 密碼
來進行
MySQL
登入,和伺服器建立連線,在完成
TCP
握手後,聯結器會根據你輸入的使用者名稱和密碼驗證你的登入身份。
如果使用者名稱或者密碼錯誤,
MySQL
就會提示
Access denied for user
來結束執行。如果登入成功後,
MySQL
會根據許可權表中的記錄來判定你的許可權。
22、MySQL 查詢快取
連線完成後,你就可以執行
SQL
語句了,這行邏輯就會來到第二步:
查詢快取
。
MySQL
在得到一個執行請求後,會首先去查詢快取中查詢,是否執行過這條
SQL
語句,之前執行過的語句以及結果會以
key-value
對的形式,被直接放在記憶體中。
key
是查詢語句,
value
是查詢的結果。如果透過
key
能夠查詢到這條
SQL
語句,就直接返回
SQL
的執行結果。
如果語句不在查詢快取中,就會繼續後面的執行階段。執行完成後,執行結果就會被放入查詢快取中。
可以看到,如果查詢命中快取,
MySQL
不需要執行後面的複雜操作,就可以直接返回結果,效率會很高。
23、MySQL 分析器
如果沒有命中查詢,就開始執行真正的
SQL
語句。
首先,
MySQL
會根據你寫的
SQL
語句進行解析,分析器會先做詞法分析,你寫的
SQL
就是由多個字串和空格組成的一條
SQL
語句,
MySQL
需要識別出裡面的字串是什麼,代表什麼。
然後進行語法分析,根據詞法分析的結果,語法分析器會根據語法規則,判斷你輸入的這個
SQL
語句是否滿足
MySQL
語法。如果
SQL
語句不正確,就會提示
You have an error in your SQL syntax
24、MySQL 最佳化器
經過分析器的詞法分析和語法分析後,你這條
SQL
就合法了,
MySQL
就知道你要做什麼了。
但是在執行前,還
需要進行最佳化器的處理
,最佳化器會判斷你使用了哪種索引,使用何種連線方式,最佳化器的作用就是確定效率最高的執行方案。
25、MySQL 執行器
MySQL
透過分析器知道了你的
SQL
語句是否合法,你想要做什麼操作,透過最佳化器知道了該怎麼做效率最高,然後就進入了執行階段,開始執行這條
SQL
語句。
在執行階段,MySQL 首先會判斷你有沒有執行這條語句的許可權,沒有許可權的話,就會返回沒有許可權的錯誤。如果有許可權,就開啟表繼續執行。
開啟表的時候,執行器就會根據表的引擎定義,去使用這個引擎提供的介面。對於有索引的表,執行的邏輯也差不多。
26、什麼是臨時表,何時刪除臨時表?
什麼是臨時表?
MySQL
在執行
SQL
語句的,通常會臨時建立一些儲存中間結果集的表,臨時表只對當前連線可見,在連線關閉時,臨時表會被刪除並釋放所有空間。
臨時表分為兩種:
一種是記憶體臨時表
,
一種是磁碟臨時表
,什麼區別呢?記憶體臨時表使用的是
MEMORY
儲存引擎,而臨時表採用的是
MyISAM
儲存引擎。
MySQL
會在下面這幾種情況產生臨時表。
使用 UNION 查詢
:
UNION
有兩種,一種是
UNION
,一種是
UNION ALL
, 它們都用於聯合查詢;區別是使用
UNION
會去掉兩個表中的重複資料,相當於對結果集做了一下去重(
distinct
)。使用
UNIONALL
,則不會排重,返回所有的行。使用
UNION
查詢會產生臨時表。
使用 TEMPTABLE 演算法或者是 UNION 查詢中的檢視
。
TEMPTABLE
演算法是整片建立臨時表的演算法,它是將結果放置到臨時表中,意味著
MySQL
要先建立好一個臨時表,然後將結果放到臨時表中去,然後再使用這個臨時表進行相應的查詢。
ORDER
和
GROUPBY
的子句不一樣時會產生臨時表。
DISTINCT
查詢並且加上
ORDER BY
時;
SQL
中用到
SQL_SMALL_RESULT
選項時,如果查詢結果比較小的時候,可以加上
SQL SMALL RESULT
來最佳化,產生臨時表。
FROM
中的子查詢;
EXPLAIN
檢視執行計劃結果的
extra
列中,如果使用
Using temporary
就表示會用到臨時表。
27、談談 SQL 最佳化的經驗
查詢語句無論是使用哪種判斷條件等於、小於、大於,
WHERE
左側的條件查詢欄位不要使用函式或者表示式。
使用
EXPLAIN
命令最佳化你的
SELECT
查詢,對於複雜、效率低的
SQL
語句,我們通常是使用
explainsql
來分析這條
sql
語句,這樣方便我們分析,進行最佳化。
當你的
SELECT
查詢語句只需要使用一條記錄時,要使用
LIMIT 1
。不要直接使用
SELECT *
,而應該使用具體需要查詢的表達欄位,因為使用
EXPLAIN
進行分析時,
SELECT *
使用的是全表掃描,也就是
type=all
。
為每一張表設定一個
ID
屬性
避免在
WHERE
子句中對欄位進行
NULL
判斷避免在
WHERE
中使用
!
或
>
運算子
使用
BETWEEN AND
替代
IN
為搜尋欄位建立索引
選擇正確的儲存引擎,
InnoDB、MyISAM、MEMORY
等
使用
LIKE %abc%
不會走索引,而使用
LIKE abc%
會走索引
對於列舉型別的欄位(即有固定羅列值的欄位),建議使用
ENUM
而不是
VARCHAR
,如性別、星期、型別、類別等。
拆分大的
DELETE
或
INSERT
語句
選擇合適的欄位型別,選擇標準是儘可能小、儘可能定長、儘可能使用整數。
欄位設計儘可能使用
NOT NULL
進行水平切割或者垂直分割
28、什麼叫外連線?
外連線分為三種,分別是
左外連線
(
LEFT OUTER JOIN
或
LEFT JOIN
)、
右外連線
(
RIGHT OUTER JOIN
或
RIGHT JOIN
)、
全外連線
(
FULL OUTER JOIN
或
FULLJOIN
)。
左外連線
:又稱為左連線,這種連線方式會
顯示左表不符合條件的資料行
,右邊不符合條件的資料行直接顯示
NULL
右外連線
:也被稱為右連線,他與左連線相對,這種連線方式會
顯示右表不符合條件的資料行
,左表不符合條件和資料行直接顯示
NULL
29、什麼叫內連線?
結合兩個表中
相同的欄位
,返回關聯欄位相符的記錄就是
內連線
內連線
30、使用 union 和union all 時需要注意些什麼?
透過
union
連線的
SQL
分別單獨取出的列數必須相同。
使用
union
時,多個相等的行將會被合併,由於合併比較耗時,一般不直接使用
union
進行合併,而是通常採用
union all
進行合併。
31、MyISAM 儲存引擎的特點
在 5。1 版本之前,
MyISAM
是
MySQL
的預設儲存引擎,
MyISAM
併發性比較差,使用的場景比較少主要特點是:
不支援事務操作
,
ACID
的特性也就不存在了,這一設計是為了效能和效率考慮的。
不支援外來鍵操作
,如果強行增加外來鍵,
MySQL
不會報錯,只不過外來鍵不起作用。
MyISAM
預設的鎖粒度是表級鎖
,所以併發效能比較差,加鎖比較快,鎖衝突比較少,不太容易產生死鎖的情況。
MyISAM
會在磁碟上儲存三個檔案,檔名和表名相同,副檔名分別是
frm
(儲存表定義)、
MYD
(
MYData
,儲存資料)、
MYI
(
MyIndex
,儲存索引)。這裡需要特別注意的是
MyISAM
只快取索引檔案,並不快取資料檔案
。
MyISAM
支援的索引型別有全域性索引(
Full-Text
)、
B-Tree
索引、
R-Tree
索引
Full-Text 索引
:它的出現是為了解決針對廣西的模糊查詢效率較低的問題。
B-Tree 索引
:所有的索引節點都按照平衡樹的資料結構來儲存,所有的索引資料節點都在葉節點。
R-Tree 索引
:它的儲存方式和
B-Tree
索引有一些區別,主要設計用於儲存空間和多維資料的欄位做索引目前的
MySQL
版本僅支援
geometry
型別的欄位作索引,相對於
BTREE
,
RTREE
的優勢在於範圍查詢。
資料庫所在的主機如果宕機,
MyISAM
的資料檔案容易損壞,而且難以恢復。
增刪改查效能方面:
SELECT
效能較高,適用於查詢較多的情況
32、InnoDB 儲存引擎的特點
自從
MySQL5。1
之後,預設的儲存引擎變成了
InnoDB
儲存引擎,相對於
MyISAM
,
InnoDB
儲存引擎有了較大的改變,它的主要特點是:
支援事務操作
,具有事務
ACID
隔離特性,預設的隔離級別是可重複讀(
repeatable-read
)、透過
MVCC
(併發版本控制)來實現的。能夠解決髒讀和不可重複讀的問題。
InnoDB
支援外來鍵操作。
InnoDB
預設的鎖粒度行級鎖
,併發效能比較好,會發生死鎖的情況。
和
MyISAM
一樣的是,
InnoDB
儲存引擎也有
frm
檔案儲存表結構定義,但是不同的是,
InnoDB
的表資料與索引資料是儲存在一起的,都位於
B+
樹的葉子節點上,而
MyISAM
的表資料和索引資料是分開的。
InnoDB 有安全的日誌檔案
,這個日誌檔案用於恢復因資料庫崩潰或其他情況導致的資料丟失問題,保證資料的一致性。
InnoDB
和
MyISAM
支援的索引型別相同
,但具體實現因為檔案結構的不同有很大差異。
增刪改查效能方面,
如果執行大量的增刪改操作,推薦使用 InnoDB 儲存引擎
,它在刪除操作時是對行刪除,不會重建表。
更多程式設計乾貨,請關注我