當前位置:偏方大全网 - 藥品查詢 - SQL優化(二)

SQL優化(二)

SQL優化壹: sql優化(壹)

上片文章已經詳細介紹了explain各個字段的含義,以及什麽情況應該建立索引,什麽情況不需要建立索引以及sql語句性能的判斷依據,接下來我介紹下如何合理的建立索引。

sql語句:select id,author_id from article where category_id = 1 and comments>1 order by views desc limit 1;

分析:首先我們根據where後面的條件建立符合索引,然後根據order by後面的字段建立索引,因此建立索引idx_article_ccv,即以(category_id,comments,views)數據列建立復合索引,但由於comments是壹個範圍,按照BTree索引的原理,先排序category_id,如果遇到相同的category_id則再排序comments,如果遇到相同的comments則再排序views,又因為comments字段在復合索引裏處於中間位置,而comments>1是壹個條件(是壹個範圍值),在復合索引的壹個範圍值的數據列後面的索引全部失效,mysql無法利用索引再對後面的views部分進行檢索,也就是說views無法按照索引排序,所以explain下此sql語句,type為range,extra使用的是Using filesort,這是比較糟糕的。所以我們放棄comments這個範圍字段,建立索引idx_article_cv,即以(category_id,views)數據列建立復合索引,explain 此sql,type變成了ref,extra的using?filesort也變成了using index,這就變得好多了。

索引:idx_article_cv,即以(category_id,views)數據列建立復合索引

前段時間做了壹個銷售精細化項目,是公司crm項目的壹個大模塊,大致就是為銷售人員制定指標,實現銷售目標從區域到團到業務員到客戶,實時跟蹤業務員所負責客戶的下單量的情況。這就存在許多關聯關系,區域-團,團-業務員,業務員-客戶,這使得sql常常需要關聯多張表。

sql語句:SELECT

tu.fuserid,

tu.faccount,

tu.fphone,

tu.fcertificationtype,

tu.fcertificatename,

tu.fkeyarea,

tu.fkeyareatext,

DATE_FORMAT(tcr.fupdatetime,'%Y-%m-%d %H:%i:%s') as fupdatetime,

tag.forggroupid,

tag.forggroupname,

tug.forguserid,

tug.fusername,

tug.fuserphone,

tag.fcitycode

FROM t_finedt_user AS tu

LEFT JOIN t_finedt_customer_relation AS tcr

ON tu.fuserid = tcr.fuserid

LEFT JOIN t_finedt_usergroup AS tug

ON tcr.forguserid = tug.forguserid

and tcr.forggroupid = tug.forggroupid

LEFT JOIN t_finedt_areagroup AS tag

ON tug.forggroupid = tag.forggroupid

where tu.fkeyarea=? and?tu.fuserid=? and tug.forggroupid = ?

分析:上面的sql是左連接,左邊的表壹定是全表查詢,所以要建立右邊表對應關聯字段的索引,在表t_finedt_user上建立tu_fuserid_fkeyarea索引,即以(fuserid,fkeyarea)字段建立索引,在表t_finedt_customer_relation 上建立tcr_forguserid_forggroupid索引,即以(forguserid,forggroupid)字段建立索引,在表t_finedt_usergroup 上建立tug_forguserid_forggroupid索引,即以(forguserid,forggroupid)字段建立索引,在表t_finedt_areagroup上建立tag_forggroupid索引,即以(forggroupid)字段建立索引。建立索引後,sql查詢速度明顯快了很多

索引:tcr_forguserid_forggroupid,tu_fuserid_fkeyarea,tug_forguserid_forggroupid,tag_forggroupid

1、盡可能減少join語句中的NestedLoop的循環次數,永遠用小結果集驅動大結果集

2、優先優化NestedLoop的內層循環

3、保證join語句總被驅動表上的join字段已經被索引

4、當無法保證被驅動表join條件字段被索引,且內存資源充足的前提下,不要太吝嗇joinBuffer的設置

1、全值匹配我最愛

2、最佳左前綴原則——如果索引了多列,要遵守最左前綴原則,指的是查詢從索引的最左前列開始並且不跳過索引中的列

3、並在索引列上做任何操作(計算、函數、自動or手動類型轉換),這些會導致索引失效而轉向全表掃描

4、存儲引擎不能使用索引中範圍條件右邊的列,範圍之後的索引全失效

5、盡量使用覆蓋索引(之訪問索引的查詢(索引列和查詢的列壹致)),減少select *

6、mysql在使用不等於(!=、>、<)的時候無法使用索引會導致全表掃描。

7、is null、is not null也無法使用索引。

8、like以通配符開頭("%abc.."),mysql索引失效也會變成全表掃描的操作。

9、字符串不加單引號也會引起索引失效

10、少用or,用它來連接時會索引失效。

1、對於單值索引,盡量選擇針對當前query過濾性更好的索引

2、在選擇組合索引的時候,當前query中過濾性最好的字段在索引字段順序中,位置越靠前越好

3、在選擇組合索引的時候,盡量選擇盡可能包含當前query中的where字句中更多字段的索引

4、盡可能通過分析統計信息和調整query的寫法來達到選擇合適索引的目的。

全值匹配我最愛,最左前綴要遵守

帶頭大哥不能死,中間兄弟不能斷

索引列上少計算,範圍之後全失效

like百分寫最右,覆蓋索引不寫裏

不等空值還有or,索引失效要少用

var引號不可丟,sql高級也不難

  • 上一篇:2021茂名執業藥師資格考試條件變化
  • 下一篇:2022年湖北省人口與計劃生育條例
  • copyright 2024偏方大全网