資料庫 索引

2021-06-21 00:08:40 字數 2651 閱讀 9996

索引是對資料庫表中乙個或多個列(例如,employee 表的姓氏 (lname) 列)的值進行排序的結構。如果想按特定職員的姓來查詢他或她,則與在表中搜尋所有的行相比,索引有助於更快地獲取資訊。

例如這樣乙個查詢:select * from table1 where id=10000。如果沒有

索引,必須遍歷整個表,直到id等於10000的這一行被找到為止;有了索引之後(必須是在id這一列上建立的索引),在索引中查詢,但索引是經過某種演算法優化過的,查詢次數要少的多的多。可見,

索引是用來定位的。

索引分為

聚簇索引

非聚簇索引兩種,聚簇索引 (clustered index)是按照資料存放的物理位置為順序的,而非聚簇索引(nonclustered index)就不一樣了;聚簇索引能提高多行檢索的速度,而非聚簇索引對於單行的檢索很快。

1,建立索引一定會減少查詢時間嗎?也就是提高查詢效率

2,乙個系統,你使用了一年後,系統響應突然變慢了,請分析變慢的原因

3,有乙個很大的表,建立索引一般需要注意些什麼,在什麼字段合理?

如果是面dba,這三個大概是:

1.請解釋一下表的儲存以及聚集和非聚集索引結構。

2.如果系統變慢,你如何針對db做乙個論斷檢查?如何確定是cpu、記憶體、io有瓶頸?請舉例你之前優化過的成功案例及解決方法。

3.你以前接觸的業務的核心表有多大?有多少索引?建乙個索引大概有多久?

下面是我對問題的想法,首先是上面的3個問題:

1、建立索引不一定能減少查詢時間。因為如果建立的索引不合適,查詢時生成的查詢計畫不一定會用到這個索引,當然也有可能會用這個索引。如果資料量不大,那麼索引的作用不大,如果資料量很大,那麼如果查詢計畫使用了這個不適合的索引,說不定還是能提公升效率的,當然也有可能變的更慢,本來只需要全表掃瞄或者聚集索引掃瞄的,用了索引,而這個索引又沒有查詢需要的其他字段或者建立索引時欄位順序不對,那麼可能對這個索引進行跳躍式掃瞄、還會繼續進行聚集索引掃瞄,這樣效率更低,還不如來個全掃瞄呢。再加上如果統計資訊不是很新,導致查詢優化器判斷有誤,那麼可能會更慢。關鍵還是看這個索引和查詢是否合適。

2、系統在使用一段時間後變的更慢,如果平時有一些基本的效能監控的話,那麼首先應該看一下大概是什麼原因導致的,是cpu使用率很高,還是io等待佇列很長,還是記憶體的問題。

如果是cpu,那麼cpu的使用率主要和3個方面有關:乙個是sql語句的解析,如果改不了**,那麼可通過設定系統強制引數化來減少硬解析次數,如果能改**,那麼盡量使用引數化的查詢;乙個是sql語句寫的有問題導致邏輯讀次數太多,當然也是隨著資料量越來越大,索引存在碎片需要重新組織、重建,或者是索引建立的不合適,或者是統計資訊不是最新的導致產生了不好的查詢計畫;乙個是並行執行計畫導致cpu使用率同時上公升,雖然使用並行執行計畫往往能是查詢的執行時間更短,但是總的開銷更大。

如果是磁碟,那麼要監控這些磁碟的等待佇列,當然等待佇列太長,不僅說明磁碟很忙,也可能說明應該優化儲存,比如建立分割槽表、分割槽索引,這有什麼好處呢?比如原來的表有1億條記錄,現在分割槽後每個分割槽1000萬條,如果我們建了索引,那麼單個分割槽的索引中頁級別有1000萬條索引記錄,相對於原來的索引的1億條索引記錄來說整個規模縮小了10倍,效率肯定是大大提公升的,同時可以把這些分割槽物理的放到不同的磁碟上,這樣如果要查1億條記錄,那麼可以同時啟動多個硬碟來並行的讀取資料。

如果是記憶體使用量很大,甚至導致系統宕機,那麼就得考慮是sql server中那些元件使用了那麼多的記憶體,是過程快取使用的,還是buffer cache使用的,還是sql server有bug,及時打最新的補丁。

當然除了上面cpu、磁碟、記憶體外,也有可能是鎖的問題,由於sql語句之間相互阻塞,還有死鎖,會導致很多語句在等待獲取資源,也有可能是儲存過程編寫的問題,導致事務沒有提交。

3、語句怎麼寫,那就怎麼建索引。比如where子句中的字段,排在前面,而用於關聯的字段放後面,select子句中的字段,可以放到include中,建立覆蓋索引。一般表中索引不可以太多,太多的話會對dml操作產生太多的開銷,導致效能問題。另外,可以通過動態效能檢視檢視,已經建立的索引的使用情況,包括seek次數、scan次數、lookup次數,如果發現這些次數為0的,那麼說明這些索引沒有被用到,可以刪除,這樣也能減小dml操作的壓力。 另外還可以檢視索引的碎片,考慮是否重建或重新組織索引,提高查詢效率。

後面針對dba的3個問題中:

1、如果建表時沒有指定主鍵,那麼這個表就是堆表,就是當有新的記錄要新增時,往上堆就行,沒有什麼順序。

如果在建立表時,指定了主鍵,那麼會自動建立乙個聚集索引,當然不指定主鍵,在建表之後,也可以建議聚集索引。聚集索引會把資料按照索引指定的字段排序存放在硬碟上,構成乙個b樹,葉子頁上存放資料記錄,葉子節點之間通過指標串聯起來,資料中間層都是存放的索引記錄,上層通過指標指向下層節點。

非聚集索引其實和集聚索引很相似,只是葉子頁上儲存的是索引欄位值和行記錄的標識,如果這個表有1000條記錄,那麼葉子節點上也會1000條索引記錄,記錄條數是一樣的。

2、這個上面已經提到了基本的思路,但是還須多實踐。

3、最大的業務表資料接近1億條,共有3到4個索引,1個聚集索引,其他為非聚集索引,其中建立乙個欄位最多的非聚集索引大概20多分鐘,建立索引時這個表中一直有資料在插入,而且cpu使用率維持在高位,磁碟的等待佇列非常高,建立索引需要的時間也和系統繁忙程度有關。

資料庫 資料庫索引

索引是儲存引擎用於快速找到記錄的一種資料結構。索引以檔案的形式儲存在磁碟中。索引可以包含乙個或多個列的值。儲存引擎查詢資料的時候,先在索引中找對應值,然後根據匹配的索引記錄找到對應的資料行。1.b tree索引 2.雜湊索引 myisam和innodb儲存引擎 只支援btree索引,也就是說預設使用...

資料庫mysql索引 資料庫 mysql索引

mysql 索引 mysql索引的建立對於mysql的高效執行是很重要的,索引可以大大提高mysql的檢索速度。打個比方,如果合理的設計且使用索引的mysql是一輛蘭博基尼的話,那麼沒有設計和使用索引的mysql就是乙個人力三輪車。索引分單列索引和組合索引。單列索引,即乙個索引只包含單個列,乙個表可...

資料庫索引

索引 索引列唯一索引 主鍵索引 聚簇索引和非聚簇索引 如何建立索引 如何刪除索引 使用索引可快速訪問資料庫表中的特定資訊。索引是對資料庫表中一列或多列的值進行排序的一種結構,例如 employee 表的姓 lname 列。如果要按姓查詢特定職員,與必須搜尋表中的所有行相比,索引會幫助您更快地獲得該資...