久久福利_99r_国产日韩在线视频_直接看av的网站_中文欧美日韩_久久一

您的位置:首頁技術(shù)文章
文章詳情頁

詳解 MySQL中count函數(shù)的正確使用方法

瀏覽:28日期:2023-10-09 13:20:47

1. 描述

在MySQL中,當(dāng)我們需要獲取某張表中的總行數(shù)時(shí),一般會(huì)選擇使用下面的語句

select count(*) from table;

其實(shí)count函數(shù)中除了*還可以放其他參數(shù),比如常數(shù)、主鍵id、字段,那么它們有什么區(qū)別?各自效率如何?我們應(yīng)該使用哪種方式來獲取表的行數(shù)呢?

當(dāng)搞清楚count函數(shù)的運(yùn)行原理后,相信上面幾個(gè)問題的答案就會(huì)了然于胸。

2. 表結(jié)構(gòu)

為了解決上述的問題,我創(chuàng)建了一張 user 表,它有兩個(gè)字段:主鍵id和name,后者可以為null,建表語句如下。

CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT ’主鍵’, `name` varchar(255) DEFAULT NULL COMMENT ’姓名’, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;

在該表中共有6000000條數(shù)據(jù),前1000000條數(shù)據(jù)行的name字段為空,其余數(shù)據(jù)行name=id,使用存儲(chǔ)過程造測(cè)試數(shù)據(jù)的代碼如下

-- 使用存儲(chǔ)過程造測(cè)試數(shù)據(jù)delimiter;;create procedure idata()begin declare i int; set i=1; while(i<=6000000)do insert into user values(i, i); set i=i+1; end while;end;;delimiter;call idata();-- 將前1000000條數(shù)據(jù)的name字段置為nullupdate user set name=null where id<1000000;

3. 執(zhí)行 SQL 語句及結(jié)果

為了區(qū)分count函數(shù)不同參數(shù)的區(qū)別,主要從執(zhí)行時(shí)間和掃描行數(shù)這兩方面來描述SQL的執(zhí)行效率,同時(shí)還會(huì)從返回結(jié)果來描述`count函數(shù)的特性。

*符號(hào) —— select count(*) from user; 常數(shù)—— select count(1) from user; 非空字段—— select count(id) from user; 可為空的字段—— select count(name) from user;

3.1 *符號(hào)

mysql> select count(*) from user;+----------+| count(*) |+----------+| 6000000 |+----------+1 row in set (0.76 sec)

遍歷全表,不取值(優(yōu)化后,必定不是null,不取值),累加計(jì)數(shù),最終返回結(jié)果。

3.2 常數(shù)

mysql> select count(1) from user;+----------+| count(1) |+----------+| 6000000 |+----------+1 row in set (0.76 sec)

遍歷全表,一行行取數(shù)據(jù),將每一行賦值為1,判斷到該字段不可為空,累加計(jì)數(shù),最終返回結(jié)果。

3.3 非空字段

mysql> select count(id) from user;+-----------+| count(id) |+-----------+| 6000000 |+-----------+1 row in set (0.85 sec)

遍歷全表,一行行取數(shù)據(jù)(會(huì)選擇最小的索引樹來遍歷,所以比相同情況下的count字段效率更高),取每行的主鍵id,判斷到該字段不可為空,累加計(jì)數(shù),最終返回結(jié)果。

3.4 可為空的字段

mysql> select count(name) from user;+-------------+| count(name) |+-------------+| 5900001 |+-------------+1 row in set (0.93 sec) 若字段定義不為空:遍歷全表,一行行取數(shù)據(jù),取每行的該字段,判斷到該字段不可為空,累加計(jì)數(shù),最終返回結(jié)果。 若字段定義可為空:遍歷全表,一行行取數(shù)據(jù),取每行的該字段,判斷到該字段可能是null,然后再判斷該字段的值是否為null,不為null才累加計(jì)數(shù),最終返回結(jié)果。 若該字段沒有索引,將遍歷主鍵索引樹。

4. 執(zhí)行結(jié)果分析

4.1 結(jié)果集

首先從結(jié)果集的角度來看,前三條 SQL 語句的目的是一樣的——返回的是所有行數(shù),而 count 函數(shù)的參數(shù)是普通字段且字段默認(rèn)為 null 的時(shí)候,它返回的是該字段不為 null 的行數(shù)。

4.2 執(zhí)行時(shí)間

從執(zhí)行時(shí)間上來看的話,效率大致是count(可為空的字段) < count(非空字段) < count(常數(shù)) < count(*)。

5. 總結(jié)

count是一個(gè)聚合函數(shù),對(duì)于返回的結(jié)果集,一行行地判斷,如果count函數(shù)的參數(shù)不是NULL,累計(jì)值就加1,否則不加。最后返回累計(jì)值。

count(*)速度最快的原因是它不會(huì)在計(jì)數(shù)的時(shí)候去取每行數(shù)據(jù)值 count(1)比count(*)稍慢的原因是它會(huì)取每個(gè)數(shù)據(jù)行并賦值為1 count(非空字段)比count(1)稍慢的原因是它會(huì)從每個(gè)數(shù)據(jù)行中取出主鍵 id count(可為空的字段)最慢的原因是它可能需要判斷每個(gè)數(shù)據(jù)行中的改字段是否為 null

所以,最好還是用count(*)。

以上就是詳解 MySQL中count函數(shù)的正確使用方法的詳細(xì)內(nèi)容,更多關(guān)于MySQL count函數(shù)的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: MySQL 數(shù)據(jù)庫
相關(guān)文章:
主站蜘蛛池模板: 亚洲福利影院 | 日本一区高清 | 成人av片在线观看 | 国产成人精品一区二区三区四区 | 日本黄色影片在线观看 | 欧美xxxⅹ性欧美大片 | 日韩成人免费在线 | 久久99精品久久久久久久青青日本 | 久久国产精品一区二区三区 | 国产另类一区 | 欧美久久影视 | 成人一区二区在线 | 伊人久久艹 | 91成人免费在线视频 | 成人久久久久久久久 | 亚洲成人毛片 | 精品久久久久久久久久久久久久久久久久 | 久久九九国产精品 | 一区二区免费在线视频 | 欧美激情一区二区三级高清视频 | 欧美成人一级 | 亚洲高清免费视频 | 久久久精品一区 | 国产精品久久久久久久久污网站 | 国产精品久久久久久久久福交 | 成人v片| 色性视频| 一区二区三区在线 | 在线日韩中文字幕 | 日韩在线播放一区 | 天天干天天摸 | 亚洲成人精品在线 | 四虎av| 亚洲狠狠爱一区二区三区 | 日韩免费在线 | 天天干天天操天天爽 | 国产视频欧美 | 精品国产乱码久久久久久密桃99 | 日韩久久综合 | 午夜在线电影 | 久久一区国产 |