<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          SQL查詢效率優(yōu)化原則

          共 4247字,需瀏覽 9分鐘

           ·

          2020-07-27 18:33

          1、對查詢進(jìn)行優(yōu)化,應(yīng)盡可能避免全表掃描

          首先應(yīng)考慮在 where 及 order by 涉及的列上建立索引。
          下面我們來以一個表中177條數(shù)據(jù)比較一下,全表掃描與建立索引之后性能的一個比較.

          1.1 全表查詢

          1.2 建立索引查詢

          1.3 結(jié)論

          從這兩種方式查詢數(shù)據(jù)庫結(jié)果看,建立索引之后查詢速度提高了些,現(xiàn)在數(shù)據(jù)量還不明顯,如果表中有10萬條速度,差異就會很明顯了.

          2、寫數(shù)據(jù)語句時盡可能減少表的全局掃描

          2.1 減少where 字段值null判斷

             
          1. SELECT * FROM "tb_real_time_car" where pay_status = null

          如何這樣做,就會導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描
          應(yīng)該這樣去設(shè)置(也就是在沒有值時,我們在存數(shù)據(jù)庫時自動默認(rèn)給個o值,而不是什么都不寫):

             
          1. SELECT * FROM "tb_real_time_car" where pay_status = 0

          2.2 應(yīng)盡量避免在 where 子句中使用!=或<>操作符

             
          1. SELECT * FROM "tb_real_time_car" where pay_status != null ;

          2. //或者

          3. SELECT * FROM "tb_real_time_car" where pay_status <> null ;

          這樣寫將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描。

          2.3 應(yīng)盡量避免在 where 子句中使用 or 來連接條件

             
          1. SELECT * FROM "tb_real_time_car" where pay_status != null or enter_time = null;

          這樣將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描

          可以這樣操作:

             
          1. SELECT * FROM "tb_real_time_car" where pay_status != null union all

          2. SELECT * FROM "tb_real_time_car" where enter_time = null;

          2.4 in 和 not in 也要慎用

             
          1. SELECT * FROM "tb_real_time_car" where rowed in [1,2,3,4];

          2. //或者

          3. SELECT * FROM "tb_real_time_car" where rowed not in [1,2,3,4];

          這樣操作,也會導(dǎo)致全表掃描

          可以這樣來寫:

             
          1. SELECT * FROM "tb_real_time_car" where rowed between 1 and 5;

          2.5 少使用模糊匹配 like

             
          1. SELECT * FROM "tb_real_time_car" where enter_time like '%2016-09-01%'

          2.6 應(yīng)盡量避免在 where 子句中對字段進(jìn)行表達(dá)式操作

             
          1. SELECT * FROM "tb_real_time_car" where rowid/4 =100;

          這樣寫,將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描

          應(yīng)該寫成:

             
          1. SELECT * FROM "tb_real_time_car" where rowid =4*100;

          2.7 任何地方都不要使用*通配符去查詢所有

             
          1. SELECT * FROM "tb_real_time_car" where rowid/4 =100;

          以通配符*去查詢所有數(shù)據(jù),這樣做也是非常耗時的,我們應(yīng)該需要什么字段就查詢什么字段.

          應(yīng)該這樣做:

             
          1. SELECT leave_time FROM "tb_real_time_car" where rowid/4 =100;

          3、不要在條件判斷時進(jìn)行 算數(shù)運(yùn)算

             
          1. SELECT * FROM "tb_real_time_car" where rowid/4 =100;

          所以不要在 where 子句中的“=”左邊進(jìn)行函數(shù)、算術(shù)運(yùn)算或其他表達(dá)式運(yùn)算,這樣系統(tǒng)將可能無法正確使用索引

          應(yīng)該這樣做:

             
          1. SELECT * FROM "tb_real_time_car" where rowed =400;

          4、很多時候用 exists 代替 in 是一個好的選擇

             
          1. SELECT * FROM "tb_real_time_car" where rowed (select rowed from "tb_real");

          應(yīng)該這樣來寫:

             
          1. SELECT * FROM "tb_real_time_car" where exists (select rowed from "tb_real" where rowed = tb_real.rowid);

          5 論索引技巧

          5.1 并不是所有索引對查詢都有效
          SQL是根據(jù)表中數(shù)據(jù)來進(jìn)行查詢優(yōu)化的,當(dāng)索引列有大量數(shù)據(jù)重復(fù)時,SQL查詢可能不會去利用索引,如一表中有字段sex,male、female幾乎各一半,那么即使在sex上建了索引也對查詢效率起不了作用

          5.2 索引并不是越多越好
          索引固然可以提高相應(yīng)的 select 的效率,但同時也降低了 insert 及 update 的效率,因?yàn)?insert 或 update 時有可能會重建索引,所以怎樣建索引需要慎重考慮,視具體情況而定。一個表的索引數(shù)最好不要超過6個,若太多則應(yīng)考慮一些不常使用到的列上建的索引是否有必要。

          5.3 應(yīng)盡可能的避免更新 clustered 索引數(shù)據(jù)列
          因?yàn)?clustered 索引數(shù)據(jù)列的順序就是表記錄的物理存儲順序,一旦該列值改變將導(dǎo)致整個表記錄的順序的調(diào)整,會耗費(fèi)相當(dāng)大的資源。若應(yīng)用系統(tǒng)需要頻繁更新 clustered 索引數(shù)據(jù)列,那么需要考慮是否應(yīng)將該索引建為 clustered 索引。

          5.4 盡量使用數(shù)字型字段

          若只含數(shù)值信息的字段盡量不要設(shè)計為字符型,這會降低查詢和連接的性能,并會增加存儲開銷。這是因?yàn)橐嬖谔幚聿樵兒瓦B接時會逐個比較字符串中每一個字符,而對于數(shù)字型而言只需要比較一次就夠了。

          5 創(chuàng)建數(shù)據(jù)庫時應(yīng)該注意地方
          5.1. 盡可能的使用 varchar/nvarchar 代替 char/nchar
          因?yàn)槭紫茸冮L字段存儲空間小,可以節(jié)省存儲空間,其次對于查詢來說,在一個相對較小的字段內(nèi)搜索效率顯然要高些。

          5.2 用表變量來代替臨時表。

          1. 如果表變量包含大量數(shù)據(jù),請注意索引非常有限(只有主鍵索引)。

          2. 在新建臨時表時,如果一次性插入數(shù)據(jù)量很大,那么可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果數(shù)據(jù)量不大,為了緩和系統(tǒng)表的資源,應(yīng)先create table,然后insert。

          3. 如果使用到了臨時表,在存儲過程的最后務(wù)必將所有的臨時表顯式刪除,先 truncate table ,然后 drop table ,這樣可以避免系統(tǒng)表的較長時間鎖定。

          3 避免頻繁創(chuàng)建和刪除臨時表,以減少系統(tǒng)表資源的消耗。
          4 盡量避免使用游標(biāo)

          1. 因?yàn)橛螛?biāo)的效率較差,如果游標(biāo)操作的數(shù)據(jù)超過1萬行,那么就應(yīng)該考慮改寫。

          2. 使用基于游標(biāo)的方法或臨時表方法之前,應(yīng)先尋找基于集的解決方案來解決問題,基于集的方法通常更有效。

          3. 與臨時表一樣,游標(biāo)并不是不可使用。對小型數(shù)據(jù)集使用 FAST_FORWARD 游標(biāo)通常要優(yōu)于其他逐行處理方法,尤其是在必須引用幾個表才能獲得所需的數(shù)據(jù)時。在結(jié)果集中包括“合計”的例程通常要比使用游標(biāo)執(zhí)行的速度快。如果開發(fā)時間允許,基于游標(biāo)的方法和基于集的方法都可以嘗試一下,看哪一種方法的效果更好。

          6 數(shù)據(jù)放回時注意什么

          6.1 盡量避免大事務(wù)操作,提高系統(tǒng)并發(fā)能力。

          這樣可以有效提高系統(tǒng)的并發(fā)能力

          6.2 盡量避免向客戶端返回大數(shù)據(jù)量

          若數(shù)據(jù)量過大,應(yīng)該考慮相應(yīng)需求是否合理。

          7.總結(jié)

          1.盡量避免where中包含子查詢;
          2.where條件中,過濾量最大的條件放在where子句最后;
          3.采用綁定變量有助于提高效率;
          4.在索引列上使用計算、改變索引列的類型、在索引列上使用!=將放棄索引;
          5.運(yùn)算符效率:exists高于in高于or,(not exists高于not in);
          (這里指出:in和or都是效率較低的運(yùn)算,但是in的效率:O(logn)仍然比or的效率:O(n)高的多,尤其當(dāng)運(yùn)算列不是索引的時候尤為明顯)
          6.避免在索引列上使用is
          null和is not null;
          7.使用索引的第一個列;
          8.用union-all替代union;
          9.like ‘text%’使用索引,但like ‘%text’不使用索引;


          最后免費(fèi)給大家分享50個Java項(xiàng)目實(shí)戰(zhàn)資料,涵蓋入門、進(jìn)階各個階段學(xué)習(xí)內(nèi)容,可以說非常全面了。大部分視頻還附帶源碼,學(xué)起來還不費(fèi)勁!


          附上截圖。(下面有下載方式)。


          項(xiàng)目領(lǐng)取方式:

          掃描下方公眾號回復(fù):50

          可獲取下載鏈接

          ???

             
          ?長按上方二維碼 2 秒
          回復(fù)「50」即可獲取資料


          點(diǎn)贊是最大的支持 

          瀏覽 34
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  青娱乐在线无码 | 香蕉社区在线观看 | 亚洲AV无码成人精品区欧洲 | 一区在线观看免费 | 操妣视频|