国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

教您如何為MYSQL表聯結做索引 讓表聯系更有效率(譯文)

數據庫 MySQL
該怎么為表做索引,才能使表聯系更有效率?看似一個很簡單的問題,但該問題需要仔細研究基于為表聯系做索引的基本理論才能給出答案。

經常看到有人問:"我該怎么為表做索引,才能使表聯系更有效率?",經常,有些人給出了答案,但是這些答案并沒有基于為表聯系做索引的基本理論.

這篇文章的目的就是描述MYSQL表聯結索引的基本理論,以一個很簡單的示例開始,為大家展示MYSQL表聯結的基本原理,然后再應用這些原理到更加復雜的4個表聯結的請求。

我盡可能使用一些簡單的測試數據,畢竟我們關心的是理論而不是表哪些表的哪些數據.因此我們就考慮這三個表:tblA,tblB,tblC. 每個表都有3列:col1,col2,col3(這樣并不符合標準).現在列的類型,表的意義,以及計劃要存儲哪種數據,對我們來說沒有關系.

  1. SELECT * FROM tblA, tblB,tblC     
  2. WHERE   
  3. tblA.col1 = tblB.col1   
  4. AND tblA.col2 = tblC.col1;  
  5.  

And EXPLAIN for the query:

  1. +-------+------+---------------+------+---------+------+------+-------------+     
  2. | table | type | possible_keys | key  | key_len | ref  | rows | Extra       |    
  3.  
  4. +-------+------+---------------+------+---------+------+------+-------------+     
  5. | tblA  | ALL  | NULL          | NULL |    NULL | NULL | 1000 |             |     
  6. | tblB  | ALL  | NULL          | NULL |    NULL | NULL | 1000 | Using where |     
  7. | tblC  | ALL  | NULL          | NULL |    NULL | NULL | 1000 | Using where |    
  8.  +-------+------+---------------+------+---------+------+------+-------------+  
  9.  

表實列出來使用這個命令,MYSQL當處理所有聯結時,使用一次掃描,多次聯結的方法.這就意味著mysql從第一個表讀一行,然后在第二個表中找一匹配行然后再在第三個表中找,等等.當所有的表都找完后,MYSQL輸出查詢的列并通過表清單回溯直到在一個表中找到更多的匹配行.再從表中讀取下行,再繼續處理下個表.

正如MYSQL手冊那個章節所說,當用explain命令去輸出表時,MYSQL先讀第一個表tblA,然后第二個表tblB,然后第三個表tblC,等等.來自前一個表的值被用于在當前表中找匹配的行.在我們的例子中,tblA中的值被用于找tblB中的行,然后來自tblB中的值被用于找tblC中的行.一旦一次全掃描完成(找到匹配行,在tblA,tblB,tblC),MYSQL并不返回tblA,它將返回tblB去看是否有更多的行和與當前來自tblA的值匹配.如果有,它得到這行,然后再到tblC中去匹配行.最重要的就是這是MYSQL連接的基本原理.
以EXPLAIN命令輸出的列,前一個表的值被用于查找當前表的匹配行.

從原理到實際做索引

了解了MYSQL使用tblA中的值去找tblB的行.我們怎么去增加索引來幫助MYSQL?為了幫助MYSQL(或者人或者相關的事物)我們都必須知道它需要什么.MYSQL需要的就是怎樣的聯結方式.你的聯結方式就是MYSQL需要的.考慮一下tblA和tblB的聯結:兩個表以tblA.col1 = tblB.col1,所以MYSQL需要一個tblB.col1,這樣mysql就能完成等式.因此,如果mysql需要tblB.col1,然后,我們就應該給tblB.col1加索引,下邊就是新的explan的同一個請求:

  1. +-------+------+---------------+----------+---------+-----------+------+-------------+     
  2. | table | type | possible_keys | key      | key_len | ref       | rows | Extra       |     
  3. +-------+------+---------------+----------+---------+-----------+------+-------------+     
  4. | tblA  | ALL  | NULL          | NULL     |    NULL | NULL      | 1000 |             |     
  5. | tblB  | ref  | ndx_col1      | ndx_col1 |       5 | tblA.col1 |    1 | Using where |    
  6. | tblC  | ALL  | NULL          | NULL     |    NULL | NULL      | 1000 | Using where |     
  7. +-------+------+---------------+----------+---------+-----------+------+-------------+  
  8.  

正如我們看到的,MYSQL現在使用了 ndx_col1來把tblB連到tblA上.當MYSQL在tblB中找到行,就不會像之前那樣掃描,它使用tblA.col1的值和ndx_col1索引,直接取出匹配的行.這就是為什么tblB表的ref列是:"tblA.col1"tblC仍然是全表掃描.但是我們也可以用同樣的tblA和tblB的方式來修復,通過查看MYSQL的需求:通過請求的"tblA.col2 = tblC.col1,"這部分,我們看到它需要tblC.col1因為我們已經有tblA.col2.把這列加上索引,explain就會出現下邊:

  1. +-------+------+---------------+----------+---------+| table | type | possible_keys | key      | key_len | ref       | rows | Extra       |    
  2. +-------+------+---------------+----------+---------+  
  3. | tblA  | ALL  | NULL          | NULL     |    NULL | NULL      | 1000 |             |     
  4. | tblB  | ref  | ndx_col1      | ndx_col1 |       5 | tblA.col1 |    1 | Using where |     
  5. | tblC  | ref  | ndx_col1      | ndx_col1 |       5 | tblA.col2 |    1 | Using where |     
  6. +-------+------+---------------+----------+---------+ 

有難度的部分?

真實環境中,你也許根本不會看到像上邊的SQL請求.你更多可能遇到像這樣的SQL:

  1. SELECT        
  2.       COUNT(tblB.a_id) as correct,  
  3.       tblA.type,  
  4.       tblA.se_type     
  5.    FROM      tblA,  
  6.       tblB,  
  7.       tblC,   
  8.       tblD     
  9.    WHERE   
  10.       tblA.ex_id = tblC.ex_id  
  11.       AND tblC.st_ex_id = tblB.st_ex_id   
  12.       AND tblB.q_num = tblA.q_num   
  13.       AND tblB.se_num = tblA.se_num        
  14. AND tblD.ex_id = tblA.ex_id  
  15.       AND tblD.exp <> tblB.se_num  
  16.       AND tblB.ans = tblA.ans  
  17.       AND tblA.ex_id = 1001 
  18.       AND tblC.r_id = 542     
  19. GROUP BY        
  20.       tblA.type,  
  21.       tblA.se_type;  
  22.  

一看上去有點令人畏懼的query:4個表.一個統計函數,9個where條件,一個groupby .EXPLAIN強大之處就是
我們能不理所有這些現在,并很容易接近它每次兩個表,正如我們之前做的那樣,決定每一步mysql需要什么.
這是一個真正的需求.所有的表和列都重命名去保護原來的一致.開始之前,先EXPLAIN:

  1. +-------+--------+---------------+---------+---------+---------------+-------+----------------------------------------------+    
  2. | table | type | possible_keys | key | key_len | ref| rows  | Extra                        |     
  3. +-------+--------+---------------+---------+---------+---------------+-------+----------------------------------------------+     
  4. | tblA  | ALL    | NULL          | NULL    |    NULL | NULL          |  1080 | Using where; Using temporary; Using filesort |     
  5. | tblB  | ALL    | NULL          | NULL    |    NULL | NULL          | 87189 | Using where                                  |     
  6. | tblC  | eq_ref | PRIMARY       | PRIMARY |       4 | tblB.st_ex_id |     1 | Using where                                  |     
  7. | tblD  | eq_ref | PRIMARY       | PRIMARY |       4 | tblA.ex_id    |     1 | Using where                                  |     
  8. +-------+--------+---------------+---------+---------+---------------+-------+----------------------------------------------+  
  9.  

首先一個決定的一個詞影響一個聯結:結果集. 一個結果集,顯然來自一個請求的結果集.為了聯結,MYSQL
需要讀每個表來估計有多少行數據.壞情況結束了,因為其它where條件將減少請求產生的行數.這個 請求產生的94百萬行結果集.這就是為什么缺少索引是多么危險.幾千行的幾千倍,數量級已達到百萬級了.

現在這個請求需要什么?從tblA和tblBga 開始.找出請求中兩個表在哪里聯結:
AND tblB.q_num = tblA.q_num
AND tblB.se_num = tblA.se_num
AND tblB.ans = tblA.ans

MYSQL至少需要 q_num,se_num,ans.我選擇把q_num和se_num做索引,因為在我查看的其它請求中,這些列最經常用到.折中是優化的一部分.再專業也不能去絕對的為每一條單獨請求找到最合適的索引.相反,你只能找到最經常使用的.在這個例子中,我們將性能改變.在tblB 上索引(se_num, q_num),EXPLAIN:

  1. +-------+--------+---------------+-------------+---------+------------------------+------+----------------------------------------------+  
  2. | table | type   | possible_keys | key         | key_len | ref                    | rows | Extra                                        |  
  3. +-------+--------+---------------+-------------+---------+------------------------+------+----------------------------------------------+  
  4. | tblA | ALL    | NULL          | NULL        |    NULL | NULL                   | 1080 | Using where; Using temporary; Using filesort |  
  5. | tblB | ref    | ndx_secn_qn   | ndx_secn_qn |       2 | tblA.se_num,tblA.q_num | 641 | Using where                                  |  
  6. | tblC | eq_ref | PRIMARY       | PRIMARY     |       4 | tblB.st_ex_id          |    1 | Using where                                  |  
  7. | tblD | eq_ref | PRIMARY       | PRIMARY     |       4 | tblA.ex_id             |    1 | Using where                                  |  
  8. +-------+--------+---------------+-------------+---------+------------------------+------+----------------------------------------------+  

請求的結果集降低了 99.3%達到692280行.但是為什么止于此呢?我們能很容易的處理tblA的全表掃描.往往,為第一個表索引,就像為單獨一個表做索引.在這種情況下,你查看請求的SQL,看是否表正在被另外的方式限制.在這個情況,我們幸運看到tblA的條件:"AND tblA.ex_id = 1001". 因為我們在優化的講座的case 1:基本索引,我們所做的就是索引 ex_id 在表tblA上.

  1. +-------+--------+---------------+-------------+---------+------------------------+------+-  
  2. | table | type   | possible_keys | key         | key_len | ref                    | rows | Extra                                        |  
  3. +-------+--------+---------------+-------------+---------+------------------------+------+-  
  4. | tblA | ref    | ndx_ex_id | ndx_ex_id   |    4 | const                  |    1 | Using where; Using temporary; Using filesort |  
  5. | tblB | ref    | ndx_secn_qn | ndx_secn_qn |  2 | tblA.se_num,tblA.q_num | 641 | Using where                                  |  
  6. | tblC | eq_ref | PRIMARY | PRIMARY     |      4 | tblB.st_ex_id          |    1 | Using where                                  |  
  7. | tblD | eq_ref | PRIMARY  | PRIMARY     |     4 | tblA.ex_id             |    1 | Using where                                  |  
  8. +-------+--------+---------------+-------------+---------+------------------------+------+-  
  9.  

現在請求的結果集是641行!從94百萬行降下來.你看幾科是100%的減少量.進一步研究查詢請求,我們還能處理掉,extra中的usring tempory,usring filesort.盡管最初看上去是挑戰,我們看到,如果你第次以兩個表處理,隔離并索引MYSQL需要的,為聯結做過引并不困難:

結論:

使復雜的聯結和知道在哪里索引成為簡單的工作就要意識到兩件事:

1.無論多復雜的請求,你僅僅以兩個MYSQL表聯結的途徑處理在EXPLAIN列出來的清單中的順序.

2.來自前一個表的值已經找到;我們工作就是幫助MYSQL使用索引這些找到的值在當前的表上來找到匹配的行.
 

 

【編輯推薦】

MySQL批量導入數據的實現

mysql拷貝表的幾種方式

mysql快速建表的方法

深入研究MySQL刪除多表數據

多個MySQL表結果集組合

 


 

責任編輯:段燃 來源: 百度空間
相關推薦

2016-04-28 16:17:44

又拍云/CDN

2020-12-09 22:00:38

GitLinux版本控制系統

2021-07-12 14:50:25

Linux命令文件

2020-12-22 10:46:42

Windows10操作系統應用

2010-11-24 14:03:28

mysql表索引

2011-05-04 16:56:45

激光一體機使用技巧

2010-10-12 14:53:31

mysql索引優化

2017-05-10 09:53:55

奧菲 傳媒

2010-10-13 15:59:21

MySQL索引

2009-08-25 17:31:57

C#讀取文件

2010-09-16 15:48:03

SQL Server系

2013-10-16 09:51:21

時間管理效率管理

2010-11-24 10:35:34

MySQL單表多字段

2021-01-27 13:28:55

編程語言Python

2010-09-17 13:35:30

SQL跨表更新

2010-10-13 09:37:48

MYSQL修改表結構

2010-11-23 14:19:12

MySQL注冊表

2010-09-25 10:41:34

SQL SERVER主

2010-09-28 14:52:37

SQL表結構

2016-03-28 10:11:37

點贊
收藏

51CTO技術棧公眾號

国产综合视频| 7m精品福利视频导航| 精品一区二区视频| 欧美3p视频| 国产精品一区二区三| 欧美日韩1区| 亚洲成人精品电影在线观看| 宅男噜噜噜66一区二区| www.亚洲视频.com| 国产成人在线免费观看| 国产又粗又大又爽的视频| 麻豆一区二区在线| 日韩精品手机在线观看| 国产精品免费看片| 国产日韩欧美二区| 在线日本欧美| 婷婷综合五月天| 涩涩涩999| 久久久噜噜噜久久人人看 | 欧日韩精品视频| 亚洲免费一区三区| 久久久久免费视频| 99re热精品视频| 色综合久久久久久久久久久| 激情五月亚洲色图| 亚洲精品按摩视频| 欧美精品一区二区三区中文字幕| 色综合色综合久久综合频道88| 成人av影视| 久久综合色综合88| 人人妻人人添人人爽欧美一区| 精品视频在线观看免费观看| 日韩专区一卡二卡| 中文字幕日韩电影| 在线观看国产一级片| 另类在线视频| 2023国产精品| 国严精品久久久久久亚洲影视| 综合中文字幕| 亚洲高清视频在线| 国产在线制服美女| 久精品免费视频| 校花撩起jk露出白色内裤国产精品| 国模精品视频一区二区| 成人免费观看在线观看| 欧美一级高清大全免费观看| 18加网站在线| 午夜精品福利一区二区三区蜜桃| 亚洲欧洲日本精品| 午夜精品一区在线观看| 成人手机在线播放| 天天射成人网| 国产视频不卡| 亚洲视频日本| 久草热久草在线频| 亚洲欧美综合色| av免费网站观看| 日韩avvvv在线播放| 亚洲xxx自由成熟| 91在线一区| 亚洲美女动态图120秒| 国产youjizz在线| 亚洲精品乱码久久久久久金桔影视| sm久久捆绑调教精品一区| 日韩大片在线观看视频| 国产成人精品免费视| 精品久久精品久久| 日本不卡视频在线观看| 五月婷婷导航| 中文字幕在线一区二区三区| 久久免费视频2| 在线精品一区| 国产免费xxx| 亚洲二区精品| wwwxx欧美| 亚洲精品欧洲| 日本999视频| 亚洲精品国产suv| 国产精品论坛| 亚洲人成在线播放| 欧美亚洲黄色| 国产成人a亚洲精品| 国产精品午夜久久| 久久一区中文字幕| 精品素人av| 日韩欧美一中文字暮专区| www亚洲成人| 天天爽天天狠久久久| 国产美女精彩久久| 日日骚av一区| 精品盗摄一区二区三区| 一本大道久久a久久综合| 国产精品69久久久久水密桃| 欧美成人milf| 综合欧美亚洲| av成人在线网站| 欧美艳星kaydenkross| 久久mv成人精品亚洲动漫| 国产尤物99| 美女视频久久黄| 日韩午夜激情免费电影| 一区二区三区在线免费| 亚洲欧美日韩专区| 成人av地址| a级影片在线观看| 97碰碰碰免费公开在线视频| 欧美精品亚洲精品| 98视频在线噜噜噜国产| 制服视频三区第一页精品| 亚洲视频中文字幕| 99精品视频在线观看免费| 欧美三级三级| 国产专区中文字幕| 日韩国产高清视频在线| 国产欧美1区2区3区| 亚洲一区二区美女| 日韩欧美国产午夜精品| 亚洲成人久久一区| 黄色国产精品| av中文字幕在线| 日韩精品综合在线| 国产精品自拍网| 精品av久久707| 中文字幕一区二| 免费人成在线观看播放视频| 国产精品吴梦梦| 懂色av中文字幕一区二区三区 | 国产一区999| 成人短剧在线观看| 久久久久亚洲精品| 日本一区二区免费高清| 少妇无码av无码专区在线观看| 国产日产欧美一区二区视频| 日韩欧美一区二区三区在线观看| 国产精品12| 色婷婷综合激情| 影音先锋久久久| 天堂av中文在线| 久久精品国产综合| 日韩成人精品在线| 啦啦啦中文高清在线视频| 欧美激情精品久久久| 国产美女在线精品| 超碰超碰人人人人精品| 97久久天天综合色天天综合色hd| 午夜婷婷国产麻豆精品| 99精品国产一区二区三区2021| 鲁一鲁一鲁一鲁一澡| 久久在精品线影院精品国产| 另类人妖一区二区av| 国产精品theporn| 奇米亚洲午夜久久精品| 久久免费资源| av在线电影网站| 在线观看国产高清视频| 一区二区三区视频国产日韩 | 亚洲一区中文日韩| 亚洲免费看黄网站| 91九色02白丝porn| 亚洲欧美一区二区激情| 精品亚洲一区二区三区在线播放| 国产一区二区三区在线视频| 欧美疯狂xxxx大交乱88av| 欧美在线观看网站| 少妇久久久久久| 中文字幕免费精品一区高清| 国产性猛交xxxx免费看久久| 精品视频久久久久久久| 欧美一区二区日韩| 日韩你懂的在线观看| 国产视频一区在线| 亚洲天堂av高清| 中文字幕亚洲一区二区三区五十路| 精品国产乱码久久久久久虫虫漫画| 欧美国产1区2区| 中文字幕精品一区二区三区精品| 亚洲网址在线| av成人资源| 小说区图片区亚洲| 国产九色精品成人porny | 伊人久久av导航| 国产999在线观看| 精品网站999www| 欧美在线|欧美| 懂色中文一区二区在线播放| 婷婷综合激情| 亚洲动漫在线观看| 亚洲va久久| 精品av一区二区| 偷拍精品精品一区二区三区| 美女网站在线| 亚洲电影有码| 日韩成人免费看| 激情图片小说一区| 欧美日韩美女在线观看| 亚洲午夜激情网页| 精品乱人伦一区二区三区| 亚洲欧美国产精品| 日韩福利在线播放| 国产精品黄色av|