mysql between 查询不出来_mysql的语句优化
生活随笔
收集整理的這篇文章主要介紹了
mysql between 查询不出来_mysql的语句优化
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
(1)mysql避免全表掃描
1、應(yīng)盡量避免在 where 子句中對字段進行 null 值判斷,否則將導(dǎo)致引擎放棄使用索引而進行全表掃描,如: select id from t where num is null,不能用null作索引,任何包含null值的列都將不會被包含在索引中。即使索引有多列這樣的情況下,只要這些列中有一列含有null,該列就會從索引中排除。也就是說如果某列存在空值,即使對該列建索引也不會提高性能。任何在where子句中使用is null或is not null的語句優(yōu)化器是不允許使用索引的。 2、應(yīng)盡量避免在 where 子句中使用!=或<>操作符,否則將引擎放棄使用索引而進行全表掃描。 MySQL只有對以下操作符才使用索引:,>=,BETWEEN,IN,以及某些時候的LIKE??梢栽贚IKE操作中使用索引的情形是指另一個操作數(shù)不是以通配符(%或者_)開頭的情形。 例如,“SELECT id FROM t WHERE col LIKE 'Mich%';”這個查詢將使用索引,但“SELECT id FROM t WHERE col LIKE '%ike';”這個查詢不會使用索引。 ?3、應(yīng)盡量避免在 where 子句中使用!=或<>操作符,否則將引擎放棄使用索引而進行全表掃描。 MySQL只有對以下操作符才使用索引:,>=,BETWEEN,IN,以及某些時候的LIKE。可以在LIKE操作中使用索引的情形是指另一個操作數(shù)不是以通配符(%或者_)開頭的情形。例如,“SELECT id FROM t WHERE col LIKE 'Mich%';”這個查詢將使用索引,但“SELECT id FROM t WHERE col LIKE '%ike';”這個查詢不會使用索引。 ?4、 應(yīng)盡量避免在 where 子句中使用 or 來連接條件,否則將導(dǎo)致引擎放棄使用索引而進行全表掃描,如:select id from t where num=10 or num=20 可以這樣查詢:select id from t where num=10 union all select id from t where num=20 5、不要在 where 子句中的“=”左邊進行函數(shù)、算術(shù)運算或其他表達式運算,否則系統(tǒng)將可能無法正確使用索引。錯誤:select id from t where substring(name,1,3)='abc'--name正確:select id from t where name like 'abc%' 錯誤:select id from t where datediff(day,createdate,'2005-11-30')=0--‘2005-11-30’生成的id 正確:select id from t where createdate>='2005-11-30' and createdate錯誤:select id from t where num/2=100 正確:select id from t where num=100*2 6、在使用索引字段作為條件時,如果該索引是復(fù)合索引,那么必須使用到該索引中的第一個字段作為條件時才能保證系統(tǒng)使用該索引,否則該索引將不會被使用,并且應(yīng)盡可能的讓字段順序與索引順序相一致。復(fù)合索引的最左優(yōu)化原則。(2)mysql聯(lián)合索引的使用
索引的最左原則(左前綴原則),如(c1,c2,c3,c4....cN)的聯(lián)合索引,where 條件按照索引建立的字段順序來使用(不代表and條件必須按照順序來寫),如果中間某列沒有條件,或使用like會導(dǎo)致后面的列不能使用索引。索引也能用于分組和排序,分組要先排序,在計算平均值等等。所以在分組和排序中,如果字段順序可以按照索引的字段順序,即可利用索引的有序特性(3)mysql索引失效
1、like 以%開頭,索引無效;當like前綴沒有%,后綴有%時,索引有效。2、or語句前后沒有同時使用索引。當or左右查詢字段只有一個是索引,該索引失效,只有當or左右查詢字段均為索引時,才會生效3、組合索引,不是使用第一列索引,索引失效。(最左原則)4、數(shù)據(jù)類型出現(xiàn)隱式轉(zhuǎn)化。如varchar不加單引號的話可能會自動轉(zhuǎn)換為int型,使索引無效,產(chǎn)生全表掃描。5、在索引字段上使用not,<>,!=。不等于操作符是永遠不會用到索引的,因此對它的處理只會產(chǎn)生全表掃描。優(yōu)化方法:key<>0 改為 key>0 or key<0。6、對索引字段進行計算操作、字段上使用函數(shù),會失效。(4)mysql執(zhí)行計劃的解讀
執(zhí)行計劃各字段含義1、idselect查詢的序列號,包含一組數(shù)字,表示查詢中執(zhí)行select子句或操作表的順序。id不同,如果是子查詢,id的序號會遞增,id值越大優(yōu)先級越高,越先被執(zhí)行。2、select_type分別用來表示查詢的類型,主要是用于區(qū)別普通查詢、聯(lián)合查詢、子查詢等的復(fù)雜查詢。SIMPLE 簡單的select查詢,查詢中不包含子查詢或者UNIONPRIMARY 查詢中若包含任何復(fù)雜的子部分,最外層查詢則被標記為PRIMARYSUBQUERY 在SELECT或WHERE列表中包含了子查詢DERIVED 在FROM列表中包含的子查詢被標記為DERIVED(衍生),MySQL會遞歸執(zhí)行這些子查詢,把結(jié)果放在臨時表中UNION 若第二個SELECT出現(xiàn)在UNION之后,則被標記為UNION:若UNION包含在FROM子句的子查詢中,外層SELECT將被標記為:DERIVEDUNION RESULT 從UNION表獲取結(jié)果的SELECT3、table當前執(zhí)行的表4、type最好到最差的排序:( 在項目使用中 至少type優(yōu)化到range和ref )system > const > eq_ref > ref > range > index > alltype所顯示的是查詢使用了哪種類型,type包含的類型包括如下圖所示的幾種:system 表只有一行記錄(等于系統(tǒng)表),這是const類型的特列,平時不會出現(xiàn),這個也可以忽略不計。const 表示通過索引一次就找到了,const用于比較primary key 或者unique索引。因為只匹配一行數(shù)據(jù),所以很快。如將主鍵置于where列表中,MySQL就能將該查詢轉(zhuǎn)換為一個常量。eq_ref 唯一性索引掃描,對于每個索引鍵,表中只有一條記錄與之匹配。常見于主鍵或唯一索引掃描ref 非唯一性索引掃描,返回匹配某個單獨值的所有行,本質(zhì)上也是一種索引訪問,它返回所有匹配某個單獨值的行,然而,它可能會找到多個符合條件的行,所以他應(yīng)該屬于查找和掃描的混合體。range 只檢索給定范圍的行,使用一個索引來選擇行,key列顯示使用了哪個索引,一般就是在你的where語句中出現(xiàn)between、< 、>、in等的查詢,這種范圍掃描索引比全表掃描要好,因為它只需要開始于索引的某一點,而結(jié)束于另一點,不用掃描全部索引。index Full Index Scan,Index與All區(qū)別為index類型只遍歷索引樹。這通常比ALL快,因為索引文件通常比數(shù)據(jù)文件小。(也就是說雖然all和Index都是讀全表,但index是從索引中讀取的,而all是從硬盤讀取的)5、possible_keys 顯示可能應(yīng)用在這張表中的索引,一個或多個。查詢涉及到的字段上若存在索引,則該索引將被列出,但不一定被查詢實際使用。key實際使用的索引,如果為NULL,則沒有使用索引。(可能原因包括沒有建立索引或索引失效)6、ref:它顯示的是列的名字(或單詞“const”),MySQL將根據(jù)這些列來選擇行。在本例中,MySQL根據(jù)三個常量選擇行。7、rows:MySQL所認為的它在找到正確的結(jié)果之前必須掃描的記錄數(shù)。顯然,這里最理想的數(shù)字就是1。8、包含不適合在其他列中顯式但十分重要的額外信息(5)mysql的exist和in
exists和in的使用方式:
#對B查詢涉及id,使用索引,故B表效率高,可用大表 -->外小內(nèi)大select * from A where exists (select * from B where A.id=B.id);#對A查詢涉及id,使用索引,故A表效率高,可用大表 -->外大內(nèi)小select * from A where A.id in (select id from B); 1、exists是對外表做loop循環(huán),每次loop循環(huán)再對內(nèi)表(子查詢)進行查詢,那么因為對內(nèi)表的查詢使用的索引(內(nèi)表效率高,故可用大表),而外表有多大都需要遍歷,不可避免(盡量用小表),故內(nèi)表大的使用exists,可加快效率; 2、in是把外表和內(nèi)表做hash連接,先查詢內(nèi)表,再把內(nèi)表結(jié)果與外表匹配,對外表使用索引(外表效率高,可用大表),而內(nèi)表多大都需要查詢,不可避免,故外表大的使用in,可加快效率。 3、如果用not in ,則是內(nèi)外表都全表掃描,無索引,效率低,可考慮使用not exists,也可使用A left join B on A.id=B.id where B.id is null 進行優(yōu)化。總結(jié)
以上是生活随笔為你收集整理的mysql between 查询不出来_mysql的语句优化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: idea 线程内存_Java线程池系列之
- 下一篇: idea mysql 创建表_idea