MySQL---正確使用索引、limit分頁、執行計劃、慢日誌查詢

来源:https://www.cnblogs.com/horror/archive/2018/08/25/9535648.html
-Advertisement-
Play Games

正確使用索引 資料庫表中添加索引後確實會讓查詢速度起飛,但前提必須是正確的使用索引來查詢,如果以錯誤的方式使用,則即使建立索引也會不奏效。即使建立索引,索引也不會生效: 其他註意事項 limit分頁 無論是否有索引,limit分頁是一個值得關註的問題 1 每頁顯示10條: 2 當前 118 120, ...


正確使用索引

資料庫表中添加索引後確實會讓查詢速度起飛,但前提必須是正確的使用索引來查詢,如果以錯誤的方式使用,則即使建立索引也會不奏效。
即使建立索引,索引也不會生效:

 1 - like '%xx'
 2     select * from tb1 where name like '%cn';
 3 - 使用函數
 4     select * from tb1 where reverse(name) = 'wupeiqi';
 5 - or
 6     select * from tb1 where nid = 1 or email = '[email protected]';
 7     特別的:當or條件中有未建立索引的列才失效,以下會走索引
 8             select * from tb1 where nid = 1 or name = 'seven';
 9             select * from tb1 where nid = 1 or email = '[email protected]' and name = 'alex'
10 - 類型不一致
11     如果列是字元串類型,傳入條件是必須用引號引起來,不然...
12     select * from tb1 where name = 999;
13 - !=
14     select * from tb1 where name != 'alex'
15     特別的:如果是主鍵,則還是會走索引
16         select * from tb1 where nid != 123
17 - >
18     select * from tb1 where name > 'alex'
19     特別的:如果是主鍵或索引是整數類型,則還是會走索引
20         select * from tb1 where nid > 123
21         select * from tb1 where num > 123
22 - order by
23     select email from tb1 order by name desc;
24     當根據索引排序時候,選擇的映射如果不是索引,則不走索引
25     特別的:如果對主鍵排序,則還是走索引:
26         select * from tb1 order by nid desc;
27  
28 - 組合索引最左首碼
29     如果組合索引為:(name,email)
30     name and email       -- 使用索引
31     name                 -- 使用索引
32     email                -- 不使用索引

其他註意事項

1 - 避免使用select *
2 - count(1)或count(列) 代替 count(*)
3 - 創建表時儘量時 char 代替 varchar
4 - 表的欄位順序固定長度的欄位優先
5 - 組合索引代替多個單列索引(經常使用多個條件查詢時)
6 - 儘量使用短索引
7 - 使用連接(JOIN)來代替子查詢(Sub-Queries)
8 - 連表時註意條件類型需一致
9 - 索引散列值(重覆少)不適合建索引,例:性別不適合

limit分頁

無論是否有索引,limit分頁是一個值得關註的問題

 1 每頁顯示10條:
 2 當前 118 120, 125
 3 
 4 倒序:
 5             大      小
 6    970  7 6  6 5  54  43  32
 7 19 98     
 8 下一頁:
 9 
10     select 
11         * 
12     from 
13         tb1 
14     where 
15         nid < (select nid from (select nid from tb1 where nid < 當前頁最小值 order by nid desc limit 每頁數據 *【頁碼-當前頁】) A order by A.nid asc limit 1)  
16     order by 
17         nid desc 
18     limit 10;
19 
20 
21 
22     select 
23         * 
24     from 
25         tb1 
26     where 
27         nid < (select nid from (select nid from tb1 where nid < 970  order by nid desc limit 40) A order by A.nid asc limit 1)  
28     order by 
29         nid desc 
30     limit 10;
31 
32 
33 上一頁:
34 
35     select 
36         * 
37     from 
38         tb1 
39     where 
40         nid < (select nid from (select nid from tb1 where nid > 當前頁最大值 order by nid asc limit 每頁數據 *【當前頁-頁碼】) A order by A.nid asc limit 1)  
41     order by 
42         nid desc 
43     limit 10;
44 
45 
46     select 
47         * 
48     from 
49         tb1 
50     where 
51         nid < (select nid from (select nid from tb1 where nid > 980 order by nid asc limit 20) A order by A.nid desc limit 1)  
52     order by 
53         nid desc 
54     limit 10;
View Code

執行計劃

explain + 查詢SQL - 用於顯示SQL執行信息參數,根據參考信息可以進行SQL優化

1 mysql> explain select * from tb2;
2 +----+-------------+-------+------+---------------+------+---------+------+------+-------+
3 | id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra |
4 +----+-------------+-------+------+---------------+------+---------+------+------+-------+
5 |  1 | SIMPLE      | tb2   | ALL  | NULL          | NULL | NULL    | NULL |    2 | NULL  |
6 +----+-------------+-------+------+---------------+------+---------+------+------+-------+
7 1 row in set (0.00 sec)
 1 id
 2         查詢順序標識
 3             如:mysql> explain select * from (select nid,name from tb1 where nid < 10) as B;
 4             +----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+
 5             | id | select_type | table      | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
 6             +----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+
 7             |  1 | PRIMARY     | <derived2> | ALL   | NULL          | NULL    | NULL    | NULL |    9 | NULL        |
 8             |  2 | DERIVED     | tb1        | range | PRIMARY       | PRIMARY | 8       | NULL |    9 | Using where |
 9             +----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+
10         特別的:如果使用union連接氣值可能為null
11 
12 
13     select_type
14         查詢類型
15             SIMPLE          簡單查詢
16             PRIMARY         最外層查詢
17             SUBQUERY        映射為子查詢
18             DERIVED         子查詢
19             UNION           聯合
20             UNION RESULT    使用聯合的結果
21             ...
22     table
23         正在訪問的表名
24 
25 
26     type
27         查詢時的訪問方式,性能:all < index < range < index_merge < ref_or_null < ref < eq_ref < system/const
28             ALL             全表掃描,對於數據表從頭到尾找一遍
29                             select * from tb1;
30                             特別的:如果有limit限制,則找到之後就不在繼續向下掃描
31                                    select * from tb1 where email = '[email protected]'
32                                    select * from tb1 where email = '[email protected]' limit 1;
33                                    雖然上述兩個語句都會進行全表掃描,第二句使用了limit,則找到一個後就不再繼續掃描。
34 
35             INDEX           全索引掃描,對索引從頭到尾找一遍
36                             select nid from tb1;
37 
38             RANGE          對索引列進行範圍查找
39                             select *  from tb1 where name < 'alex';
40                             PS:
41                                 between and
42                                 in
43                                 >   >=  <   <=  操作
44                                 註意:!= 和 > 符號
45 
46 
47             INDEX_MERGE     合併索引,使用多個單列索引搜索
48                             select *  from tb1 where name = 'alex' or nid in (11,22,33);
49 
50             REF             根據索引查找一個或多個值
51                             select *  from tb1 where name = 'seven';
52 
53             EQ_REF          連接時使用primary key 或 unique類型
54                             select tb2.nid,tb1.name from tb2 left join tb1 on tb2.nid = tb1.nid;
55 
56 
57 
58             CONST           常量
59                             表最多有一個匹配行,因為僅有一行,在這行的列值可被優化器剩餘部分認為是常數,const表很快,因為它們只讀取一次。
60                             select nid from tb1 where nid = 2 ;
61 
62             SYSTEM          系統
63                             表僅有一行(=系統表)。這是const聯接類型的一個特例。
64                             select * from (select nid from tb1 where nid = 1) as A;
65     possible_keys
66         可能使用的索引
67 
68     key
69         真實使用的
70 
71     key_len
72         MySQL中使用索引位元組長度
73 
74     rows
75         mysql估計為了找到所需的行而要讀取的行數 ------ 只是預估值
76 
77     extra
78         該列包含MySQL解決查詢的詳細信息
79         “Using index”
80             此值表示mysql將使用覆蓋索引,以避免訪問表。不要把覆蓋索引和index訪問類型弄混了。
81         “Using where”
82             這意味著mysql伺服器將在存儲引擎檢索行後再進行過濾,許多where條件里涉及索引中的列,當(並且如果)它讀取索引時,就能被存儲引擎檢驗,因此不是所有帶where子句的查詢都會顯示“Using where”。有時“Using where”的出現就是一個暗示:查詢可受益於不同的索引。
83         “Using temporary”
84             這意味著mysql在對查詢結果排序時會使用一個臨時表。
85         “Using filesort”
86             這意味著mysql會對結果使用一個外部索引排序,而不是按索引次序從表裡讀取行。mysql有兩種文件排序演算法,這兩種排序方式都可以在記憶體或者磁碟上完成,explain不會告訴你mysql將使用哪一種文件排序,也不會告訴你排序會在記憶體里還是磁碟上完成。
87         “Range checked for each record(index map: N)”
88             這個意味著沒有好用的索引,新的索引將在聯接的每一行上重新估算,N是顯示在possible_keys列中索引的點陣圖,並且是冗餘的。
詳細

慢日誌查詢

a、配置MySQL自動記錄慢日誌

1 slow_query_log = OFF                            是否開啟慢日誌記錄
2 long_query_time = 2                              時間限制,超過此時間,則記錄
3 slow_query_log_file = /usr/slow.log        日誌文件
4 log_queries_not_using_indexes = OFF     為使用索引的搜索是否記錄

註:查看當前配置信息:
       show variables like '%query%'
     修改當前配置:
    set global 變數名 = 值

b、查看MySQL慢日誌

mysqldumpslow -s at -a  /usr/local/var/mysql/MacBook-Pro-3-slow.log

 1 """
 2 --verbose    版本
 3 --debug      調試
 4 --help       幫助
 5  
 6 -v           版本
 7 -d           調試模式
 8 -s ORDER     排序方式
 9              what to sort by (al, at, ar, c, l, r, t), 'at' is default
10               al: average lock time
11               ar: average rows sent
12               at: average query time
13                c: count
14                l: lock time
15                r: rows sent
16                t: query time
17 -r           反轉順序,預設文件倒序拍。reverse the sort order (largest last instead of first)
18 -t NUM       顯示前N條just show the top n queries
19 -a           不要將SQL中數字轉換成N,字元串轉換成S。don't abstract all numbers to N and strings to 'S'
20 -n NUM       abstract numbers with at least n digits within names
21 -g PATTERN   正則匹配;grep: only consider stmts that include this string
22 -h HOSTNAME  mysql機器名或者IP;hostname of db server for *-slow.log filename (can be wildcard),
23              default is '*', i.e. match all
24 -i NAME      name of server instance (if using mysql.server startup script)
25 -l           總時間中不減去鎖定時間;don't subtract lock time from total time
26 """

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • iOS安裝包所需的p12文件,需要開發者自行生成,在此,qio763分享了此次生成p12文件的經驗,無論是初學iOS原生開發,還是.NET移動開發平臺的smobiler,在生成iOS安裝包之前,p12文件生成這一步都是必經之路 ...
  • #安裝以下包以使apt可以通過HTTPS使用存儲庫(repository): $ sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common #添加Docker官方的GPG密鑰... ...
  • 第1章 學習方法及工具 1.1 學習方法 保證每天學習時間(10小時),學習按照企業要求,以高薪為結果 先預習à看書、看視頻à寫作業à複習à總結 1.2 學習工具 1.2.1 筆記類 會使用Notepad++、有道雲筆記、印象筆記、馬克飛象、為知筆記、Markdown(Markdown是一種可以使用 ...
  • IIS 反向代理可以將請求的網址重寫到其它網址,達到轉發的目的。一般用於一臺伺服器只允許開啟80埠,而80埠又被IIS使用,此時需要在IIS中設置URL重寫,將請求轉發到指定 `IP:埠` 或網址 ...
  • 安裝Ubuntu 18.04後,使用國外源太慢了,修改為國內源會快很多。 修改阿裡源為Ubuntu 18.04預設的源 備份/etc/apt/sources.list #備份 cp /etc/apt/sources.list /etc/apt/sources.list.bak 在/etc/apt/s ...
  • 1、下載centos7manimal.iso 下載地址: http://isoredirect.centos.org/centos/7/isos/x86_64/CentOS-7-x86_64-Minimal-1804.iso 2、虛擬機配置自定義,在這裡選好鏡像文件裡面就不用選了 3、配置好以後開啟 ...
  • 今天在Vmware上安裝了CentOS6.5系統,下午首先把書上的安裝過程看了一遍,實際進行操作時有些步驟不一樣,經過查資料成功安裝,說一下收穫。選擇自定義安裝虛擬機,首先創建空白虛擬機,稍後編輯虛擬機,選擇DVD,添加鏡像。將磁碟以單文件形式使用,選擇亞洲上海時區,註意取消使用UTC。選擇Linu ...
  • 一 zabbix 的安裝部署 略 二監控 apache服務的配置 首先在本機下載模板:https://github.com/rdvn/zabbix-templates/archive/m aster.zip 該 zip 包有 apache、memcache、redis、varnish 模板,我們解壓 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...