MySQL
資料庫指定哪些索引,都說說
普通索引,唯一索引,主鍵索引,全文索引
使用索引的優點
- 提高資料的搜索速度
- 加快表與表之間的連接速度
- 在資訊檢索程序中,若使用分組及排序子句進行時,通過建立索引能有效的減少檢索程序中所需的分組及排序時間,提高檢索效率,
使用索引的缺點
- 在我們建立資料庫的時候,需要花費的時間去建立和維護索引,而且隨著資料量的增加,需要維護它的時間也會增加,
- 在創建索引的時候會占用存盤空間
- 在我們需要修改表中的資料時,索引還需進行動態的維護,所以對資料庫的維護帶來了一定的麻煩,
唯一索引: 在創建唯一索引時要不能給具有相同的索引值
主鍵索引: 在我們給一個欄位設定主鍵的時候,它就會自動創建主鍵索引,用來確保每一個值都是唯一的
聚集索引: 我們在表中添加資料的順序,與我們創建索引值相同,而且一個表中只能有一個聚集索引
普通索引: 它的結構主要以B+樹和哈希索引為主,主要是對資料表中的資料進行精確查找
全文索引: 它的作用是搜索資料表中的欄位不是包含我們的關鍵字,就像索引引擎中的模糊查詢,
什么是回表知道嗎
比如一個資料庫索引有一級索引和二級索引,二級索引葉子節點存盤的是主鍵,一級索引存盤的是主鍵和資料,通過二級索引查找到主鍵后再到一級索引通過已知主鍵查找資料,需要查找兩次,這就是索引,
非聚集索引一定會回表查詢嗎?
不一定,這涉及到查詢陳述句所要求的欄位是否命中了索引,如果全部命中了索引,那么就不必要再進行回表查詢,
舉個簡單的例子:假設我們在員工表的年齡上建立了索引,那么當進行 select age from employee where age < 20 的查詢時,在索引的葉子節點上,已經包含了age資訊,不會再次進行回表查詢
知道聯合索引為什么要注意索引的順序嗎?
MySQL使用索引時需要索引有序,假設現在建立了”name,age,school“的聯合索引,那么索引的排序為:先按照name排序,如果name相同,則按照age排序,如果age的值相等,則按照school進行排序,當進行查詢時,此時索引僅僅按照嚴格有序,因此必須首先使用name欄位進行等值查詢,之后對于匹配到的列而言,其按照age欄位嚴格有序,此時可以使用age欄位做索引查詢…以此類推,因此建立聯合索引的時候應該注意索引列的順序,一般情況下,將查詢需求頻繁或者欄位高的列放在前面,此外可以根據帶列的查詢或者表結構進行單獨的調整,
資料庫事務的四大特性
A=Atomicity
原子性,一個事務要么全部成功 ,要么全部失敗,不可能只執行一部分操作
C=Consistency
一致性,系統(資料庫)總是從一個一致性狀態移到另一個一致性狀態,不會存在中間態
所有事務對資料的讀取都是一致性的,
I=Isolation
隔離性:通常來說,一個事務未完全提交之前,對其他事務是不可見的,
D=Durability
持久性,一旦事務提交,那么就永遠是這樣子,那么資料庫奔潰,寫入磁盤中
多個事務同時進行時會造成什么問題?
臟讀:A事務讀取到了B事務未提交的內容,而B事務后面進行了回滾
不可重復讀:當設定A事務只能讀取B事務已經提交的部分,會造成A事務內的兩次查詢,結果竟然不一樣,因為在此期間B事務進行了操作
幻讀:A事務讀取了一個范圍的內容,而同時B事務在此期間插入了一條資料,造成幻覺
如何解決以上的問題呢
MySQL的四種隔離級別如下:
未提交讀(READ UNCOMMITTED)
這就是上面所說的例外情況了,這個隔離級別下,其他事務可以看到本事務沒有提交的部分修改.因此會造成臟讀的問題(讀取到了其他事務未提交的部分,而之后該事務進行了回滾).
這個級別的性能沒有足夠大的優勢,但是又有很多的問題,因此很少使用.
已提交讀(READ COMMITTED)
其他事務只能讀取到本事務已經提交的部分.這個隔離級別有 不可重復讀的問題,在同一個事務內的兩次讀取,拿到的結果竟然不一樣,因為另外一個事務對資料進行了修改.
REPEATABLE READ(可重復讀)
可重復讀隔離級別解決了上面不可重復讀的問題(看名字也知道),但是仍然有一個新問題,就是 幻讀,當你讀取id> 10 的資料行時,對涉及到的所有行加上了讀鎖,此時例外一個事務新插入了一條id=11的資料,因為是新插入的,所以不會觸發上面的鎖的排斥,那么進行本事務進行下一次的查詢時會發現有一條id=11的資料,而上次的查詢操作并沒有獲取到,再進行插入就會有主鍵沖突的問題.
SERIALIZABLE(可串行化)
這是最高的隔離級別,可以解決上面提到的所有問題,因為他強制將所以的操作串行執行,這會導致并發性能極速下降,因此也不是很常用.
對MySQL有了解嗎?
從鎖的類別上來講,有共享鎖和排他鎖.
- 共享鎖: 又叫做讀鎖. 當用戶要進行資料的讀取時,對資料加上共享鎖.共享鎖可以同時加上多個.
- 排他鎖: 又叫做寫鎖. 當用戶要進行資料的寫入時,對資料加上排他鎖.排他鎖只可以加一個,他和其他的排他鎖,共享鎖都相斥.
用上面的例子來說就是用戶的行為有兩種,一種是來看房,多個用戶一起看房是可以接受的. 一種是真正的入住一晚,在這期間,無論是想入住的還是想看房的都不可以.
鎖的粒度取決于具體的存盤引擎,InnoDB實作了行級鎖,頁級鎖,表級鎖.
他們的加鎖開銷從大大小,并發能力也是從大到小.
為什么不使用UUID?
因為在InnoDB存盤引擎中,主鍵索引是作為聚簇索引存在的,也就是說,主鍵索引的B+樹葉子節點上存盤了主鍵索引以及全部的資料(按照順序),如果主鍵索引是自增ID,那么只需要不斷向后排列即可,如果是UUID,由于到來的ID與原來的大小不確定,會造成非常多的資料插入,資料移動,然后導致產生很多的記憶體碎片,進而造成插入性能的下降.
固定長度的字串比如身份證號應該用什么欄位存盤好呢,說說原因,
用戶身份證號等固定長度的字串應該使用char而不是varchar來存盤,這樣可以節省空間且提高檢索效率.
char是一個定長欄位,假如申請了char(10)的空間,那么無論實際存盤多少內容.該欄位都占用10個字符,而varchar是變長的,也就是說申請的只是最大長度,占用的空間為實際字符長度+1,最后一個字符存盤使用了多長的空間.
在檢索效率上來講,char > varchar,因此在使用中,如果確定某個欄位的值的長度,可以使用char,否則應該盡量使用varchar.例如存盤用戶MD5加密后的密碼,則應該使用char.
InnoDB和MyISAM的區別?
- InnoDB支持事物,而MyISAM不支持事物
- InnoDB支持行級鎖,而MyISAM支持表級鎖
- InnoDB支持MVCC, 而MyISAM不支持
- InnoDB支持外鍵,而MyISAM不支持
- InnoDB不支持全文索引,而MyISAM支持
關心過業務系統里面的sql耗時嗎?一般你會怎么考慮優化?
在業務系統中,除了使用主鍵進行的查詢,其他的我都會在測驗庫上測驗其耗時,慢查詢的統計主要由運維在做,會定期將業務中的慢查詢反饋給我們.
慢查詢的優化首先要搞明白慢的原因是什么? 是查詢條件沒有命中索引?是load了不需要的資料列?還是資料量太大?
所以優化也是針對這三個方向來的:
首先分析陳述句,看看是否load了額外的資料,可能是查詢了多余的行并且拋棄掉了,可能是加載了許多結果中并不需要的列,對陳述句進行分析以及重寫.
分析陳述句的執行計劃,然后獲得其使用索引的情況,之后修改陳述句或者修改索引,使得陳述句可以盡可能的命中索引.
如果對陳述句的優化已經無法進行,可以考慮表中的資料量是否太大,如果是的話可以進行橫向或者縱向的分表.
表設計的時候遵循范式,說一說三個范式,
第一范式: 每個列都不可以再拆分. 第二范式: 非主鍵列完全依賴于主鍵,而不能是依賴于主鍵的一部分. 第三范式: 非主鍵列只依賴于主鍵,不依賴于其他非主鍵.
在設計資料庫結構的時候,要盡量遵守三范式,如果不遵守,必須有足夠的理由.比如性能. 事實上我們經常會為了性能而妥協資料庫的設計.
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/179157.html
標籤:其他
上一篇:學習記錄
下一篇:解決:Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException:
