sql管理:索引超出范围必须为非负值并小于集合大小_java面试基础知识-数据库基础知识(数据库索引部分)...
1.1數據庫架構:
如何設計一個關系型數據庫?
存儲模塊(文件系統)用塊或者頁作為存儲單位
程序實例:
存儲管理
緩存機制 不宜過大,要有淘汰機制
SQL解析
日志管理
權限劃分
容災機制
索引管理
鎖管理
1.2 索引
為什么要使用索引?
全表掃描:
數據庫存儲用塊或者頁存儲,全表掃描時,需要將整個表加載到緩存中,當數據量很小的時候,緩存可以一次加載所有數據量,全表掃描就會比較快,而當數據量很大需要緩存多次加載,就會很慢,這個時候就要用到索引。
索引來源于字典,將關鍵信息集中起來,快速查找數據
因為索引能夠避免全表掃描查找數據,提升檢索效率
什么樣的信息能成為索引?
能把該記錄限定在一定查找范圍中的字段
主鍵,唯一鍵以及普通鍵 能夠讓數據具備一定區分度的字段
索引的數據結構?
主流是B+Tree,還有Hash結構 bitMap索引,其中MySql不支持BitMap索引,同時基于MyISAM 或 InnoDB的MySql不支持Hash
二叉查找樹:
有左右子樹,對于樹中的節點值X 他的左子樹的任意節點值小于X,右字數任意節點值大于X,時間復雜度O(logn)
但在插入過程中可能會產生以下問題 導致IO次數變多時間復雜度變為O(n),比全表掃描都要慢得多
B-Tree (通過合并上移下移來保證特征)
特征:
根節點至少包括兩個孩子
樹中每個節點最多含有M個孩子(m>=2)
除根節點和葉節點外,其他每個節點至少有ceil(m/2)個孩子
所有終端葉子節點都位于同一層(即葉子節點高度一致)
假設每個非終端結點中包含N個關鍵字信息,其中1)Ki(i=1...n)為關鍵字,且關鍵字按順序升序排序K(i-1)<Ki, 2)關鍵字的個數N必須滿足:{cell(m/2)-1} <= n <= m-1,3)非葉子結點的指針P[1],P[2] P[3]... P[M]其中P[1]指向關鍵字小于K[1]的子樹,P[m]指向關鍵字大于K[m-1]的子樹,其他P[i]指向關鍵字屬于(K[i-1],k[i])的子樹
B+-Tree (B-Tree 的變體)
非葉子節點的子樹指針與關鍵字個數相同
非葉子節點得子樹指針P[I],指向關鍵字【K[i],K[i+1]】的子樹
非葉子節點僅用來做索引,數據保存在葉子節點中,即非葉子節點值和葉子節點值可能相同(保證樹更矮)
所有葉子節點均有一個鏈指針指向下一個葉子節點并按大小順序鏈接(可以方便橫向跨子樹進行統計,比如n>10 會直接統計10以后的葉子節點而不統計10以前的)
結論:
B+Tree更適合用于做存儲索引
1)B+樹的磁盤讀寫代價更低,B+樹的內部結構沒有存儲指向關鍵字具體信息的指針,所容納的關鍵字多,一次IO可讀取關鍵字數量更多。
2)B+樹的查詢效率更加穩定,由于非終端點并不是最終指向文件內容的結點,而只是葉子結點中關鍵字的索引。所以任何關鍵字的查找必須走一條從根結點到葉子結點的路。所有關鍵字查詢的路徑長度相同,導致每一個數據的查詢效率相當。
3)B+樹更有利于數據庫的掃描,只需要遍歷節點就可以完成對整個數據庫數據的掃描查找
Hash索引(理論上高于B+Tree):不穩定不支持線性查詢
存放通過HASH算法計算出來的Hash值和行指針
優點
根據Hash的運算可以一次查找到數據所在的鏈表
缺點
僅僅能滿足“=”,“in”,不能使用范圍查詢
無法被用來避免數據的排序操作
(HASH索引比較的是Hash算法計算后的值,不能保證和原有順序(大小)一致)
組合索引中Hash是用組合全部索引值的方式進行查找的,無法通過組合索引中的部分索引鍵進行查詢
無法避免表掃描,不同索引鍵可能存在相同索引值,需要通過訪問實際數據進行比較
遇到大量Hash值相等的情況后,性能并不一定就會比B-Tree索引高(有可能出現極端情況,即很多不同數據計算出的索引值都一樣變成線性存儲結構)
BitMap(位圖)索引:
存儲時按照狀態分開,每個數據是否是這個值,按位存儲
只適用于某個字段的值只有某種幾個的情況
鎖力度較大,不適合高并發聯機系統,適用于并發低但是統計多的。
密集索引和稀疏索引的區別:
密集索引文件中的每個搜索碼值都對應一個索引值,葉子節點不僅僅保存鍵值 并且保存了位于同一行記錄里的其他列的信息,由于密集索引決定了一個表的物理排序,一個表只能有一個物理排列順序故只能創建一個密集索引
稀疏索引文件只為索引碼的某些值建立索引項,葉子節點僅保存鍵位信息和該行指針地址(或主鍵)定位到葉子后通過地址或主鍵尋找
存儲引擎:
MyISAM 索引和數據是分開存儲的 (更適合大量的查詢操作)
InnoDB 索引和數據是一起存儲的 (支持事務 支持行級鎖 set update更快)
有且僅有一個密集索引
如果一個主鍵被定義,該主鍵作為密集索引
如果沒有主鍵被定義,該表的第一個唯一非空索引作為密集索引
若不滿足以上條件,innodb會在內部生成一個隱藏主鍵
非主鍵索引存儲箱關鍵為何其對應的主鍵值,兩次查找(查找次級索引自身,再查找主鍵索引或者物理索引索引)
如何定位并優化慢SQL?
該題目比較看經驗
1)根據慢日志定位慢查詢SQL(數據定義語言不會進入慢查詢
慢日志:記錄執行比較慢的SQL 執行命令:Show variables like‘ %quer%’
從上到下分別是:
SQL執行時間即超過多少時間算執行較慢,會記錄超過這個時間的慢查詢
慢日志開關:set global slow_query_log= on;
慢日志路徑:set global long_query_time=1;(此句變量需要重連數據庫后才生效)
使用命令修改后再重啟數據庫服務后會回復默認,可以在配置文件中修改
2)使用explain等工具分析sql:
顯示了mysql如何使用索引來處理select語句以及連接表。可以幫助選擇更好的索引和寫出更優化的查詢語句
type:mysql找到數據行的方式 最優—>最差(紅字需要優化)
extra:中出現以下兩項表示mysql沒有使用索引
3+)修改sql(減少使用*,減少使用模糊查詢)或者使SQL盡量走索引(like‘%趙%’這種形式不會走索引,但是like‘趙%會走索引’、強制索引等)
mysql的查詢優化器會盡可能的使用索引并且使用最嚴格的索引消除盡可能多的數據行,最終目標是提交SQL語句查詢數據行而不是排除數據行,sql優化器試圖排除語句的目的在于排除數據行的素的越快,找到與條件匹配的數據行就越快,sql優化器會判斷密集索引的葉子結點會帶有數據,效率可能會低,故選擇稀疏索引(有時候不一定會最優)。
聯合索引的最左匹配原則的成因?
最左匹配原則:對于索引(A,B),有where A=1會走該索引,where A=1and B=1也會走該索引,where B=1則不會走該索引;
mysql會一直向右匹配直到遇到范圍查詢(<,>,between,like)就停止匹配,比如a=3 and b=2 and c>5 and d=6,如果建立(abcd)順序的索引,d是用不到索引的,如果建立(abdc)順序的索引,abdc的索引都可以用到,abd 的順序可以任意調整;=和in可以亂序,比如a=1 and b=2 and c=3 建立(abc)索引可以任意順序,musql的查詢優化器會幫你優化成索引可以識別的形式。
mysql創建聯合索引會對復合索引的第一個索引字段排序在此基礎上再對第二個字段排序,其中第一個字段是有序的,第二個字段是無序的、所以用第一個字段是可以用到索引的,單獨用第二個字段是用不到索引的
從col3,col2,col1做索引會做出下圖所示的索引,單使用col2無法走索引。
索引是建立的越多越好嗎?
1)否定的,物極必反,數據量小的表不需要建立索引,建立會增加額外的索引開銷
2)數據變更需要維護索引,更多的索引意味著更多的維護成本
3)更多的索引意味著需要更多的空間。
總結
以上是生活随笔為你收集整理的sql管理:索引超出范围必须为非负值并小于集合大小_java面试基础知识-数据库基础知识(数据库索引部分)...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Win11黑夜模式在哪开启 Win11黑
- 下一篇: mysql以user1登录_在mysql