索引若是沒有特指,通常是指B+TREE,一般意味着全部值都是順序存放,所以對於範圍查詢會很是快。InnoDB按照原數據格式進行存儲。InnoDB存儲引擎表是索引組織表,表中數據按照主鍵存放(InnoDB會隱式定義一個主鍵做爲彙集索引,切記不能重複定義)。索引的葉節點中存放表的行記錄,使葉節點成爲數據頁。而普通索引僅僅存放鍵值以及偏移量而已。(ps:MYISAM使用前綴壓縮使索引更小,表中數據是經過索引所記錄的數據物理的位置,直接引用的。)
Tips1:
範圍查詢很是快
eg:limit 優化mysql
select * from yanxue8_visit limit 10,10
屢次運行,時間保持在0.0004-0.0005之間sql
Select * From yanxue8_visit Where vid >=( Select vid From yanxue8_visit Order By vid limit 10,1 ) limit 10
Tips2:
在使用索引時須要獨立的列
eg:服務器
select * from tablename where id +1 = 5
這樣的寫法是不能用索引的,這也是爲何不少mysql優化語句中常提到的一點。
Tip3:
可使用前綴索引
eg:mysql優化
alter table tablename add key(a(7))
這樣可使索引變小並變快,節約空間,提升索引效率。但會減少索引的選擇性。
前綴索引,一種優化索引大小的解決方案
事實上,彙集索引頁有些缺點,提升了使用磁盤I/O的次數。而且要嚴格按照插入順序插入,不然可能面臨數據頁分裂,耗用更多空間並下降性能。所以咱們都須要一個自增加鍵做爲主鍵,保證數據順序寫入。若使用UUID狀況會變糟糕,因此如今分佈式系統基本放棄了原生的UUID尋找替代品。分佈式
輔助索引只是存取了彙集索引的書籤。若想查詢須要對輔助索引遍歷一遍再在彙集索引遍歷一遍,遍歷深度由索引樹高度決定。工具
聯合索引顧名思義是多索引組成的聯合索引.
如一張t表中有兩列,a與b,其中a爲主鍵,b爲普通列
建立:alter table t add key idx_a_b(a,b)
如上圖,數據先根據a排放,a值相同則根據b排放。既該索引包括了a與b的笛卡爾積。若where a = xxx and b = xxx 以及 where a = xxx則能夠利用該索引,但where b = xxx 就不能利用該索引。(最左前綴)
好處:
能夠聯合讀取多個列
能夠作聯合排序
Tip1:
利用多列條件作分頁操做
建立:alter table tablename add key idx_a_b(a,b)性能
select * from tablename t1 left join( select id from tablename where a = 1 oder by b limit 1000,10) t2 on t1.id = t2.id
但事實上,也不能一棒子拍死。查詢結果會很是依賴於選定的具體指,會對其餘查詢不公平,會使服務器運行不如預期。其順序必須以選擇性高低進行排序。事實上實際開發中,本人是由於某個查詢量大的業務才創建聯合索引,基本業務也是單個索引(但要注意重複索引,如我建立了(a,b)就得把(a)索引刪除)。優化
InnoDB中只用哈希對字典進行查找,事實上,哈希表只需理解有這麼個東西就行。InnoDB會自動建立哈希表並維護,並只是對字典查詢會變快(where a = 'xxx'),不對範圍查詢起做用。spa
innodb_adaptive_hash_index 啓用/禁用特性 innodb_buffer_pool_size/256=哈希的槽數
explain
很是強大的工具,分析sql語句的性能以及所運用的索引。能夠解決絕大多數sql性能問題。
慢查詢日誌
超過閾值的SQL語句記錄的日誌。
show index from tablename
能夠分析表中索引,有些字段對於分析該表索引很是有用,如Cardinality。
analyze table
能優化索引存儲,使索引更好工做.可每週或天天凌晨運行一次。
值得注意的地方
mysql在查詢時,若數據大於整張表的20%,則會放棄索引
參考書籍
高性能MySQL
MySQL技術內幕日誌