在實際項目中,當MySQL表的數據達到百萬級別時候,普通查詢效率直線下降,而且當使用的where條件較多,其查詢效率是讓人無法容忍的。假如一個taobao訂單查詢詳情要幾十秒,可想而知的用戶體驗是多差。
查詢效率慢的原因:
1:沒有加索引或者索引失效
where條件使用如下語句會索引失效:null、!=、<>、or連接、in(非要使用,可用關鍵字exist替代)和not in、'%abc%';
使用參數:num=@num、表達式操作:where num/2=100、函數操作:where substring(name,1,3)=‘abc’-name;
--exist代替in
select id from table where num exist(1,2,3,4,5,6)
--where字句使用or連接條件的替代方案
select id from table where num=10
union
select id from table where num=20;
--連續的數值,能用between就不要用in
select id from table where num between 1 and 3;
--使用參數的替代方案
--如果在where子句中使用參數(num = @num;),也會導致全表掃描。因為SQL只有在運行時才會解析局部變量,但優化程序不能將訪問計划的選擇到運行時;它必須在編譯時進行選擇。然而,如果在編譯時建立訪問計划,變量的值還是未知的,因而無法作為索引的輸入項。
select id from table where num=@num;
替代為:強制查詢使用索引:
select id from table with(index(索引名)) where num=@num;
--使用表達式的替代方案
select id from table where num/2=100;
替代為
select id from table where num=100*2;
--使用函數操作的替代方案
select id from t where substring(name, 1, 3) = ’abc’–name; //以abc開頭
替代為
select id from t where name like ‘abc%’;//單個百分號
2:查詢的數據量過大,返回不必要的行和列
只查詢有用的字段,不要用*查詢出所有字段。
采用多線程多次查詢。如果查詢條件是某段時間之類的范圍條件,可以把時間條件切分,多次查詢結果合並。
3:鎖或者死鎖
4: I/O吞吐量小,形成瓶頸效應。
5:內存不足。
少造對象,對象只在需要使用時創建,不要在整個上下文傳遞。
及時清理jvm內存。
6:網絡速度慢。
一些SQL優化方法
1:如果索引是復合索引,必須使用該索引的第一個字段作為條件才能保證系統使用該索引,否則索引不會被引用,並且應盡可能的讓字段順序與索引順序一致。
2:索引並不是越多越好,一個表索引最好不要超過6個。索引固然可以提高select效率,但是也降低了insert效率和update效率,因為insert和update會使索引重建,所以怎么建索引需要慎重考慮。
3:建表的一些優化:
盡量使用數字型字段,若數據只含有數值信息盡量不要設計成字符型,這會降低查詢和連接的性能,並會增加存儲開銷。因為引擎在處理查詢和連接時會逐個比較字符串中每個字符,而對於數字型而言只需比較一次就夠了。
盡量使用varchar/nvarchar代替char/nchar,因為首先變長字段存儲空間小,可以節省存儲空間,其次對於查詢來說,在一個相對較小的字段內搜索效率顯然要高一些。
4:任何地方都不要使用select * from table,用具體的字段列表代替*,不要返回用不到的任何字段。
5:盡量避免使用游標,因為游標的效率較差,如果游標操作的數據超過1萬行,那么就應該考慮改寫。
6:並不是所有索引對查詢都有效,SQL是根據表中數據來進行查詢優化的,當索引列有大量數據重復時,SQL查詢可能不會去利用索引,如一表中有字段 sex,male、female幾乎各一半,那么即使在sex上建了索引也對查詢效率起不了作用。
7:盡量避免大事務操作,提高系統並發能力。
---------------------
作者:來去擼兩行
來源:CSDN
原文:https://blog.csdn.net/qq_39416311/article/details/82315090
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!