時間過得太快了,春節假期感覺光速般就結束了,轉眼間就要繼續搬磚上班了。緊接著很快就要進入金三銀四的求職面試高峰期,程式猿小楓還沒有找到令自己感到滿意的工作。就算是在過年放假期間也在拼命的準備技術面試,這不他又梳理了下之前面試過程中面試官經常問到的關於資料庫方面的一道面試題,我們來一起幫小楓看看有沒有遺漏的地方吧。
面試官:看你的簡歷中有提到過曾經進行過索引優化的工作,那我就問問你,假設資料庫表中有索引,但是進行sql資料查詢還是很慢,這種情況下應該怎麼分析查詢慢的原因?
在進行資料庫查詢的時候,我們都知道索引可以加快資料查詢的效率。但是在實際的業務場景下,經常會遇到即使在表中增加了索引,但是同樣還是會出現資料查詢慢的問題。這就需oueuhey要具體分析資料查詢慢的具體原因到底是什麼了。
首先需要進行確認的就是sql語句中對應的條件查詢中欄位有沒有建立索引。雖然面試官說了有索引,但是不一定sql語句中的查詢欄位有建立索引,所以第一步應該進行sql中的字段索引www.cppcns.com確認。如果沒有建立對應的索引可以先嘗試下建立索引再進行查詢。如果已經有了索引,查詢的字段也是索引字段,那麼就要考慮下是不是出現了索引失效的情況。下面我們再具體分析下,看看在哪些場景下會出現索引失效的情況。
在分析索引失效場景之前,我們必須要清楚索引結構的特點是什麼。關於mysql的資料庫索引結構在之前的文章中已經進行了詳細的分析,可以參見之前的文章。
mysql資料庫索引面試題(程式設計師基礎技能)
我們來看下mysql資料庫索引的結構特點:
這裡以user_info這張表來作為分析的基礎,在user_info這張表上,我們分別建立了idx_name以及idx_phone二級索引以及idx_age_address聯合索引。
create table if not exists `user_info` (
`id` bigint(20) not null auto_increment,
`name` varchar(20) not null,
`gender` int(2) not null,
`age` int(10) not null,
`phone_number` varchar(20) not null,
`address` varchar(40) not null,
primary key ( `id` ),
key `idx_name`(`name`),
key `idx_phone`(`phone_number`),
key `idx_age_address`(`age`,程式設計客棧`address`)
)engine=innodb default charset=utf8;
進行sql資料查詢的時候,where條件字段型別與實際表中字段型別不匹配的時候,mysql會進行隱式的資料型別轉換,而型別轉換會使用到內建函式,導致在進行資料查詢的時候並沒有使用索引。我們可以使用explain命令檢視sql語句。可以看的出來在key欄中,對應的值為null,說明並沒有使用索引進行查詢。
但是如果在按照phone_number欄位為字串型別進行查詢的時候,mysql沒有進行隱式的型別轉換,所以最終還是走了索引。
在where中條件使用了條件表示式的時候,資料表中的索引就失效了,實際是因為mysql需要將索引字段取出來之後再進行表示式的條件判斷,因而進行了全表掃瞄,導致索引失效。
索引字段實際上是依賴於整個b+索引樹的遍歷,而索引樹的遍歷又依賴於索引樹底層葉子節點的有序性。索引儲存的是索引列的原始值,如果經過函式計算,msql的直譯器無法判斷計算後的索引在原來的索引樹上是否可以被索引到,因此它就直接放棄使用索引查詢了。
使用左模糊匹配以及左右模糊匹配都會導致索引失效,但是使用右模糊匹配,還是可以走索引查詢的。
由於b+樹按照索引值進行排序的,實際是按照最左字首進行比較,而使用了%作為最左字首,mysql無法判斷其有序性,因此只能進行全表掃瞄查詢。
如果資料庫表中有聯合索引的話,我們在sql查詢語句中使用的索引欄位又不是聯合索引的最左欄位,那麼就會導致索引失效。
實際上在mysql中的索引檢索是遵循最左匹配原則的,同時b+索引樹的葉子節點的有序性也是建立都在最左匹配原則之上,而上述的4、5兩種情況實際違反了最左匹配原則,因此mysq執行器則無法使用對應的索引進行檢查查詢。
因為 or 的含義就是兩個只要滿足乙個即可,因此只有乙個條件列進行了索引是沒有意義的,只要有條件列沒有進行索引,就會進行全表掃瞄,因此索引的條件列也會失效。
這裡需要說明的是使用in以及not in走不走索引,實際和mysql的版本以及表中的資料量有關係,在8程式設計客棧.0之後的版本是走索引的。
本文根據面試官的存在索引但是出現資料查詢慢的問題為出發點,總結了幾種索引失效的場景,希望在大家平時專案開發時遇到類似的問題可以有對應的問題排查方向。導致索引失效的場景歸結起來實際就是在索引使用上面存在瑕疵最終導致了索引失效的情況,這就像我們小時候打拳皇97一樣,遙感和按鈕的組合如果姿勢不對,就沒辦法放出我們希望的大招。小楓的求職面試之路還在繼續,我們一起期待下次小楓還會遇到怎樣的面試問題吧。
mysql資料庫索引名 Mysql資料庫索引簡介
1.什麼是索引?資料庫索引是表中的乙個特殊的資料結構,存放的記錄的快速檢索的值,也稱為目錄,被儲存在乙個地方,所以索引是乙個存在的檔案,並不是儲存在記憶體中 索引的存在是為了在查詢時,可以直接通過查詢索引找到那一條記錄所在的位置,而不是逐一的去檢索,大大的提高的查詢的效率 那麼是不是每一列都建立乙個...
為什麼要選擇MySQL資料庫
什麼是mysql?mysql是乙個多使用者 多執行緒的sql資料庫,是乙個客戶機 伺服器結構的應用,它由乙個伺服器守護程式mysqld和很多不同的客戶程式和庫組成。sql structured query language結構化查詢語言 是目前使用最廣的並且是標準的資料庫語言。sql語言使得訪問或更...
資料庫技術 為什麼在MySQL中只使用InnoDB
我們大多數的客戶系統都執行mysql。這樣很好。但是大部分客戶的mysql引擎都是使用myisam。這樣很糟糕。幾乎所有的系統資料都應該只使用innodb 這樣會很簡單,當然下面也會討論一些例外。mysql 有兩種通常的資料儲存引擎 myisam和innodb。直到5.1版本 包括5.1 myisa...