自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

MySQL的四種不同查詢的分析

數(shù)據(jù)庫 MySQL
MYSQL的全表掃描,主鍵索引(聚集索引、第一索引),非主鍵索引(非聚集索引、第二索引),覆蓋索引四種不同查詢的分析。

1.前置條件:

本次是基于小數(shù)據(jù)量,且數(shù)據(jù)塊在一個(gè)頁中的最理想情況進(jìn)行分析,可能無具體的實(shí)際意義,但是可以借鑒到各種復(fù)雜條件下,因?yàn)樵硎窍嗤?知小見大,見微知著!

 

打開語句分析并確認(rèn)是否已經(jīng)打開

  1. mysql> set profiling=1;     
  2. Query OK, 0 rows affected (0.00 sec)  
  3.  
  4. mysql> select @@profiling;  
  5. +-------------+  
  6. | @@profiling |  
  7. +-------------+  
  8. |           1 |  
  9. +-------------+  
  10. 1 row in set (0.01 sec)  

2.數(shù)據(jù)準(zhǔn)備:

2.1全表掃描數(shù)據(jù)

  1. create table person4all(id int not null  auto_increment, name varchar(30) not null, gender varchar(10) not null ,primary key(id));  
  2. insert into person4all(name,gender) values("zhaoming","male");  
  3. insert into person4all(name,gender) values("wenwen","female"); 

2.2根據(jù)主鍵查看數(shù)據(jù)

  1. create table person4pri(id int not null  auto_increment, name varchar(30) not null, gender varchar(10) not null ,primary key(id));  
  2. insert into person4pri(name,gender) values("zhaoming","male");  
  3. insert into person4pri(name,gender) values("wenwen","female"); 

2.3根據(jù)非聚集索引查數(shù)據(jù)

  1. create table person4index(id int not null  auto_increment, name varchar(30) not null, gender varchar(10) not null ,primary key(id) , index(gender));  
  2. insert into person4index(name,gender) values("zhaoming","male");  
  3. insert into person4index(name,gender) values("wenwen","female"); 

2.4根據(jù)覆蓋索引查數(shù)據(jù)

  1. create table person4cindex(id int not null  auto_increment, name varchar(30) not null, gender varchar(10) not null ,primary key(id) , index(name,gender));    
  2. insert into person4cindex(name,gender) values("zhaoming","male");    
  3. insert into person4cindex(name,gender) values("wenwen","female");   

主要從以下幾個(gè)方面分析:查詢消耗的時(shí)間,走的執(zhí)行計(jì)劃等方面。

3.開工測試:

第一步:全表掃描

  1. mysql> select * from person4all ;  
  2. +----+----------+--------+  
  3. | id | name     | gender |  
  4. +----+----------+--------+  
  5. |  1 | zhaoming | male   |  
  6. |  2 | wenwen   | female |  
  7. +----+----------+--------+  
  8. 2 rows in set (0.00 sec)  

查看其執(zhí)行計(jì)劃:

  1. mysql> explain select * from person4all;  
  2. +----+-------------+------------+------+---------------+------+---------+------+------+-------+  
  3. | id | select_type | table      | type | possible_keys | key  | key_len | ref  | rows | Extra |  
  4. +----+-------------+------------+------+---------------+------+---------+------+------+-------+  
  5. |  1 | SIMPLE      | person4all | ALL  | NULL          | NULL | NULL    | NULL |    2 |       |  
  6. +----+-------------+------------+------+---------------+------+---------+------+------+-------+  
  7. 1 row in set (0.01 sec)  

我們可以很清晰的看到走的是全表掃描,而沒有走索引!

 

查詢消耗的時(shí)間:

  1. mysql> show profiles;  
  2. +----------+------------+-----------------------------------------------------------------------------------------------------------------------------------+  
  3. | Query_ID | Duration   | Query                                                                                                                             |  
  4. |       54 | 0.00177300 | select * from person4all                                                                                                          |  
  5. |       55 | 0.00069200 | explain select * from person4all                                                                                                  |  
  6. +----------+------------+-----------------------------------------------------------------------------------------------------------------------------------+ 

全表掃描總共話了0.0017730秒

 

各個(gè)階段消耗的時(shí)間是:

  1. mysql> show profile for query 54;  
  2. +--------------------------------+----------+  
  3. | Status                         | Duration |  
  4. +--------------------------------+----------+  
  5. | starting                       | 0.000065 |  
  6. | checking query cache for query | 0.000073 |  
  7. | Opening tables                 | 0.000037 |  
  8. | System lock                    | 0.000024 |  
  9. | Table lock                     | 0.000053 |  
  10. | init                           | 0.000044 |  
  11. | optimizing                     | 0.000022 |  
  12. | statistics                     | 0.000032 |  
  13. | preparing                      | 0.000030 |  
  14. | executing                      | 0.000020 |  
  15. | Sending data                   | 0.001074 |  
  16. | end                            | 0.000091 |  
  17. | query end                      | 0.000020 |  
  18. | freeing items                  | 0.000103 |  
  19. | storing result in query cache  | 0.000046 |  
  20. | logging slow query             | 0.000019 |  
  21. | cleaning up                    | 0.000020 |  
  22. +--------------------------------+----------+  
  23. 17 rows in set (0.00 sec)  

第一次不走緩存的話,需要檢查是否存在緩存中,打開表,初始化等操作,最大的開銷在于返回?cái)?shù)據(jù)。

 

第二步:根據(jù)主鍵查詢數(shù)據(jù)。

  1. mysql> select name ,gender from person4pri where id in (1,2);  
  2. +----------+--------+  
  3. | name     | gender |  
  4. +----------+--------+  
  5. | zhaoming | male   |  
  6. | wenwen   | female |  
  7. +----------+--------+  
  8. 2 rows in set (0.01 sec) 

查看其執(zhí)行計(jì)劃:

  1. mysql> explain select name ,gender from person4pri where id in (1,2);  
  2. +----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+  
  3. | id | select_type | table      | type  | possible_keys | key     | key_len | ref  | rows | Extra       |  
  4. +----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+  
  5. |  1 | SIMPLE      | person4pri | range | PRIMARY       | PRIMARY | 4       | NULL |    2 | Using where |  
  6. +----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+  
  7. 1 row in set (0.00 sec) 

從執(zhí)行計(jì)劃中我們可以看出,走的是范圍索引。

 

再看其執(zhí)行消耗的時(shí)間:

  1. mysql> show profiles;  
  2. +----------+------------+-----------------------------------------------------------------------------------------------------------------------------------+  
  3. | Query_ID | Duration   | Query                                                                                                                             |  
  4. +----------+------------+-----------------------------------------------------------------------------------------------------------------------------------+  
  5. |       63 | 0.00135700 | select name ,gender from person4pri where id in (1,2)                                                                             |  
  6. |       64 | 0.00079200 | explain select name ,gender from person4pri where id in (1,2)                                                                     |  
  7. +----------+------------+-----------------------------------------------------------------------------------------------------------------------------------+  
  8. 15 rows in set (0.01 sec) 

這次查詢消耗時(shí)間為0.00079200。

 

查看各個(gè)階段消耗的時(shí)間:

  1. mysql> show profile for query 63;  
  2. +--------------------------------+----------+  
  3. | Status                         | Duration |  
  4. +--------------------------------+----------+  
  5. | starting                       | 0.000067 |  
  6. | checking query cache for query | 0.000146 |  
  7. | Opening tables                 | 0.000342 |  
  8. | System lock                    | 0.000027 |  
  9. | Table lock                     | 0.000115 |  
  10. | init                           | 0.000056 |  
  11. | optimizing                     | 0.000032 |  
  12. | statistics                     | 0.000069 |  
  13. | preparing                      | 0.000039 |  
  14. | executing                      | 0.000022 |  
  15. | Sending data                   | 0.000100 |  
  16. | end                            | 0.000075 |  
  17. | query end                      | 0.000022 |  
  18. | freeing items                  | 0.000158 |  
  19. | storing result in query cache  | 0.000045 |  
  20. | logging slow query             | 0.000019 |  
  21. | cleaning up                    | 0.000023 |  
  22. +--------------------------------+----------+  
  23. 17 rows in set (0.00 sec) 

看出最大的消耗也是在Sending data,第一次也是需要一些初始化操作。

 

第三步:根據(jù)非聚集索引查詢

  1. mysql> select name ,gender from person4index where gender in ("male","female");  
  2. +----------+--------+  
  3. | name     | gender |  
  4. +----------+--------+  
  5. | wenwen   | female |  
  6. | zhaoming | male   |  
  7. +----------+--------+  
  8. 2 rows in set (0.00 sec) 

查看器執(zhí)行計(jì)劃:

  1. mysql> explain select name ,gender from person4index where gender in ("male","female");  
  2. +----+-------------+--------------+-------+---------------+--------+---------+------+------+-------------+  
  3. | id | select_type | table        | type  | possible_keys | key    | key_len | ref  | rows | Extra       |  
  4. +----+-------------+--------------+-------+---------------+--------+---------+------+------+-------------+  
  5. |  1 | SIMPLE      | person4index | range | gender        | gender | 12      | NULL |    2 | Using where |  
  6. +----+-------------+--------------+-------+---------------+--------+---------+------+------+-------------+  
  7. 1 row in set (0.00 sec)  

可以看出,走的也是范圍索引。同主鍵查詢,那么就看其消耗時(shí)間了

  1. mysql> show profiles;  
  2. +----------+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------+  
  3. | Query_ID | Duration   | Query                                                                                                                                               |  
  4. +----------+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------+  
  5. |       68 | 0.00106600 | select name ,gender from person4index where gender in ("male","female")                                                                             |  
  6. |       69 | 0.00092500 | explain select name ,gender from person4index where gender in ("male","female")                                                                     |  
  7. +----------+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------+  
  8. 15 rows in set (0.00 sec) 

這個(gè)非主鍵索引消耗的時(shí)間為:0.00106600,可以看出略大于組件索引消耗的時(shí)間。

 

看其具體消耗的階段:

  1. mysql> show profile for query 68 ;  
  2. +--------------------------------+----------+  
  3. | Status                         | Duration |  
  4. +--------------------------------+----------+  
  5. | starting                       | 0.000059 |  
  6. | checking query cache for query | 0.000111 |  
  7. | Opening tables                 | 0.000085 |  
  8. | System lock                    | 0.000023 |  
  9. | Table lock                     | 0.000067 |  
  10. | init                           | 0.000183 |  
  11. | optimizing                     | 0.000031 |  
  12. | statistics                     | 0.000139 |  
  13. | preparing                      | 0.000035 |  
  14. | executing                      | 0.000020 |  
  15. | Sending data                   | 0.000148 |  
  16. | end                            | 0.000024 |  
  17. | query end                      | 0.000019 |  
  18. | freeing items                  | 0.000043 |  
  19. | storing result in query cache  | 0.000042 |  
  20. | logging slow query             | 0.000017 |  
  21. | cleaning up                    | 0.000020 |  
  22. +--------------------------------+----------+  
  23. 17 rows in set (0.00 sec) 

看幾個(gè)關(guān)鍵詞的點(diǎn);init,statistics,Sending data 這幾個(gè)關(guān)鍵點(diǎn)上的消耗向比較主鍵的查詢要大很多,特別是Sending data。因?yàn)槿羰亲叩姆蔷奂饕?,那么就需要回表進(jìn)行再進(jìn)行一次查詢,多消耗一次IO。

 

第四部:根據(jù)覆蓋索引查詢數(shù)據(jù)

  1. mysql> select gender ,name from person4cindex where gender in ("male","female");  
  2. +--------+----------+  
  3. | gender | name     |  
  4. +--------+----------+  
  5. | female | wenwen   |  
  6. | male   | zhaoming |  
  7. +--------+----------+  
  8. 2 rows in set (0.01 sec) 

這里需要注意的是,我的字段查詢順序變了,是gender,name而不在是前面的name,gender,這樣是為了走覆蓋索引。具體看效果吧

 

還是先看執(zhí)行計(jì)劃:

  1. mysql> explain select gender ,name from person4cindex where gender in ("male","female");  
  2. +----+-------------+---------------+-------+---------------+------+---------+------+------+--------------------------+  
  3. | id | select_type | table         | type  | possible_keys | key  | key_len | ref  | rows | Extra                    |  
  4. +----+-------------+---------------+-------+---------------+------+---------+------+------+--------------------------+  
  5. |  1 | SIMPLE      | person4cindex | index | NULL          | name | 44      | NULL |    2 | Using where; Using index |  
  6. +----+-------------+---------------+-------+---------------+------+---------+------+------+--------------------------+  
  7. 1 row in set (0.00 sec) 

最后欄Extra中表示走的就是覆蓋索引。

 

看消耗的時(shí)間吧:

  1. mysql> show profiles;  
  2. +----------+------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+  
  3. | Query_ID | Duration   | Query                                                                                                                                                            |  
  4. +----------+------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+  
  5. |       83 | 0.00115400 | select gender ,name from person4cindex where gender in ("male","female")                                                                                         |  
  6. |       84 | 0.00074000 | explain select gender ,name from person4cindex where gender in ("male","female")                                                                                 |  
  7. +----------+------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 

我們看到消耗的時(shí)間是0.00115400,看這個(gè)數(shù)字好像挺高的,那么都花在什么地方了呢?

 

看下具體的消耗情況:

  1. mysql> show profile for query 83 ;  
  2. +--------------------------------+----------+  
  3. | Status                         | Duration |  
  4. +--------------------------------+----------+  
  5. | starting                       | 0.000083 |  
  6. | checking query cache for query | 0.000113 |  
  7. | Opening tables                 | 0.000039 |  
  8. | System lock                    | 0.000026 |  
  9. | Table lock                     | 0.000075 |  
  10. | init                           | 0.000128 |  
  11. | optimizing                     | 0.000193 |  
  12. | statistics                     | 0.000056 |  
  13. | preparing                      | 0.000038 |  
  14. | executing                      | 0.000021 |  
  15. | Sending data                   | 0.000121 |  
  16. | end                            | 0.000042 |  
  17. | query end                      | 0.000021 |  
  18. | freeing items                  | 0.000112 |  
  19. | storing result in query cache  | 0.000043 |  
  20. | logging slow query             | 0.000021 |  
  21. | cleaning up                    | 0.000022 |  
  22. +--------------------------------+----------+  
  23. 17 rows in set (0.00 sec)  

很驚奇吧,在初始化和優(yōu)化上消耗了這么多時(shí)間,取數(shù)據(jù)基恩差不多。

 

總  結(jié):

有了上面這些數(shù)據(jù),那么我們整理下吧。未存在緩存下的數(shù)據(jù)。

 

看這個(gè)表,全表掃描最慢,我們可以理解,同時(shí)主鍵查詢比覆蓋所有掃描慢也還能接受,但是為什么主鍵掃描會比非主鍵掃描慢?而且非主鍵查詢需要消耗的1次查詢的io+一次回表的查詢IO,理論上是要比主鍵掃描慢,而出來的數(shù)據(jù)缺不是如此。那么就仔細(xì)看下是個(gè)查詢方式在各個(gè)主要階段消耗的時(shí)間吧。

查詢是否存在緩存,打開表及鎖表這些操作時(shí)間是差不多,我們不會計(jì)入。具體還是看init,optimizing等環(huán)節(jié)消耗的時(shí)間。

1.從這個(gè)表中,我們看到非主鍵索引和覆蓋索引在準(zhǔn)備時(shí)間上需要開銷很多的時(shí)間,預(yù)估這兩種查詢方式都需要進(jìn)行回表操作,所以花在準(zhǔn)備上更多時(shí)間。

2.第二項(xiàng)optimizing上,可以清晰知道,覆蓋索引話在優(yōu)化上大量的時(shí)間,這樣在二級索引上就無需回表。

3. Sendingdata,全表掃描慢就慢在這一項(xiàng)上,因?yàn)槭羌虞d所有的數(shù)據(jù)頁,所以花費(fèi)在這塊上時(shí)間較大,其他三者都差不多。

4. 非主鍵查詢話在freeingitems上時(shí)間最少,那么可以看出它在讀取數(shù)據(jù)塊的時(shí)候最少。

5.相比較主鍵查詢和非主鍵查詢,非主鍵查詢在Init,statistics都遠(yuǎn)高于主鍵查詢,只是在freeingitems開銷時(shí)間比主鍵查詢少。因?yàn)檫@里測試數(shù)據(jù)比較少,但是我們可以預(yù)見在大數(shù)據(jù)量的查詢上,不走緩存的話,那么主鍵查詢的速度是要快于非主鍵查詢的,本次數(shù)據(jù)不過是太小體現(xiàn)不出差距而已。

6.在大多數(shù)情況下,全表掃描還是要慢于索引掃描的。

tips:

過程中的輔助命令:

1.清楚緩存

reset query cache ;

flush tables;

 

2.查看表的索引:

show index from tablename;

原文鏈接:http://inter12.iteye.com/blog/1430144

【編輯推薦】

  1. 甲骨文推出MySQL集群7.2
  2. MySQL Workbench 5.2.38發(fā)布
  3. MySQL內(nèi)存表的特性與使用介紹
  4. 利用Java進(jìn)行MySql數(shù)據(jù)庫的導(dǎo)入和導(dǎo)出
  5. MySQL 5.5.21 GA發(fā)布(附下載)
責(zé)任編輯:林師授 來源: inter12的博客
相關(guān)推薦

2020-06-24 07:49:13

Kubernetes場景網(wǎng)絡(luò)

2023-11-05 09:00:00

Linux命令MySQL

2020-11-10 10:08:41

Kubernetes容器開發(fā)

2017-08-09 14:34:12

MysqlJavaPython

2020-12-09 11:21:48

大數(shù)據(jù)數(shù)據(jù)分析

2020-12-09 10:56:15

業(yè)務(wù)分析數(shù)據(jù)分析大數(shù)據(jù)

2017-08-01 23:44:25

數(shù)據(jù)分析數(shù)據(jù)科學(xué)數(shù)據(jù)

2010-04-23 14:47:05

Oracle Data

2020-12-10 16:15:04

物聯(lián)網(wǎng)物聯(lián)網(wǎng)分析計(jì)算類型

2017-09-21 13:04:35

數(shù)據(jù)挖掘分析分析方法數(shù)據(jù)分析師

2017-07-27 14:01:51

大數(shù)據(jù)數(shù)據(jù)分析類型模式

2021-08-12 11:37:23

數(shù)據(jù)分析錯(cuò)誤

2018-01-03 08:52:27

MySQL數(shù)據(jù)庫級別

2021-09-01 10:05:04

機(jī)器學(xué)習(xí)人工智能算法

2024-09-26 14:27:14

2011-11-24 16:34:39

Java

2011-03-16 09:05:53

NATiptables

2012-09-11 09:55:26

編程HTML5編程能力

2017-07-06 15:40:19

DevOps核心能力

2019-10-24 07:42:28

Java引用GC
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號