說起mysql查詢效率問題,就無法繞開索引問題,而innodb索引是mysql儲存引擎中的重中之重,innodb索引包括「主鍵索引(聚集索引)」也就是實際資料和主鍵資料儲存在一起的索引。innodb除了主鍵索引以外就是二級索引,二級索引葉子結點的資料區儲存的是主鍵,mysql每個資料頁面有16k大小,innodb在執行插入資料後就已經根據唯一鍵將資料頁排好順序,索引結構暫時不做過多解釋。
例如,想要建立兩個欄位的聯合索引,而第二個欄位你可以選擇使用字首的建立方式,也就是第二個欄位只使用部分資料。
比如查詢優化中我們要遵循最佳做字首原則,這個時候我們很可能想根據字尾去查詢,我們可以將資料倒置後,儲存冗餘一列在按照左匹配模糊查詢。
按照建立索引涉及的列去重後的總數和資料總數做對比,結果越趨近於1,則索引查詢效果越好。因為越趨近於0說明資料差距不大,所掃瞄的資料代價越高。
*****====join*****====
先說下join吧,兩個表的join操作,實質是將一張表的記錄放入另一張表進行匹配過濾,mysql有join_buffer_size設定,這個設定會決定每次從驅動表中拿出多少條資料去另一張表做過濾,如果記憶體允許的話,盡量將其調大(預設256kb)這樣會減少io開銷,每次拿驅動表中多的資料去和另一張表的資料作匹配,sql優化器會試圖將兩個表的操作先優化為內連線也就是inner join,這樣做可以使用驅動表優化策略,會將小表設定為驅動表。
*****===子查詢*****===
子查詢的效能也是關鍵,子查詢可以分為相關子查詢和獨立子查詢;每種查詢方式又分為標量子查詢(返回單條記錄)和結果集子查詢。
(1)如:select * from td1 where name=(select a from td2 where td2.b=td1.c limit 1) 相關子查詢中的標量子查詢;
其實相關標量子查詢,如果子查詢內能夠使用索引速度也是基本沒什麼問題的,因為它會在外層查詢中先取出一條資料,然後去子查詢中做唯一匹配,雖然稍複雜些,但是效能損耗可以接受
(2)如:select * from td1 where name in (select a from td2)獨立子查詢;
ps:如果是上面這種則相對複雜了很多,如果子查詢的返回結果數量沒有超過mysql服務的預設值(tmp_table_size),則會以memory引擎建立乙個td2 臨時表並建立hash索引,因為td1中是以等值方式去td2中匹配的;超過了就會建立磁碟物理表並建立b+tree索引。
《2.1》針對於in子查詢,查詢優化器會將in優化為join,那麼轉換為join的情況則不同,獨立子查詢如果子查詢返回資料庫唯一鍵,則直接可轉成join。
《2.2》如果子查詢返回非唯一鍵,則會使用物化表(按照ps的規則),將結果集先去重,然後在進行join。
(3)如:select * from td1 where name in (select a from td2 where td1.a=td2.b)相關子查詢中使用了主鍵;
semijoin=materialization=
loosescan=
subquery_materialization_cost_based=
4種情況:
《3.1》如果子查詢中select返回是資料庫唯一鍵 ,情況也是直接轉換為semi join。
《3.2》mysql會建立乙個臨時表,每次將主表資料取出後在子查詢表中查詢資料,查詢到以後插入臨時表,該臨時表中不會有重複的資料,當資料插入完畢以後,在與臨時表做semi join。
《3.3》使用firstmatch方法在子查詢表中返回一條語句後,即返回,不在向後繼續尋找。
《3.4》使用loosescan,依賴本身的索引,進行group by進行去重後,在semi join
***************===
mysql查詢部分包括,(1)sql執行器,(2)sql優化器。
sql優化的執行過程可以先開啟sql優化日誌後(set optimizer_trace='enabled=on';),到information_schema.optimizer_trace這個表中進行優化過程的查詢,結合查詢計畫就能夠看到mysql究竟是怎樣執行最終的sql的。
查詢優化日誌中,我們可以主要觀察where條件優化,join優化,和analyzing_range_alternatives查詢成本優化。
這裡我們可以拿analysisi_query_cost查詢成本優化為例,row查詢預設開銷因子為0.2,主鍵索引資料頁查詢因子為1,按照公式=主鍵索引資料頁*1+行數*0.2,最終獲得查詢成本cost的值,優化器會根據cost值,取最小的執行查詢。
]}},,,]
}},]},
,,]},
,"potential_range_indices": [,,
,],
"setup_range_conditions": [
],"group_index_range": ,
"analyzing_range_alternatives": ,,,
],"analyzing_roworder_intersect":
},"chosen_range_access_summary": ,
"rows_for_plan": 3,
"cost_for_plan": 4.61,
"chosen": true
} }}]
},,,,
]},
"cost_for_plan": 5.21,
"rows_for_plan": 3,
"chosen": true
} ]},]
}},]}
]}},}
]}
高效率秘籍
高效率秘籍1 能量管理 假如今天透支身體數小時,下週你可能要為此償還更多的時間。良好的能量管理有兩步 1 增加你的能量儲備。2 將你的日程表由線性的改為迴圈式的。能量儲備 1 每週有3 5次運動嗎?如果你的回答為否,你正在削弱你的潛在能量水平,除非你的醫生不讓你參加運動,否則最少每天要抽出40分鐘來...
高效率生活
如何高效率生活 我們經常會想,為什麼我天天很努力的工作可是工作還是幹不完,如何才能高效率的工作和學習呢?我想這裡有過一些想法和經驗 經驗2 完成乙個事情再休息。因為人腦和電腦很像,乙個東西只有有了結果之後,再次回想時候才能有用,每個東西都要歸根到乙個節點上,乙個完結的點之後才能由這個點拓展開來,就和...
高效率java程式設計
1 考慮使用靜態工廠方法代替構構方法來例項化類。2 使用私用構構函式,使類具有不可例項化的能力。3 避免建立重複的物件 4 消除過期的物件的使用 5 避免使用終結函式 6 使類和成員的可訪問性最小 7 介面優先於抽象 8 為所有的引數進行有效性檢查 9 謹慎使用過載 10 使用0長度的陣列,而不是空...