mysql是乙個很流行的資料庫,大中小公司都有使用,本人也使用了兩年mysql,對效能優化這塊很有興趣,尤其是索引,一直是一種模稜兩可的感覺,主要是總結的太少,學的很瑣碎,故寫此文來對自己做個總結。
大多數索引(不包括hash)說白了就是顆樹,設定好索引等於建立了一顆包含索引列的樹,隨後可以根據樹的性質來快速找到指定的資料,這樣就避免了去一行行找資料,大大節約了查詢時間。但索引也不全是好的,結合剛才說的索引會生成帶有資料的樹,那麼在更新資料庫的時候就會要去更新索引樹,那也就多了一部分操作,也就會多消耗時間,多消耗儲存空間。這是索引的利弊。 接下來說下我所認識的一些索引類別,這裡只涉及innodb的索引。
hash索引,hash索引是根據索引列計算出乙個hash值,這個值對應乙個或幾個值,根據hash值可以快速找出資料,但是有乙個致命的缺點,因為key的值互相之間可以說是無關聯的,也就說明只能用來找特定的值,如果我們要找個區間範圍的值,比如說時間範圍,hash索引就無能為力了。同樣的,hash索引也不能用於排序,這也就說明不能避免表掃瞄,其次,如果是做多列hash索引,則查詢時必須使用所有的索引列查詢,否則無法使用hash索引。所以hash索引看似效率很高,但是限制太多,很少有使用到。
btree樹,可以說是使用最多的索引。先說說聚族索引和非聚族索引。聚族索引一般來說就是我們的primary key,但是這也不是絕對的,在沒有主鍵的時候,會使用乙個唯一的非空索引列,不管選哪個都只能乙個聚族索引。 下面展示了聚族索引中的記錄是如何存放的。注意到,葉子頁包含了行的全部資料,但是節點頁只包含了索引列。
剩下的就是非聚族索引,也是btree的一種,其中有一種叫做唯一索引,其實唯一索引和普通索引基本一樣,唯一的區別是,設定了唯一索引,某列或某幾列的資料不能重複,否則會報錯duplicatekey。
普通索引的建立主要注意要選選擇性高的列,盡量建立聯合索引,最好是覆蓋索引,覆蓋索引其實就是說索引列覆蓋了所有的查詢列。
建立索引主要關注3個地方,按照sql的執行順序來說就是
1.聯表查詢時的關聯列需要建索引,假設是左聯,那右邊表的關聯列就需要使用索引,這樣能加快on語句的速度。
2.where語句也是建立索引的關鍵位置,建立的原則過會再說。
3.最後就是排序時候的索引 所有的索引需要滿足幾個原則,最基本的就是最左匹配原則。舉個栗子:idx_key(col1,col2)。這個聯合索引可以應用到兩種情況,用where語句舉例,col1=1 and col=2或者col1=1,但是不能用col2=n這樣,不能跨過第一列。
還有乙個很重要的就是不要建很多索引企圖利用多個索引提高速度,因為不管如何每一次只能用到乙個索引,這也就牽涉到乙個問題,如果你在前三個地方中的任何地方使用了不同的索引,那mysql只能使用乙個,試想一下,我們通過索引很快的從where語句中過濾出一批資料,速度很快,但如果排序的時候沒有使用之前的那個索引,那排序的時候就不能使用索引,用explain看到的是filesort方式而不是index,結果排序使用了很長時間而拖慢了查詢速度,所以前後索引盡量保持一致最完美,但是有時候也不能做的那麼周全,這時候mysql優化器會根據預估的計算時間替我們選擇合適的索引。還有幾個會影響索引正常使用的情況,比如說在列上做了轉換或者計算,例如a+1=n,或者是使用了null型別等等,這些都會影響索引。
最後要說明乙個很重要點,不要以為你掌握了索引的建立法則就一定能建立好索引,因為在不同的資料量的情況下,原本優秀的索引會變差,或者說在資料量上公升後,資料分布在資料列上的比例開始變化了,可能需要調整索引順序,還有很多時候,需要依靠經驗來做出索引(傳說中的dba!)。所以dba是很重要的,要那麼容易建那還要dba做什麼呢對吧 個人總結,望大神指教!
漢諾塔問題個人小總結
關於遞迴,必須了解其關鍵的思想,重複相同的動作,但處理的卻是不同的資料,在幾乎所有我所見過的遞迴函式中,都是這樣.幾乎都是讓資料之間進行交換,然後以相同的 機器 去加工.故此引入著名的tower of hanoi include void hanoi int n,char a,char b,char...
錯排問題(個人總結 複習用)
錯排問題是組合數學發展史上的乙個重要問題,錯排數也是一項重要的數。令 的乙個錯排,如果每個元素都不在其對應下標的位置上,即 那麼這種排列稱為錯位排列,或錯排 重排 derangement 我們從分析1 2 3 4的錯排開始 1 2 3 4的錯排有 4 3 2 1,4 1 2 3,4 3 1 2,3 ...
面試題(個人總結)
執行緒啟動方式 r語言1.start 開啟執行緒,start是通過執行緒來呼叫run方法 2.run 此run非彼run 不是在run方法實現執行緒的邏輯,而是thread.run 這個run方法是直接呼叫了執行緒中的run 3.yield 暫停當前執行緒,並執行其他執行緒 4.sleep 使當前執...