數據庫面試知識點(五)數據庫優化

一、優化介紹

在這裏插入圖片描述
數據結構、SQL、索引是成本最低,且效果最好的優化手段。


二、優化方向

1. SQL 以及索引的優化

首先要根據需求寫出結構良好的 SQL,然後根據 SQL 在表中建立有效的索引。但是如果索引太多,不但會影響寫入的效率,對查詢也有一定的影響。

2. 合理的數據庫設計

(1)根據數據庫三範式來進行表結構的設計。設計表結構時,就需要考慮如何設計才能更有效的查詢。

數據庫三範式:

  • 第一範式:數據表中每個字段都必須是不可拆分的最小單元,也就是確保每一列的原子性;
  • 第二範式:滿足一範式後,表中每一列必須有唯一性,都必須依賴於主鍵
  • 第三範式:滿足二範式後,表中的每一列只與主鍵直接相關而不是間接相關 (外鍵也是直接相關),字段沒有冗餘。

(2)有時候可以根據場景合理地反規範化:

  • 分割表
  • 保留冗餘字段。當兩個或多個表在查詢中經常需要連接時,可以在其中一個表上增加若干冗餘的字段,以 避免表之間的連接過於頻繁,一般在冗餘列的數據不經常變動的情況下使用。
  • 增加派生列。派生列是由表中的其它多個列的計算所得,增加派生列可以減少統計運算,在數據彙總時可以大大縮短運算時間。

(3)數據庫五大約束:

  • PRIMARY key: 設置主鍵約束;
  • UNIQUE:設置唯一性約束,不能有重複值;
  • DEFAULT 默認值約束
  • NOT NULL:設置非空約束,該字段不能爲空;
  • FOREIGN key : 設置外鍵約束。

(4)字段類型選擇:

  • 儘量使用 TINYINT、SMALLINT、MEDIUM_INT 作爲整數類型而非 INT,如果非負則加上 UNSIGNED
  • VARCHAR 的長度只分配真正需要的空間
  • 使用枚舉或整數代替字符串類型
  • 儘量使用 TIMESTAMP 而非 DATETIME
  • 單表不要有太多字段,建議在 20 以內
  • 避免使用 NULL 字段,很難查詢優化且佔用額外索引空間

3.優化的步驟

(1)代碼優化

第一步就應該是分析相關的代碼,找出相應的瓶頸,再來考慮具體的優化策略。有一些性能問題,完全是由於代碼寫的不合理,通過直接修改一下代碼就能解決問題的,比如 for 循環次數過多、作了很多無謂的條件判斷、相同邏輯重複多次等。

(2)定位慢 SQL,並優化

由自帶的慢查詢日誌或者開源的慢查詢系統定位到具體的出問題的 SQL,然後使用 explain、profile 等工具來逐步調優,最後經過測試達到效果後上線。

  • slow_query_log 慢查詢開啓狀態。

  • slow_query_log_file 慢查詢日誌存放的位置(這個目錄需要 MySQL 的運行帳號的可寫權限,一般設置爲 MySQL 的數據存放目錄)。

  • long_query_time 查詢超過多少秒才記錄。

當在配置文件中開啓慢查詢日誌記錄之後,就會在指定的存放目錄生成日誌文件。


三、優化方案

(一)語句優化

  • 連續數值條件,用 BETWEEN 不用 IN:SELECT id FROM t WHERE num BETWEEN 1 AND 5
  • Update 語句,如果只更改 1、2 個字段,不要 Update 全部字段,否則頻繁調用會引起明顯的性能消耗
  • 儘量使用數字型字段,若只含數值信息的字段儘量不要設計爲字符型
  • 不建議使用 select * from t ,用具體的字段列表代替 “*”,不要返回用不到的任何字段。儘量避免向客戶端返回大數據量,若數據量過大,應該考慮相應需求是否合理
  • 表與表之間通過一個冗餘字段來關聯,要比直接使用 JOIN 有更好的性能
  • select count (*) from table;這樣不帶任何條件的 count 會引起全表掃描
  • 在搜索字符型字段時,我們有時會使用 LIKE 關鍵字和通配符,這種做法雖然簡單,但卻也是以犧牲系統性能爲代價的。

(二)合理使用索引

索引一般情況下都是高效的。但是由於索引是以空間換時間的一種策略,索引本身在提高查詢效率的同時會影響插入、更新、刪除的效率,頻繁寫的表不宜建索引。

1.索引類型

  • 主鍵索引 (PRIMARY KEY)
  • 唯一索引 (UNIQUE)
  • 普通索引 (INDEX)
  • 組合索引 (INDEX)
  • 全文索引 (FULLTEXT)

2.注意

  • 在建有索引的字段上儘量不要使用函數進行操作。
  • 儘量不要在 where 子句中對字段進行 null 值判斷或者使用!= 或 <> 操作符,否則將導致引擎放棄使用索引而進行全表掃描

(三)分表

1.分表方式

水平分割(按行)、垂直分割 (按列)

2.分表場景

  • 根據經驗,mysql 表數據一般達到百萬級別,查詢效率就會很低。
  • 一張表的某些字段值比較大並且很少使用。可以將這些字段隔離成單獨一張表,通過外鍵關聯,例如考試成績,我們通常關注分數,不關注考試詳情。

3.水平分表策略

  • 按時間分表:當數據有很強的實效性,例如微博的數據,可以按月分割。
  • 按區間分表:例如用戶表 1 到一百萬用一張表,一百萬到兩百萬用一張表。
  • hash 分表:通過一個原始目標 id 或者是名稱按照一定的 hash 算法計算出數據存儲的表名。

【Java 面試那點事】

這裏致力於分享 Java 面試路上的各種知識,無論是技術還是經驗,你需要的這裏都有!

這裏可以讓你【快速瞭解 Java 相關知識】,並且【短時間在面試方面有跨越式提升】

面試路上,你不孤單!
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章