欄位越多,查詢越慢嗎?為什麼
欄位越多,查詢通常會變慢。具體原因涉及資料庫內部的一些機制:
-
資料讀取:
每個查詢都需要從硬碟或者記憶體中讀取資料。欄位越多,每行的資料量越大,意味著更多的資料需要被讀取到記憶體中進行處理。這增加了IO操作次數和時間。 -
記憶體使用:
欄位越多,查詢的結果集越大,需要佔用更多的記憶體。對於複雜的查詢,資料庫可能需要在記憶體中儲存和處理大量資料,這會導致記憶體開銷增大,可能導致效能下降。 -
鎖和併發控制:
在多使用者環境中,欄位多的查詢可能會持有鎖更長時間,特別是如果這些欄位分佈在不同的行或頁面上。這可能會導致鎖爭用和等待,從而影響整體效能。
在關聯查詢時,比如A和B表是一對多關係,select * from A inner join B on A.id = B.A_id,資料庫在原理上是怎麼去查詢A和B的資料的,請一步步說明
- 掃描表 A: MySQL 會先從表 A 開始掃描資料。如果select的欄位和表A關聯欄位是同一個或者id欄位,那麼則會遍歷索引,而不是全表掃描
- 連線表 B: 對於表 A 的每一行資料,MySQL 會使用連線條件 A.id = B.A_id 在表 B 中進行匹配。這裡的連線方式(join type)取決於查詢計劃,常見的連線方式有巢狀迴圈連線(Nested Loop Join)和雜湊連線(Hash Join)。
巢狀迴圈連線: 對於表 A 的每一行資料,MySQL 會掃描表 B,並根據連線條件 A.id = B.A_id 查詢匹配的資料行。當B表的A_id有索引時,可以透過索引快速查詢B表資料,而不是全表掃描
雜湊連線: MySQL 會先構建一個雜湊表,將表 B 的連線列(B.A_id)雜湊化,然後在掃描表 A 時,透過雜湊表進行快速匹配。
- 提取資料: 對於每一個匹配的行,MySQL 會提取需要的欄位資料,並將匹配結果返回給客戶端。在 SELECT * 的情況下,會提取 A 表和 B 表的所有列。
笛卡爾積查詢如何實現?
比如A和B表都有10條記錄,如下SQL:
select * from A,B
查詢的結果會有100條記錄,相當兩個表相乘
為什麼推薦小表來join大表?
其實絕大部分情況下,from A表是走全表的,join表很多時候能走索引,因此儘量from表是小資料量表,join是大資料量表也可以快速查詢
7種SQLjoin寫法?
SELECT employee_id, department_ name
FROM employees e Inner JoIN departments d ON e.`department_id` = d. 'department_id `;
SELECT employee_id, department_name
FROM employees e
LEFT JoIN departments d ON e. `department_id` = d. department_id `;
SELECT employee_id, department_name
FROM employees e
RIGHT JoIN departments d ON e. `department_id` = d. department_id `;
SELECT employee_id, department_name
FROM employees e
LEFT JOIN departments d ON e. `department_id` = d.'department_id`
WHERE d. department_id IS NUL;
SELECT employee_id, department name
FROM employees e
RIGHT JOIN departments d ON e. `department_id = d. `department_id`
WHERE e.'department_id`IS NULL;
SELECT employee_id, department_name
FROM employees e
LEFT JoIN departments d ON e. `department_id` = d. department_id `;
union all
SELECT employee_id, department name
FROM employees e
RIGHT JOIN departments d ON e. `department_id = d. `department_id`
WHERE e.'department_id`IS NULL;
SELECT employee_id, department_name
FROM employees e
LEFT JOIN departments d ON e. `department_id` = d.'department_id`
WHERE d. department_id IS NUL;
union all
SELECT employee_id, department name
FROM employees e
RIGHT JOIN departments d ON e. `department_id = d. `department_id`
WHERE e.'department_id`IS NULL;
檢視的作用是什麼?為啥真實開發中很少見到建立檢視?
檢視並不是一張真實表,而是將各個真實表拼接展示的虛擬表,不過我們對檢視進行增加、更新、刪除,是能影響到實體表的。檢視的出現是為了讓一些人員不能看到真實表的某一些欄位,比如表A有工資等敏感欄位,不希望開發人員能看到這張表的全部資料,那麼就可以根據A建立檢視,讓開發人員看這張檢視即可
在中小型企業中,其實對資訊保安這塊不是很嚴格,往往開發人員是可以直接看到表的全部欄位資料的,所以就不需要建立檢視。但在一些大型企業,檢視還是挺常見到的
預設字符集?
在MysQL 8.0版本之前,預設字符集為latin1,utf8字符集指向的是utf8mb3。網站開發人員在資料庫設計的時候往往會將編碼修改為utf8字符集。如果遺忘修改預設的編碼,就會出現亂碼的問題。從MySQL 8.0開始,資料庫的預設編碼將改為utf8mb4,從而避免上述亂碼的問題。
utf8字符集是什麼?
utf8與utf8mb4
utf8字符集表示一個字元需要使用14個位元組,但是我們常用的一些字元使用13個位元組就可以表示了。而字符集表示一個字元所用的最大位元組長度,在某些方面會影響系統的儲存和效能,所以設計MysQL的設計者偷偷的定義了兩個概念:
utf8mb3︰閹割過的utf8字符集,只使用1~3個位元組表示字元。
utf8mb4 :正宗的utf8字符集,使用1~4個位元組表示字元。
在MysQL中utf8是utf8mb3的別名,所以之後在MysQL中提到utf8就意味著使用1~3個位元組來表示一個字元。如果大家有使用4位元組編碼一個字元的情況,比如儲存一些emoji表情,那請使用utf8mb4 。
比較規則是什麼?
Mysql,什麼SQL語句下會出現鎖表情況
- DDL 操作
任何修改表結構的操作都會鎖住表,例如:
ALTER TABLE:修改表結構,如增加或刪除列。
DROP TABLE:刪除表。
TRUNCATE TABLE:清空表資料。
總結:最好在資料庫低峰的時候進行ALTER TABLE操作。
2. 全表掃描的 DML 操作
如果在沒有索引的情況下對錶進行全表掃描的操作,可能會導致表鎖,例如:
UPDATE:對錶中所有行進行更新。
DELETE:刪除表中所有行。
總結:每次寫update語句時,保證where是有索引的。在事務開啟下,多次對同一張表執行相同的update語句不會鎖表,但會鎖行,因此儘量縮短事務時間。
- 大量資料操作
在表上執行大規模資料操作也可能導致鎖表,例如:
大批次的 INSERT 操作。
總結:一次性插入的數量不宜太多
- 行鎖升級為表鎖
在 InnoDB 儲存引擎中,如果行鎖的數量過多,也可能會升級為表鎖,例如:
多行更新操作 UPDATE,涉及的行數特別多時。
總結:儘量確保每次更新的資料行不會太多