1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        SQL優(yōu)化最干貨總結(jié)-MySQL(2020最新版)

        共 649字,需瀏覽 2分鐘

         ·

        2020-12-08 00:33

        擊上方Java專欄”,選擇“置頂或者星標(biāo)”


        第一時間閱讀精彩文章!


        點擊這段文字獲?。?/strong>5個可以寫到簡歷的項目實戰(zhàn)視頻教程(含源碼)

        作者:陳哈哈

        chensj.blog.csdn.net/article/details/107020686

        前言

        BATJTMD等大廠的面試難度越來越高,但無論從大廠還是到小公司,一直未變的一個重點就是對SQL優(yōu)化經(jīng)驗的考察。一提到數(shù)據(jù)庫,先“說一說你對SQL優(yōu)化的見解吧?”。

        SQL優(yōu)化已經(jīng)成為衡量程序猿優(yōu)秀與否的硬性指標(biāo),甚至在各大廠招聘崗位職能上都有明碼標(biāo)注,如果是你,在這個問題上能吊打面試官還是會被吊打呢?

        注:如果看著模糊,可能是你擼多了

        目錄

        前言

        SELECT語句 - 語法順序:

        SELECT語句 - 執(zhí)行順序:

        SQL優(yōu)化策略

        一、避免不走索引的場景

        二、SELECT語句其他優(yōu)化

        三、增刪改 DML 語句優(yōu)化

        四、查詢條件優(yōu)化

        五、建表優(yōu)化


        有朋友疑問到,SQL優(yōu)化真的有這么重要么?如下圖所示,SQL優(yōu)化在提升系統(tǒng)性能中是:(成本最低 && 優(yōu)化效果最明顯) 的途徑。如果你的團(tuán)隊在SQL優(yōu)化這方面搞得很優(yōu)秀,對你們整個大型系統(tǒng)可用性方面無疑是一個質(zhì)的跨越,真的能讓你們老板省下不止幾沓子錢。

        • 優(yōu)化成本:硬件>系統(tǒng)配置>數(shù)據(jù)庫表結(jié)構(gòu)>SQL及索引。

        • 優(yōu)化效果:硬件<系統(tǒng)配置<數(shù)據(jù)庫表結(jié)構(gòu)

        String?result?=?"嗯,不錯,";
        ?
        if?("SQL優(yōu)化經(jīng)驗足")?{
        ????if?("熟悉事務(wù)鎖")?{
        ????????if?("并發(fā)場景處理666")?{
        ????????????if?("會打王者榮耀")?{
        ????????????????result?+=?"明天入職"?
        ????????????}
        ????????}
        ????}
        }?else?{
        ????result?+=?"先回去等消息吧";
        }?
        ?
        Logger.info("面試官:"?+?result?);

        別看了,上面這是一道送命題。

        好了我們言歸正傳,首先,對于MySQL層優(yōu)化我一般遵從五個原則:

        1. 減少數(shù)據(jù)訪問:設(shè)置合理的字段類型,啟用壓縮,通過索引訪問等減少磁盤IO

        2. 返回更少的數(shù)據(jù):只返回需要的字段和數(shù)據(jù)分頁處理 減少磁盤io及網(wǎng)絡(luò)io

        3. 減少交互次數(shù):批量DML操作,函數(shù)存儲等減少數(shù)據(jù)連接次數(shù)

        4. 減少服務(wù)器CPU開銷:盡量減少數(shù)據(jù)庫排序操作以及全表查詢,減少cpu 內(nèi)存占用

        5. 利用更多資源:使用表分區(qū),可以增加并行操作,更大限度利用cpu資源

        總結(jié)到SQL優(yōu)化中,就三點:

        • 最大化利用索引;

        • 盡可能避免全表掃描;

        • 減少無效數(shù)據(jù)的查詢;

        理解SQL優(yōu)化原理 ,首先要搞清楚SQL執(zhí)行順序:

        SELECT語句 - 語法順序:

        1.?SELECT?
        2.?DISTINCT?
        3.?FROM?
        4.??JOIN?
        5.?ON?
        6.?WHERE?
        7.?GROUP?BY?
        8.?HAVING?
        9.?ORDER?BY?
        10.LIMIT?

        SELECT語句 - 執(zhí)行順序:

        FROM
        <表名> # 選取表,將多個表數(shù)據(jù)通過笛卡爾積變成一個表。
        ON
        <篩選條件> # 對笛卡爾積的虛表進(jìn)行篩選
        JOIN??
        # 指定join,用于添加數(shù)據(jù)到on之后的虛表中,例如left join會將左表的剩余數(shù)據(jù)添加到虛表中
        WHERE
        # 對上述虛表進(jìn)行篩選
        GROUP BY
        <分組條件> # 分組
        # 用于having子句進(jìn)行判斷,在書寫上這類聚合函數(shù)是寫在having判斷里面的
        HAVING
        <分組篩選> # 對分組后的結(jié)果進(jìn)行聚合篩選
        SELECT
        <返回數(shù)據(jù)列表> # 返回的單列必須在group by子句中,聚合函數(shù)除外
        DISTINCT
        # 數(shù)據(jù)除重
        ORDER BY
        <排序條件> # 排序
        LIMIT
        <行數(shù)限制>

        SQL優(yōu)化策略

        聲明:以下SQL優(yōu)化策略適用于數(shù)據(jù)量較大的場景下,如果數(shù)據(jù)量較小,沒必要以此為準(zhǔn),以免畫蛇添足。

        一、避免不走索引的場景

        1. 盡量避免在字段開頭模糊查詢,會導(dǎo)致數(shù)據(jù)庫引擎放棄索引進(jìn)行全表掃描。如下:

        SELECT?*?FROM?t?WHERE?username?LIKE?'%陳%'

        優(yōu)化方式:盡量在字段后面使用模糊查詢。如下:

        SELECT?*?FROM?t?WHERE?username?LIKE?'陳%'

        如果需求是要在前面使用模糊查詢,

        • 使用MySQL內(nèi)置函數(shù)INSTR(str,substr) 來匹配,作用類似于java中的indexOf(),查詢字符串出現(xiàn)的角標(biāo)位置

        • 使用FullText全文索引,用match against 檢索

        • 數(shù)據(jù)量較大的情況,建議引用ElasticSearch、solr,億級數(shù)據(jù)量檢索速度秒級

        • 當(dāng)表數(shù)據(jù)量較少(幾千條兒那種),別整花里胡哨的,直接用like '%xx%'。

        2. 盡量避免使用in 和not in,會導(dǎo)致引擎走全表掃描。如下:

        SELECT?*?FROM?t?WHERE?id?IN?(2,3)

        優(yōu)化方式:如果是連續(xù)數(shù)值,可以用between代替。如下:

        SELECT?*?FROM?t?WHERE?id?BETWEEN?2?AND?3

        如果是子查詢,可以用exists代替。如下:

        --?不走索引
        select?*?from?A?where?A.id?in?(select?id?from?B);
        --?走索引
        select?*?from?A?where?exists?(select?*?from?B?where?B.id?=?A.id);

        3. 盡量避免使用 or,會導(dǎo)致數(shù)據(jù)庫引擎放棄索引進(jìn)行全表掃描。如下:

        SELECT?*?FROM?t?WHERE?id?=?1?OR?id?=?3

        優(yōu)化方式:可以用union代替or。如下:

        SELECT?*?FROM?t?WHERE?id?=?1
        ???UNION
        SELECT?*?FROM?t?WHERE?id?=?3

        4. 盡量避免進(jìn)行null值的判斷,會導(dǎo)致數(shù)據(jù)庫引擎放棄索引進(jìn)行全表掃描。如下:

        SELECT?*?FROM?t?WHERE?score?IS?NULL

        優(yōu)化方式:可以給字段添加默認(rèn)值0,對0值進(jìn)行判斷。如下:

        SELECT?*?FROM?t?WHERE?score?=?0

        5.盡量避免在where條件中等號的左側(cè)進(jìn)行表達(dá)式、函數(shù)操作,會導(dǎo)致數(shù)據(jù)庫引擎放棄索引進(jìn)行全表掃描。

        可以將表達(dá)式、函數(shù)操作移動到等號右側(cè)。如下:

        --?全表掃描
        SELECT?*?FROM?T?WHERE?score/10?=?9
        --?走索引
        SELECT?*?FROM?T?WHERE?score?=?10*9

        6. 當(dāng)數(shù)據(jù)量大時,避免使用where 1=1的條件。通常為了方便拼裝查詢條件,我們會默認(rèn)使用該條件,數(shù)據(jù)庫引擎會放棄索引進(jìn)行全表掃描。如下:

        SELECT?username,?age,?sex?FROM?T?WHERE?1=1

        優(yōu)化方式:用代碼拼裝sql時進(jìn)行判斷,沒 where 條件就去掉 where,有where條件就加 and。

        搜索Java知音公眾號,回復(fù)“后端面試”,送你一份Java面試題寶典.pdf

        7. 查詢條件不能用 <> 或者 !=

        使用索引列作為條件進(jìn)行查詢時,需要避免使用<>或者!=等判斷條件。如確實業(yè)務(wù)需要,使用到不等于符號,需要在重新評估索引建立,避免在此字段上建立索引,改由查詢條件中其他索引字段代替。

        8. where條件僅包含復(fù)合索引非前置列

        如下:復(fù)合(聯(lián)合)索引包含key_part1,key_part2,key_part3三列,但SQL語句沒有包含索引前置列"key_part1",按照MySQL聯(lián)合索引的最左匹配原則,不會走聯(lián)合索引。

        select?col1?from?table?where?key_part2=1?and?key_part3=2

        9. 隱式類型轉(zhuǎn)換造成不使用索引

        如下SQL語句由于索引對列類型為varchar,但給定的值為數(shù)值,涉及隱式類型轉(zhuǎn)換,造成不能正確走索引。

        select?col1?from?table?where?col_varchar=123;

        10. order by 條件要與where中條件一致,否則order by不會利用索引進(jìn)行排序

        --?不走age索引
        SELECT?*?FROM?t?order?by?age;
        ?
        --?走age索引
        SELECT?*?FROM?t?where?age?>?0?order?by?age;

        對于上面的語句,數(shù)據(jù)庫的處理順序是:

        • 第一步:根據(jù)where條件和統(tǒng)計信息生成執(zhí)行計劃,得到數(shù)據(jù)。

        • 第二步:將得到的數(shù)據(jù)排序。當(dāng)執(zhí)行處理數(shù)據(jù)(order by)時,數(shù)據(jù)庫會先查看第一步的執(zhí)行計劃,看order by 的字段是否在執(zhí)行計劃中利用了索引。如果是,則可以利用索引順序而直接取得已經(jīng)排好序的數(shù)據(jù)。如果不是,則重新進(jìn)行排序操作。

        • 第三步:返回排序后的數(shù)據(jù)。

        當(dāng)order by 中的字段出現(xiàn)在where條件中時,才會利用索引而不再二次排序,更準(zhǔn)確的說,order by 中的字段在執(zhí)行計劃中利用了索引時,不用排序操作。

        這個結(jié)論不僅對order by有效,對其他需要排序的操作也有效。比如group by 、union 、distinct等。

        11. 正確使用hint優(yōu)化語句

        MySQL中可以使用hint指定優(yōu)化器在執(zhí)行時選擇或忽略特定的索引。一般而言,處于版本變更帶來的表結(jié)構(gòu)索引變化,更建議避免使用hint,而是通過Analyze table多收集統(tǒng)計信息。但在特定場合下,指定hint可以排除其他索引干擾而指定更優(yōu)的執(zhí)行計劃。

        1. USE INDEX 在你查詢語句中表名的后面,添加 USE INDEX 來提供希望 MySQL 去參考的索引列表,就可以讓 MySQL 不再考慮其他可用的索引。例子: SELECT col1 FROM table USE INDEX (mod_time, name)...

        2. IGNORE INDEX 如果只是單純的想讓 MySQL 忽略一個或者多個索引,可以使用 IGNORE INDEX 作為 Hint。例子: SELECT col1 FROM table IGNORE INDEX (priority) ...

        3. FORCE INDEX 為強(qiáng)制 MySQL 使用一個特定的索引,可在查詢中使用FORCE INDEX 作為Hint。例子: SELECT col1 FROM table FORCE INDEX (mod_time) ...

        在查詢的時候,數(shù)據(jù)庫系統(tǒng)會自動分析查詢語句,并選擇一個最合適的索引。但是很多時候,數(shù)據(jù)庫系統(tǒng)的查詢優(yōu)化器并不一定總是能使用最優(yōu)索引。如果我們知道如何選擇索引,可以使用FORCE INDEX強(qiáng)制查詢使用指定的索引。

        例如:

        SELECT?*?FROM?students?FORCE?INDEX?(idx_class_id)?WHERE?class_id?=?1?ORDER?BY?id?DESC;

        二、SELECT語句其他優(yōu)化

        1. 避免出現(xiàn)select *

        首先,select * 操作在任何類型數(shù)據(jù)庫中都不是一個好的SQL編寫習(xí)慣。

        使用select * 取出全部列,會讓優(yōu)化器無法完成索引覆蓋掃描這類優(yōu)化,會影響優(yōu)化器對執(zhí)行計劃的選擇,也會增加網(wǎng)絡(luò)帶寬消耗,更會帶來額外的I/O,內(nèi)存和CPU消耗。

        建議提出業(yè)務(wù)實際需要的列數(shù),將指定列名以取代select *。

        2. 避免出現(xiàn)不確定結(jié)果的函數(shù)

        特定針對主從復(fù)制這類業(yè)務(wù)場景。由于原理上從庫復(fù)制的是主庫執(zhí)行的語句,使用如now()、rand()、sysdate()、current_user()等不確定結(jié)果的函數(shù)很容易導(dǎo)致主庫與從庫相應(yīng)的數(shù)據(jù)不一致。另外不確定值的函數(shù),產(chǎn)生的SQL語句無法利用query cache。

        3.多表關(guān)聯(lián)查詢時,小表在前,大表在后。

        在MySQL中,執(zhí)行 from 后的表關(guān)聯(lián)查詢是從左往右執(zhí)行的(Oracle相反),第一張表會涉及到全表掃描,所以將小表放在前面,先掃小表,掃描快效率較高,在掃描后面的大表,或許只掃描大表的前100行就符合返回條件并return了。

        例如:表1有50條數(shù)據(jù),表2有30億條數(shù)據(jù);如果全表掃描表2,你品,那就先去吃個飯再說吧是吧。

        4. 使用表的別名

        當(dāng)在SQL語句中連接多個表時,請使用表的別名并把別名前綴于每個列名上。這樣就可以減少解析的時間并減少哪些友列名歧義引起的語法錯誤。

        5. 用where字句替換HAVING字句

        避免使用HAVING字句,因為HAVING只會在檢索出所有記錄之后才對結(jié)果集進(jìn)行過濾,而where則是在聚合前刷選記錄,如果能通過where字句限制記錄的數(shù)目,那就能減少這方面的開銷。HAVING中的條件一般用于聚合函數(shù)的過濾,除此之外,應(yīng)該將條件寫在where字句中。

        where和having的區(qū)別:where后面不能使用組函數(shù)

        6.調(diào)整Where字句中的連接順序

        MySQL采用從左往右,自上而下的順序解析where子句。根據(jù)這個原理,應(yīng)將過濾數(shù)據(jù)多的條件往前放,最快速度縮小結(jié)果集。

        三、增刪改 DML 語句優(yōu)化

        1. 大批量插入數(shù)據(jù)

        如果同時執(zhí)行大量的插入,建議使用多個值的INSERT語句(方法二)。這比使用分開INSERT語句快(方法一),一般情況下批量插入效率有幾倍的差別。

        方法一:

        insert?into?T?values(1,2);?
        ?
        insert?into?T?values(1,3);?
        ?
        insert?into?T?values(1,4);

        方法二:

        Insert?into?T?values(1,2),(1,3),(1,4);

        選擇后一種方法的原因有三。

        • 減少SQL語句解析的操作,MySQL沒有類似Oracle的share pool,采用方法二,只需要解析一次就能進(jìn)行數(shù)據(jù)的插入操作;

        • 在特定場景可以減少對DB連接次數(shù)

        • SQL語句較短,可以減少網(wǎng)絡(luò)傳輸?shù)腎O。

        2. 適當(dāng)使用commit

        適當(dāng)使用commit可以釋放事務(wù)占用的資源而減少消耗,commit后能釋放的資源如下:

        • 事務(wù)占用的undo數(shù)據(jù)塊;

        • 事務(wù)在redo log中記錄的數(shù)據(jù)塊;

        • 釋放事務(wù)施加的,減少鎖爭用影響性能。特別是在需要使用delete刪除大量數(shù)據(jù)的時候,必須分解刪除量并定期commit。

        3. 避免重復(fù)查詢更新的數(shù)據(jù)

        針對業(yè)務(wù)中經(jīng)常出現(xiàn)的更新行同時又希望獲得改行信息的需求,MySQL并不支持PostgreSQL那樣的UPDATE RETURNING語法,在MySQL中可以通過變量實現(xiàn)。

        例如,更新一行記錄的時間戳,同時希望查詢當(dāng)前記錄中存放的時間戳是什么,簡單方法實現(xiàn):

        Update?t1?set?time=now()?where?col1=1;?
        ?
        Select?time?from?t1?where?id?=1;?

        使用變量,可以重寫為以下方式:

        Update?t1?set?time=now?()?where?col1=1?and?@now:?=?now?();?
        ?
        Select?@now;?

        前后二者都需要兩次網(wǎng)絡(luò)來回,但使用變量避免了再次訪問數(shù)據(jù)表,特別是當(dāng)t1表數(shù)據(jù)量較大時,后者比前者快很多。

        4.查詢優(yōu)先還是更新(insert、update、delete)優(yōu)先

        MySQL 還允許改變語句調(diào)度的優(yōu)先級,它可以使來自多個客戶端的查詢更好地協(xié)作,這樣單個客戶端就不會由于鎖定而等待很長時間。改變優(yōu)先級還可以確保特定類型的查詢被處理得更快。我們首先應(yīng)該確定應(yīng)用的類型,判斷應(yīng)用是以查詢?yōu)橹鬟€是以更新為主的,是確保查詢效率還是確保更新的效率,決定是查詢優(yōu)先還是更新優(yōu)先。

        下面我們提到的改變調(diào)度策略的方法主要是針對只存在表鎖的存儲引擎,比如 MyISAM 、MEMROY、MERGE,對于Innodb 存儲引擎,語句的執(zhí)行是由獲得行鎖的順序決定的。MySQL 的默認(rèn)的調(diào)度策略可用總結(jié)如下:

        1)寫入操作優(yōu)先于讀取操作。

        2)對某張數(shù)據(jù)表的寫入操作某一時刻只能發(fā)生一次,寫入請求按照它們到達(dá)的次序來處理。

        3)對某張數(shù)據(jù)表的多個讀取操作可以同時地進(jìn)行。MySQL 提供了幾個語句調(diào)節(jié)符,允許你修改它的調(diào)度策略:

        • LOW_PRIORITY關(guān)鍵字應(yīng)用于DELETE、INSERT、LOAD DATA、REPLACE和UPDATE;

        • HIGH_PRIORITY關(guān)鍵字應(yīng)用于SELECT和INSERT語句;

        • DELAYED關(guān)鍵字應(yīng)用于INSERT和REPLACE語句。

        如果寫入操作是一個 LOW_PRIORITY(低優(yōu)先級)請求,那么系統(tǒng)就不會認(rèn)為它的優(yōu)先級高于讀取操作。在這種情況下,如果寫入者在等待的時候,第二個讀取者到達(dá)了,那么就允許第二個讀取者插到寫入者之前。只有在沒有其它的讀取者的時候,才允許寫入者開始操作。這種調(diào)度修改可能存在 LOW_PRIORITY寫入操作永遠(yuǎn)被阻塞的情況。

        SELECT 查詢的HIGH_PRIORITY(高優(yōu)先級)關(guān)鍵字也類似。它允許SELECT 插入正在等待的寫入操作之前,即使在正常情況下寫入操作的優(yōu)先級更高。另外一種影響是,高優(yōu)先級的 SELECT 在正常的 SELECT 語句之前執(zhí)行,因為這些語句會被寫入操作阻塞。如果希望所有支持LOW_PRIORITY 選項的語句都默認(rèn)地按照低優(yōu)先級來處理,那么 請使用--low-priority-updates 選項來啟動服務(wù)器。通過使用 INSERTHIGH_PRIORITY 來把 INSERT 語句提高到正常的寫入優(yōu)先級,可以消除該選項對單個INSERT語句的影響。

        四、查詢條件優(yōu)化

        1. 對于復(fù)雜的查詢,可以使用中間臨時表 暫存數(shù)據(jù)

        2. 優(yōu)化group by語句

        默認(rèn)情況下,MySQL 會對GROUP BY分組的所有值進(jìn)行排序,如 “GROUP BY col1,col2,....;” 查詢的方法如同在查詢中指定 “ORDER BY col1,col2,...;” 如果顯式包括一個包含相同的列的 ORDER BY子句,MySQL 可以毫不減速地對它進(jìn)行優(yōu)化,盡管仍然進(jìn)行排序。

        因此,如果查詢包括 GROUP BY 但你并不想對分組的值進(jìn)行排序,你可以指定 ORDER BY NULL禁止排序。例如:

        SELECT?col1,?col2,?COUNT(*)?FROM?table?GROUP?BY?col1,?col2?ORDER?BY?NULL?;

        3. 優(yōu)化join語句

        MySQL中可以通過子查詢來使用 SELECT 語句來創(chuàng)建一個單列的查詢結(jié)果,然后把這個結(jié)果作為過濾條件用在另一個查詢中。使用子查詢可以一次性的完成很多邏輯上需要多個步驟才能完成的 SQL 操作,同時也可以避免事務(wù)或者表鎖死,并且寫起來也很容易。但是,有些情況下,子查詢可以被更有效率的連接(JOIN)..替代。

        例子:假設(shè)要將所有沒有訂單記錄的用戶取出來,可以用下面這個查詢完成:

        SELECT?col1?FROM?customerinfo?WHERE?CustomerID?NOT?in?(SELECT?CustomerID?FROM?salesinfo?)

        如果使用連接(JOIN).. 來完成這個查詢工作,速度將會有所提升。尤其是當(dāng) salesinfo表中對 CustomerID 建有索引的話,性能將會更好,查詢?nèi)缦拢?/p>

        SELECT?col1?FROM?customerinfo?
        ???LEFT?JOIN?salesinfoON?customerinfo.CustomerID=salesinfo.CustomerID?
        ??????WHERE?salesinfo.CustomerID?IS?NULL?

        連接(JOIN).. 之所以更有效率一些,是因為 MySQL 不需要在內(nèi)存中創(chuàng)建臨時表來完成這個邏輯上的需要兩個步驟的查詢工作。

        4. 優(yōu)化union查詢

        MySQL通過創(chuàng)建并填充臨時表的方式來執(zhí)行union查詢。除非確實要消除重復(fù)的行,否則建議使用union all。原因在于如果沒有all這個關(guān)鍵詞,MySQL會給臨時表加上distinct選項,這會導(dǎo)致對整個臨時表的數(shù)據(jù)做唯一性校驗,這樣做的消耗相當(dāng)高。

        高效:

        SELECT?COL1,?COL2,?COL3?FROM?TABLE?WHERE?COL1?=?10?
        ?
        UNION?ALL?
        ?
        SELECT?COL1,?COL2,?COL3?FROM?TABLE?WHERE?COL3=?'TEST';?

        低效:

        SELECT?COL1,?COL2,?COL3?FROM?TABLE?WHERE?COL1?=?10?
        ?
        UNION?
        ?
        SELECT?COL1,?COL2,?COL3?FROM?TABLE?WHERE?COL3=?'TEST';

        5.拆分復(fù)雜SQL為多個小SQL,避免大事務(wù)

        • 簡單的SQL容易使用到MySQL的QUERY CACHE;

        • 減少鎖表時間特別是使用MyISAM存儲引擎的表;

        • 可以使用多核CPU。

        6. 使用truncate代替delete

        當(dāng)刪除全表中記錄時,使用delete語句的操作會被記錄到undo塊中,刪除記錄也記錄binlog,當(dāng)確認(rèn)需要刪除全表時,會產(chǎn)生很大量的binlog并占用大量的undo數(shù)據(jù)塊,此時既沒有很好的效率也占用了大量的資源。

        使用truncate替代,不會記錄可恢復(fù)的信息,數(shù)據(jù)不能被恢復(fù)。也因此使用truncate操作有其極少的資源占用與極快的時間。另外,使用truncate可以回收表的水位,使自增字段值歸零。

        7. 使用合理的分頁方式以提高分頁效率

        使用合理的分頁方式以提高分頁效率 針對展現(xiàn)等分頁需求,合適的分頁方式能夠提高分頁的效率。

        案例1:

        select?*?from?t?where?thread_id?=?10000?and?deleted?=?0?
        ???order?by?gmt_create?asc?limit?0,?15;

        上述例子通過一次性根據(jù)過濾條件取出所有字段進(jìn)行排序返回。數(shù)據(jù)訪問開銷=索引IO+索引全部記錄結(jié)果對應(yīng)的表數(shù)據(jù)IO。因此,該種寫法越翻到后面執(zhí)行效率越差,時間越長,尤其表數(shù)據(jù)量很大的時候。

        適用場景:當(dāng)中間結(jié)果集很?。?0000行以下)或者查詢條件復(fù)雜(指涉及多個不同查詢字段或者多表連接)時適用。

        案例2:

        select?t.*?from?(select?id?from?t?where?thread_id?=?10000?and?deleted?=?0
        ???order?by?gmt_create?asc?limit?0,?15)?a,?t?
        ??????where?a.id?=?t.id;?

        上述例子必須滿足t表主鍵是id列,且有覆蓋索引secondary key:(thread_id, deleted, gmt_create)。通過先根據(jù)過濾條件利用覆蓋索引取出主鍵id進(jìn)行排序,再進(jìn)行join操作取出其他字段。數(shù)據(jù)訪問開銷=索引IO+索引分頁后結(jié)果(例子中是15行)對應(yīng)的表數(shù)據(jù)IO。因此,該寫法每次翻頁消耗的資源和時間都基本相同,就像翻第一頁一樣。

        適用場景:當(dāng)查詢和排序字段(即where子句和order by子句涉及的字段)有對應(yīng)覆蓋索引時,且中間結(jié)果集很大的情況時適用。

        五、建表優(yōu)化

        1. 在表中建立索引,優(yōu)先考慮where、order by使用到的字段。

        2. 盡量使用數(shù)字型字段(如性別,男:1 女:2),若只含數(shù)值信息的字段盡量不要設(shè)計為字符型,這會降低查詢和連接的性能,并會增加存儲開銷。

        這是因為引擎在處理查詢和連接時會 逐個比較字符串中每一個字符,而對于數(shù)字型而言只需要比較一次就夠了。

        3. 查詢數(shù)據(jù)量大的表 會造成查詢緩慢。主要的原因是掃描行數(shù)過多。這個時候可以通過程序,分段分頁進(jìn)行查詢,循環(huán)遍歷,將結(jié)果合并處理進(jìn)行展示。要查詢100000到100050的數(shù)據(jù),如下:

        SELECT?*?FROM?(SELECT?ROW_NUMBER()?OVER(ORDER?BY?ID?ASC)?AS?rowid,*?
        ???FROM?infoTab)t?WHERE?t.rowid?>?100000?AND?t.rowid?<=?100050

        4. 用varchar/nvarchar 代替 char/nchar

        盡可能的使用 varchar/nvarchar 代替 char/nchar ,因為首先變長字段存儲空間小,可以節(jié)省存儲空間,其次對于查詢來說,在一個相對較小的字段內(nèi)搜索效率顯然要高些。

        不要以為 NULL 不需要空間,比如:char(100) 型,在字段建立時,空間就固定了, 不管是否插入值(NULL也包含在內(nèi)),都是占用 100個字符的空間的,如果是varchar這樣的變長字段, null 不占用空間。

        ---END---
        文末福利



        瀏覽 39
        點贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

          <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            欧美黄片在线免费看| 蜜桃视频一区二区三区四区使用方法| 三个黑人猛躁我一晚上| 在线精品福利| 成人激情五月天| 亚洲综合日韩在线| 久久久久久久久毛片| 久久久3| 一区二区三区在线看| 成人A片一级| 大香焦久久| 久久aa| 京东一热本色道久久爱| 欧美在线无码| 高清中文字幕在线A片| 波多野结衣无码一区| 女人BBBB| 天天夜夜狠狠| 欧美熟女一区二区| 国产激情免费视频| 杨晨晨不雅视频| 精品视频一区二区| 激情视频网址| 99久久精品国产一区色| 成人爽a毛片一区二区免费| 婷婷丁香五月综合| 亚洲成人AⅤ| 韩国三级HD久久精品HD| 超碰人人操人人摸| 色婷婷久久综合| 啊啊啊啊啊在线观看| 黄色一级小说| 日韩AA片| 亚洲国产成人精品女人久久| 99久久精彩视频| 日区无码| 日本三级久久| 国产美女一级特黄大片| 成人电影aaa| 亚洲无码在线播放| 无码天堂| 天天精品| 一级无码毛片| 蜜桃一区二区三区| www.av在线| 人人艹人人摸| 免费无码高清视频| 人妻视频网站| 亚洲精品福利视频| 国产精品99久久久久的广告情况 | 成人免费激情视频| 欧美人妻中文字幕| 亚洲天堂视频网| 五月欧美激情| 天天爽天天| 国产综合色婷婷精品久久| 91在线无码精品秘网站| 少妇性视频| 九九热播精品| 成人网站视频在线免费观看| 91丨牛牛丨国产人妻| 成人午夜A片| 日韩黄色免费视频| 成人免费毛片果冻日本| 日韩色导航| 久久久久久亚洲精品| 亚洲天堂av在线免费观看| 俺来俺去www色婷婷| 国产精品女人精品久久久天天| 松岛枫在线视频| 吴梦梦| 99AV| 日日騒av无码| 加勒比综合无码| 亚洲精品无码中文| 国产精品人人人人| 欧美大鸡巴在线观看| 一区黄片| 国产三级无码视频| 国产无遮挡又黄又爽又色视频| 日韩十八禁网站| 97精品欧美91久久久久久久| 国产成人大香蕉| 日韩成人无码免费视频| 国产黄网站| 成年人在线观看视频网站| 久久精品99久久久久久| 伊人狠狠蜜桃亚洲综合| 欧美黄色免费观看| 婷婷久久久久| 久久午夜视频| 国产熟妇码视频| 久久久999| www.黄片| 麻豆免费福利视频| 精品中文字幕在线播放| 91福利视频网| 91国产精品在线视频| 北条麻妃免费视频| 懂色av懂色av粉嫩av| 韩国成人精品三级| AV免费网址| 精品乱伦视频| 国产凹凸视频| 狠狠操狠狠撸| 国产性爱在线观看| 日韩高清无码一区| 人人摸人人搞| 女人特级毛片18| 五月激情黄色| 天天日日天天| 精品一区二区久久久久久久网站 | 婷婷五月激情小说| 在线视频播放| 国产三级一区二区| 在线观看视频无码| 狠狠插视频| 国产娇小13videos糟蹋 | 国产精品93333333| 亚洲三级片视频| 免费无码视频在线观看| 欧美日韩一区二区三区| 中文字幕免费在线看一区七区| 夜夜爽日日爽| 波多野结衣视频在线观看| 欧美二区视频| 91麻豆精品在线观看| 不卡无线在一区| 国产视频一区二区三区四区五区| 亚洲无码99| 日韩美女视频19| 豆花视频在线| 永久免费看A人片无码精| 在线看黄网| 黄色大片视频| 国产九九九九九九| 污片网站| 国产精品无码成人AV在线播放| 重庆美女揉BBBB搡BBBB| 在线黄网| 美女视频一区二区三区| 国产黄色一区| 亚洲一区2区| 国产黄色视频免费看| 三个黑人猛躁我一晚上| 日本韩国无码| 玉米地一级婬片A片| 视频一区乳奴| 免费无码婬片A片AA片| 天堂AV无码AV| 成人午夜| 成人精品一区二区三区中文字幕| 国产黄色免费乱伦片| 久久亚洲成人| 中文无码在线| 久久人妻视频| 人妻一区二区在线| aaa成人| 99精品在线观看视频| 波多野结衣亚洲无码| 亚洲在线免费| 色色com| 免费无码国产在线怀| 日逼网站视频| 婷婷精品国产一区二区三区日韩| 蜜桃91精品秘成人取精库| 黄色www| 国内成人精品网站| 久久国产一级片| 国产成人无码精品一区秘二区 | 91三级视频| 欧美激情一区二区| 人妻无码一区二区三区免费| 国产91嫩草乱婬A片2蜜臀| AAA日韩| 一级内射视频| 午夜成人毛片| 黄色视频在线免费看| 激情无码av| 国产高清第一页| 国产色情视频在线观看| 女生自慰网站在线观看| 九九九九精品| 日韩毛片在线视频x| 黄色A片免费| 国产a片免费看| 一级特黄大片录像i| 蜜桃传媒一区二区| 久久久一级| 日韩在线网址| 波多野结衣无码一区二区| 华女与黑人91A∨| 一欧美日韩免费/看| 成人久久大香蕉| 婷婷伊人中文字幕| 北条麻妃精品| 韩日在线| 一级艹逼| 波多野吉衣av| 日韩高清无码片| 国产A视频| 亚洲天堂无码a| 欧美性爱第四页| 人妻av无码| 男女啪啪动态图| 欧美操| 大香蕉精品一区| 国产ts在线观看| 亚洲黄色小视频| 一区二区高清| 天天综合字幕一区二区| 欧美aaa在线| 免费黄色三级片| 欧美成人无码片免费看A片秀色 | 网络自拍亚洲激情| 69AV电影| 99精品全国免费观看| 亚州精品人妻一二三区| 一线天嫩穴少妇| 日韩无码2024| 日韩av中文| 欧美黑吊大战白妞| 成人免费Av| 免费观看黄色AV| 美女大香蕉| 久久99深爱久久99精品| 亚洲天堂2014| 2018中文字幕第一页| 日逼中文字幕| 51成人网站| 超碰毛片| 激情久久AV一区AV二区AV三区 | 免费A片国产毛无码A片| 玖玖99视频| 久久怡春院| 中文字幕日本精品5| 亚洲视频免费播放| 男人午夜AV| 韩国gogogo高清在线完整版| 美女免费网站| 精品偷拍| 亚洲三级片免费观看| 69成人天堂无码免费| 免费一级做a爱片毛片A片小说 | 亚洲黄色视频在线免费观看 | 东京热久久综合| 777Av| 国产在线不卡年轻点的| 人人射人人干| 国产91网| 一级久久| 制服.丝袜.亚洲.中文.豆花| 日韩AV无码专区亚洲AV| 黄色午夜福利| 能看的黄色视频| 亚洲插菊花综合网| 日日夜夜天天| 囯产精品久久久久久久久久久久久久 | 欧美日韩在线视频播放| 日韩A片一级无码免费蜜桃| 无码在线视频播放| 黄色99| 午夜天堂精品久久久久| 日韩在线小电影| 欧美人妻日韩精品| 人妻无码免费视频| 亚洲欧美日韩不卡| 三级片视频网址| 插菊花综合网2| 久久综合站| 777超碰| 青青草无码视频| 欧美干综合| 蜜桃91精品入口| 无码午夜| 中文在线不卡| 最近中文字幕在线| 中文有码| 操鸡视频在线观看| 欧美中文日韩| 狠狠爱一区| AV五月| 五月天狠狠操| 成人女人18女人毛片| 激情久久AV一区AV二区AV三区 | 91九色91蝌蚪91窝成人| 国产婷婷久久Av免费高清| 国产亚洲99久久精品熟女| 西西人体大胆ww4444多少集| 久久1234| 9l视频自拍九色9l视频成人 | 韩国午夜电影| 久热国产在线| 欧美熟妇精品一级A片视色| 91麻豆国产福利精品| AV天天干| 51成人网站| 在线乱视频| 强伦轩一区二区三区四区| 天天操天天干欧美精品|