日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql not in优化_实践中如何优化MySQL(收藏)

發布時間:2024/7/23 数据库 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql not in优化_实践中如何优化MySQL(收藏) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
  • SQL語句的優化:
    • 1、盡量避免使用子查詢
    • 3、用IN來替換OR
    • 4、LIKE前綴%號、雙百分號、_下劃線查詢非索引列或*無法使用到索引,如果查詢的是索引列則可以
    • 5、讀取適當的記錄LIMIT M,N,而不要讀多余的記錄
    • 6、避免數據類型不一致
    • 7、分組統計可以禁止排序sort,總和查詢可以禁止排重用union all
    • 8、避免隨機取記錄
    • 9、禁止不必要的ORDER BY排序
    • 10、批量INSERT插入
    • 11、不要使用NOT等負向查詢條件
    • 12、盡量不用select *
    • 13、**區分in和exists**
  • 索引的優化:
    • 1、Join語句的優化
    • 2、避免索引失效

在開始介紹如何優化sql前,先附上mysql內部邏輯圖讓大家有所了解

① SQL語句及索引的優化

SQL語句的優化:

1、盡量避免使用子查詢

2、避免函數索引

3、用IN來替換OR

另外,MySQL對于IN做了相應的優化,即將IN中的常量全部存儲在一個數組里面,而且這個數組是排好序的。但是如果數值較多,產生的消耗也是比較大的。再例如:select id from table_name where num in(1,2,3) 對于連續的數值,能用 between 就不要用 in 了;再或者使用連接來替換。

4、LIKE前綴%號、雙百分號、_下劃線查詢非索引列或*無法使用到索引,如果查詢的是索引列則可以

5、讀取適當的記錄LIMIT M,N,而不要讀多余的記錄

select id,name from table_name limit 866613, 20

使用上述sql語句做分頁的時候,可能有人會發現,隨著表數據量的增加,直接使用limit分頁查詢會越來越慢。

優化的方法如下:可以取前一頁的最大行數的id,然后根據這個最大的id來限制下一頁的起點。比如此列中,上一頁最大的id是866612。sql可以采用如下的寫法:

select id,name from table_name where id> 866612 limit 20

6、避免數據類型不一致

7、分組統計可以禁止排序sort,總和查詢可以禁止排重用union all

union和union all的差異主要是前者需要將結果集合并后再進行唯一性過濾操作,這就會涉及到排序,增加大量的CPU運算,加大資源消耗及延遲。**當然,union all的前提條件是兩個結果集沒有重復數據。**所以一般是我們明確知道不會出現重復數據的時候才建議使用 union all 提高速度。

另外,如果排序字段沒有用到索引,就盡量少排序;

8、避免隨機取記錄

9、禁止不必要的ORDER BY排序

10、批量INSERT插入

11、不要使用NOT等負向查詢條件

你可以想象一下,對于一棵B+樹,根節點是40,如果你的條件是等于20,就去左面查,你的條件等于50,就去右面查,但是你的條件是不等于66,索引應該咋辦?還不是遍歷一遍才知道。

12、盡量不用select *

SELECT *增加很多不必要的消耗(cpu、io、內存、網絡帶寬);增加了使用覆蓋索引的可能性;當表結構發生改變時,前者也需要經常更新。所以要求直接在select后面接上字段名。

13、區分in和exists

select * from 表A where id in (select id from 表B)

上面sql語句相當于

select * from 表A where exists(select * from 表B where 表B.id=表A.id)

區分in和exists主要是造成了驅動順序的改變(這是性能變化的關鍵),如果是exists,那么以外層表為驅動表,先被訪問,如果是IN,那么先執行子查詢。所以IN適合于外表大而內表小的情況;EXISTS適合于外表小而內表大的情況。

索引的優化:

1、Join語句的優化

Join 性能點

當我們執行兩個表的Join的時候,就會有一個比較的過程,逐條比較兩個表的語句是比較慢的,因此可以把兩個表中數據依次讀進一個內存塊中,在Mysql中執行:show variables like 'join_buffer_size',可以看到join在內存中的緩存池大小,其大小將會影響join語句的性能。

在執行join的時候,數據庫會選擇一個表把他要返回以及需要進行和其他表進行比較的數據放進join_buffer。

如果是有索引的情況,則直接讀取兩個表的索引樹進行比較就可以了。

若沒有索引,則會使用 'Block nested loop' 算法,Block 塊,也就是說每次都會取一塊數據到內存以減少I/O的開銷

另外,Innodb會為每個數據表分配一個存儲在磁盤的 表名.ibd 文件,若關聯的表過多,將會導致查詢的時候磁盤的磁頭移動次數過多,從而影響性能

所以實踐中,盡可能減少Join語句中的NestedLoop的循環次數:“永遠用小結果集驅動大的結果集”

  • 用小結果集驅動大結果集,將篩選結果小的表首先連接,再去連接結果集比較大的表,盡量減少join語句中的Nested Loop的循環總次數
  • 優先優化Nested Loop的內層循環(也就是最外層的Join連接),因為內層循環是循環中執行次數最多的,每次循環提升很小的性能都能在整個循環中提升很大的性能;
  • 對被驅動表的join字段上建立索引;
  • 當被驅動表的join字段上無法建立索引的時候,設置足夠的Join Buffer Size。
  • 盡量用inner join(因為其會自動選擇小表去驅動大表).避免 LEFT JOIN (一般我們使用Left Join的場景是大表驅動小表)和NULL,那么如何優化Left Join呢?
    1、條件中盡量能夠過濾一些行將驅動表變得小一點,用小表去驅動大表
    2、右表的條件列一定要加上索引(主鍵、唯一索引、前綴索引等),最好能夠使type達到range及以上(ref,eq_ref,const,system)
  • 適當地在表里面添加冗余信息來減少join的次數
  • 使用更快的固態硬盤
  • 性能優化,left join 是由左邊決定的,左邊一定都有,所以右邊是我們的關鍵點,建立索引要建在右邊。當然如果索引是在左邊的,我們可以考慮使用右連接,如下

    select * from atable left join btable on atable.aid=btable.bid;//最好在bid上建索引

    (Tips:Join左連接在右邊建立索引;組合索引則盡量將數據量大的放在左邊,在左邊建立索引)

    2、避免索引失效

    1.最佳左前綴法則

    如果索引了多列,要遵守最左前綴法則,指的是查詢從索引的最左前列開始并且不跳過索引中的列。Mysql查詢優化器會對查詢的字段進行改進,判斷查詢的字段以哪種形式組合能使得查詢更快,所有比如創建的是(a,b)索引,查詢的是(b,a),查詢優化器會修改成(a,b)后使用索引查詢。

    2.不在索引列上做任何操作

    (計算、函數、(自動or手動)類型轉換),會導致索引失效而轉向全表掃描。

    3.存儲引擎不能使用索引中范圍條件右邊的列。

    如這樣的sql: select * from user where username='123' and age>20 and phone='1390012345',其中username, age, phone都有索引,只有username和age會生效,phone的索引沒有用到。

    4.盡量使用覆蓋索引(只訪問索引的查詢(索引列和查詢列一致))

    如select age from user減少`select *``

    5.mysql在使用不等于(!= 或者 <>)的時候無法使用索引會導致全表掃描。

    6.is null, is not null 也無法使用索引,在實際中盡量不要使用null。

    7.like 以通配符開頭(‘%abc..’)mysql索引失效會變成全表掃描的操作。

    所以最好用右邊like 'abc%'。如果兩邊都要用,可以用select age from user where username like '%abc%',其中age是必須是索引列,才可讓索引生效

    假如index(a,b,c), where a=3 and b like 'abc%' and c=4,a能用,b能用,c不能用,類似于不能使用范圍條件右邊的列的索引

    對于一棵B+樹來講,如果根是字符def,如果通配符在后面,例如abc%,則應該搜索左面,例如efg%,則應該搜索右面,如果通配符在前面%abc,則不知道應該走哪一面,還是都掃描一遍吧。

    8.字符串不加單引號索引失效

    9.少用or,用它來連接時會索引失效

    10.盡量避免子查詢,而用join

    11、在組合索引中,將有區分度的索引放在前面

    如果沒有區分度,例如用性別,相當于把整個大表分成兩部分,查找數據還是需要遍歷半個表才能找到,使得索引失去了意義。

    12、避免在 where 子句中對字段進行 null 值判斷

    對于null的判斷會導致引擎放棄使用索引而進行全表掃描。

    ② 數據庫表結構的優化:使得數據庫結構符合三大范式與BCNF

    ③ 系統配置的優化

    ④ 硬件的優化

    總結

    以上是生活随笔為你收集整理的mysql not in优化_实践中如何优化MySQL(收藏)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。