婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > MySQL中無過濾條件的count詳解

MySQL中無過濾條件的count詳解

熱門標簽:淄博400電話申請 電話機器人市場趨勢 電銷機器人 行業 南昌高頻外呼系統哪家公司做的好 百度地圖標注后不顯示 電銷機器人各個細節介紹 溫州瑞安400電話怎么申請 俄國地圖標注app 昆明電信400電話辦理

count(*)

實現

1、MyISAM:將表的總行數存放在磁盤上,針對無過濾條件的查詢可以直接返回

如果有過濾條件的count(*),MyISAM也不能很快返回

2、InnoDB:從存儲引擎一行行地讀出數據,然后累加計數

由于MVCC,在同一時刻,InnoDB應該返回多少行是不確定

樣例

假設表t有10000條記錄

session A session B session C
BEGIN;
SELECT COUNT(*) FROM t;(返回10000)
INSERT INTO t;(插入一行)
BEGIN;
INSERT INTO t(插入一行);
SELECT COUNT(*) FROM t;(返回10000) SELECT COUNT(*) FROM t;(返回10002) SELECT COUNT(*) FROM T;(返回10001)

最后時刻三個會話同時查詢t的總行數,拿到的結果卻是不同的

InnoDB默認事務隔離級別是RR,通過MVCC實現

  • 每個事務都需要判斷每一行記錄是否對自己可見

優化

1、InnoDB是索引組織表

  • 聚簇索引樹:葉子節點是數據
  • 二級索引樹:葉子節點是主鍵值

2、二級索引樹占用的空間比聚簇索引樹小很多

3、優化器會在保證邏輯正確的前提下,遍歷最小的索引樹,盡量減少掃描的數據量

  • 針對無過濾條件的count操作,無論遍歷哪一顆索引樹,效果都是一樣的
  • 優化器會為count(*)選擇最優的索引樹

show table status

mysql> SHOW TABLE STATUS\G;
*************************** 1. row ***************************
 Name: t
 Engine: InnoDB
 Version: 10
 Row_format: Dynamic
 Rows: 100256
 Avg_row_length: 47
 Data_length: 4734976
Max_data_length: 0
 Index_length: 5275648
 Data_free: 0
 Auto_increment: NULL
 Create_time: 2019-02-01 17:49:07
 Update_time: NULL
 Check_time: NULL
 Collation: utf8_general_ci
 Checksum: NULL
 Create_options:
 Comment:

SHOW TABLE STATUS同樣通過采樣來估算(非常不精確),誤差能到40%~50%

維護計數

緩存

方案

  • 用Redis來保存表的總行數(無過濾條件)
  • 這個表每插入一行,Redis計數+1,每刪除一行,Redis計數-1

缺點

丟失更新

1、Redis可能會丟失更新

2、解決方案:Redis異常重啟后,到數據庫執行一次count(*)

  • 異常重啟并不常見,這時全表掃描的成本是可以接受的

邏輯不精確 – 致命

1、場景:顯示操作記錄的總數和最近操作的100條記錄

2、Redis和MySQL是兩個不同的存儲系統,不支持分布式事務,因此無法拿到精確的一致性視圖

時序A

session B在T3時刻,查到的100行結果里面有最新插入的記錄,但Redis還沒有+1,邏輯不一致

時刻 session A session B
T1
T2 插入一行數據R;
T3 讀取Redis計數;
查詢最近100條記錄;
T4 Redis計數+1;

時序B

session B在T3時刻,查到的100行結果里面沒有最新插入的記錄,但Redis已經+1,邏輯不一致

時刻 session A session B
T1
T2 Redis計數+1;
T3 讀取Redis計數;
查詢最近100條記錄;
T4 插入一行數據R;

數據庫

  • 把計數值放到數據庫單獨的一張計數表C中
  • 利用InnoDB的crash-safe的特性,解決了崩潰丟失的問題
  • 利用InnoDB的支持事務的特性,解決了一致性視圖的問題
  • session B在T3時刻,session A的事務還未提交,表C的計數值+1對自己不可見,邏輯一致

時刻 session A session B
T1
T2 BEGIN;
表C中的計數值+1;
T3 BEGIN;
讀表C計數值;
查詢最新100條記錄;
COMMIT;
T4 插入一行數據R;
COMMIT;

count的性能

語義

1、count()是一個聚合函數,對于返回的結果集,一行一行地進行判斷

如果count函數的參數值不是NULL,累計值+1,否則不加,最后返回累計值

2、count(字段F)

  • 字段F有可能為NULL
  • 表示返回滿足條件的結果集里字段F不為NULL的總數

3、count(主鍵ID)、count(1)、count(*)

  • 不可能為NULL
  • 表示返回滿足條件的結果集的總數

4、Server層要什么字段,InnoDB引擎就返回什么字段

  • count(*)例外,不返回整行,只返回空行

性能對比

count(字段F)

1、如果字段F定義為不允許為NULL,一行行地從記錄里讀出這個字段,判斷通過后按行累加

  • 通過表結構判斷該字段是不可能為NULL

2、如果字段F定義為允許NULL,一行行地從記錄里讀出這個字段,判斷通過后按行累加

  • 通過表結構判斷該字段是有可能為NULL
  • 判斷該字段值是否實際為NULL

3、如果字段F上沒有二級索引,只能遍歷整張表(聚簇索引)

4、由于InnoDB必須返回字段F,因此優化器能做出的優化決策將減少

  • 例如不能選擇最優的索引來遍歷

count(主鍵ID)

  • InnoDB會遍歷整張表(聚簇索引),把每一行的id值取出來,返回給Server層
  • Server層拿到id后,判斷為不可能為NULL,然后按行累加
  • 優化器可能會選擇最優的索引來遍歷

count(1)

  1. InnoDB引擎會遍歷整張表(聚簇索引),但不取值
  2. Server層對于返回的每一行,放一個數字1進去,判斷是不可能為NULL,按行累加
  3. count(1)比count(主鍵ID)快,因為count(主鍵ID)會涉及到兩部分操作
  • 解析數據行
  • 拷貝字段值

count(*)

  1. count(*)不會把所有值都取出來,而是專門做了優化,不取值,因為『*』肯定不為NULL,按行累加
  2. 不取值:InnoDB返回一個空行,告訴Server層不是NULL,可以計數

效率排序

  1. count(字段F) count(主鍵ID) count(1) ≈ count(*)
  2. 盡量使用count(*)

樣例

mysql> SHOW CREATE TABLE prop_action_batch_reward\G;
*************************** 1. row ***************************
 Table: prop_action_batch_reward
Create Table: CREATE TABLE `prop_action_batch_reward` (
 `id` bigint(20) NOT NULL,
 `source` int(11) DEFAULT NULL,
 `serial_id` bigint(20) NOT NULL,
 `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
 `user_ids` mediumtext,
 `serial_index` tinyint(4) DEFAULT '0',
 PRIMARY KEY (`id`),
 UNIQUE KEY `uniq_serial_id_source_index` (`serial_id`,`source`,`serial_index`),
 KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

count(字段F)

無索引

user_ids上無索引,而InnoDB又必須返回user_ids字段,只能遍歷聚簇索引

mysql> EXPLAIN SELECT COUNT(user_ids) FROM prop_action_batch_reward;
+----+-------------+--------------------------+------+---------------+------+---------+------+----------+-------+
| id | select_type | table   | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------------------------+------+---------------+------+---------+------+----------+-------+
| 1 | SIMPLE | prop_action_batch_reward | ALL | NULL  | NULL | NULL | NULL | 16435876 | NULL |
+----+-------------+--------------------------+------+---------------+------+---------+------+----------+-------+

mysql> SELECT COUNT(user_ids) FROM prop_action_batch_reward;
+-----------------+
| count(user_ids) |
+-----------------+
| 17689788 |
+-----------------+
1 row in set (10.93 sec)

有索引

1、serial_id上有索引,可以遍歷uniq_serial_id_source_index

2、但由于InnoDB必須返回serial_id字段,因此不會遍歷邏輯結果等價的更優選擇idx_create_time

  • 如果選擇idx_create_time,并且返回serial_id字段,這意味著必須回表
mysql> EXPLAIN SELECT COUNT(serial_id) FROM prop_action_batch_reward;
+----+-------------+--------------------------+-------+---------------+-----------------------------+---------+------+----------+-------------+
| id | select_type | table   | type | possible_keys | key    | key_len | ref | rows | Extra |
+----+-------------+--------------------------+-------+---------------+-----------------------------+---------+------+----------+-------------+
| 1 | SIMPLE | prop_action_batch_reward | index | NULL  | uniq_serial_id_source_index | 15 | NULL | 16434890 | Using index |
+----+-------------+--------------------------+-------+---------------+-----------------------------+---------+------+----------+-------------+

mysql> SELECT COUNT(serial_id) FROM prop_action_batch_reward;
+------------------+
| count(serial_id) |
+------------------+
|  17705069 |
+------------------+
1 row in set (5.04 sec)

count(主鍵ID)

優化器選擇了最優的索引idx_create_time來遍歷,而非聚簇索引

mysql> EXPLAIN SELECT COUNT(id) FROM prop_action_batch_reward;
+----+-------------+--------------------------+-------+---------------+-----------------+---------+------+----------+-------------+
| id | select_type | table   | type | possible_keys | key  | key_len | ref | rows | Extra |
+----+-------------+--------------------------+-------+---------------+-----------------+---------+------+----------+-------------+
| 1 | SIMPLE | prop_action_batch_reward | index | NULL  | idx_create_time | 5 | NULL | 16436797 | Using index |
+----+-------------+--------------------------+-------+---------------+-----------------+---------+------+----------+-------------+

mysql> SELECT COUNT(id) FROM prop_action_batch_reward;
+-----------+
| count(id) |
+-----------+
| 17705383 |
+-----------+
1 row in set (4.54 sec)

count(1)

mysql> EXPLAIN SELECT COUNT(1) FROM prop_action_batch_reward;
+----+-------------+--------------------------+-------+---------------+-----------------+---------+------+----------+-------------+
| id | select_type | table   | type | possible_keys | key  | key_len | ref | rows | Extra |
+----+-------------+--------------------------+-------+---------------+-----------------+---------+------+----------+-------------+
| 1 | SIMPLE | prop_action_batch_reward | index | NULL  | idx_create_time | 5 | NULL | 16437220 | Using index |
+----+-------------+--------------------------+-------+---------------+-----------------+---------+------+----------+-------------+

mysql> SELECT COUNT(1) FROM prop_action_batch_reward;
+----------+
| count(1) |
+----------+
| 17705808 |
+----------+
1 row in set (4.12 sec)

count(*)

mysql> EXPLAIN SELECT COUNT(*) FROM prop_action_batch_reward;
+----+-------------+--------------------------+-------+---------------+-----------------+---------+------+----------+-------------+
| id | select_type | table   | type | possible_keys | key  | key_len | ref | rows | Extra |
+----+-------------+--------------------------+-------+---------------+-----------------+---------+------+----------+-------------+
| 1 | SIMPLE | prop_action_batch_reward | index | NULL  | idx_create_time | 5 | NULL | 16437518 | Using index |
+----+-------------+--------------------------+-------+---------------+-----------------+---------+------+----------+-------------+

mysql> SELECT COUNT(*) FROM prop_action_batch_reward;
+----------+
| count(*) |
+----------+
| 17706074 |
+----------+
1 row in set (4.06 sec)

參考資料

《MySQL實戰45講》

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

您可能感興趣的文章:
  • MySQL 大表的count()優化實現
  • MySQL中聚合函數count的使用和性能優化技巧
  • 關于mysql中innodb的count優化問題分享
  • 聊聊MySQL的COUNT(*)的性能
  • 詳解 MySQL中count函數的正確使用方法
  • 淺談MySQL 統計行數的 count
  • mysql count提高方法總結
  • MySQL中count(*)、count(1)和count(col)的區別匯總
  • mySQL count多個表的數據實例詳解
  • MySQL COUNT函數的使用與優化

標簽:拉薩 嘉峪關 吐魯番 葫蘆島 甘南 安徽 海口 洛陽

巨人網絡通訊聲明:本文標題《MySQL中無過濾條件的count詳解》,本文關鍵詞  MySQL,中無,過濾,條件,的,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《MySQL中無過濾條件的count詳解》相關的同類信息!
  • 本頁收集關于MySQL中無過濾條件的count詳解的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    国产午夜亚洲精品理论片色戒| 婷婷国产v国产偷v亚洲高清| 欧美猛男超大videosgay| 欧美激情一区二区三区四区 | 一区二区三区中文字幕电影| 亚洲色图另类专区| 久久久久久夜精品精品免费| 91精品国产综合久久福利软件| 成人午夜av电影| 蜜臀av一级做a爰片久久| 亚洲欧美在线另类| 国产精品成人一区二区艾草 | 日韩—二三区免费观看av| 欧美一卡二卡在线观看| 这里只有精品视频在线观看| 欧美一级高清大全免费观看| 美腿丝袜一区二区三区| 亚洲成人精品一区二区| 欧美国产日韩一二三区| 国产精品成人免费| 亚洲女与黑人做爰| 亚洲国产日韩一级| 精品亚洲免费视频| 色老综合老女人久久久| 成人激情综合网站| 亚洲一区二区五区| 高清国产午夜精品久久久久久| 色一情一乱一乱一91av| 欧美日本一区二区三区| 国产精品久久免费看| 福利一区福利二区| 欧美日韩成人在线| 欧美国产成人精品| 美女脱光内衣内裤视频久久影院| 成人性视频网站| 中文字幕av一区 二区| 一区二区三区小说| 国产盗摄女厕一区二区三区| 国产精品影音先锋| 在线观看视频一区二区| 亚洲免费视频成人| www.av精品| 国产欧美精品一区| 久久精品国内一区二区三区| 色一区在线观看| 亚洲免费电影在线| 一本色道久久综合狠狠躁的推荐 | 日韩视频在线观看一区二区| 亚洲一区二区三区自拍| av中文一区二区三区| 国产精品天干天干在线综合| 激情综合网天天干| 国产精品妹子av| 91视频一区二区三区| 一区二区三区在线免费播放| 成人va在线观看| 亚洲免费观看在线视频| 色视频成人在线观看免| ㊣最新国产の精品bt伙计久久| 成人性色生活片| 18涩涩午夜精品.www| 欧美日韩一级大片网址| 亚洲成人高清在线| 日韩一区二区三区高清免费看看| 中文字幕欧美一| 在线不卡一区二区| 国产福利一区二区三区在线视频| 制服.丝袜.亚洲.中文.综合 | 日韩国产一二三区| 中文字幕精品三区| 成人免费观看av| 亚洲成av人片| 国产欧美日韩另类一区| www.亚洲在线| 紧缚奴在线一区二区三区| 亚洲精品欧美激情| 欧美精品一区二区三区视频| 91国产免费看| 极品少妇xxxx精品少妇偷拍| 亚洲一区在线播放| 99精品欧美一区| 日韩一区二区中文字幕| 国产成人精品aa毛片| 最新欧美精品一区二区三区| 日韩视频免费观看高清完整版在线观看| 激情小说欧美图片| 五月婷婷久久丁香| 亚洲欧美日韩电影| 国产精品麻豆网站| 精品国产乱码久久久久久图片| 欧美在线999| 99久久99久久精品免费观看 | 日韩精品1区2区3区| 亚洲男人的天堂网| 亚洲欧美日韩国产手机在线| 国产欧美日韩不卡免费| 国产欧美精品一区二区色综合 | 91性感美女视频| 国产真实乱偷精品视频免| 日韩高清不卡在线| 青青草原综合久久大伊人精品| 天堂一区二区在线免费观看| 午夜视频一区在线观看| 手机精品视频在线观看| 蜜桃在线一区二区三区| 美女性感视频久久| 成人一级片在线观看| 91偷拍与自偷拍精品| 欧美日韩久久一区| 精品区一区二区| 国产精品麻豆一区二区| 日韩一区在线免费观看| 精品一区二区三区在线播放| 久久97超碰国产精品超碰| 国产99精品视频| 91黄色免费网站| 欧美女孩性生活视频| 欧美tk—视频vk| 国产精品久久久久久久久久久免费看 | www.亚洲色图.com| 宅男噜噜噜66一区二区66| 欧美极品少妇xxxxⅹ高跟鞋| 亚洲精品菠萝久久久久久久| 黑人精品欧美一区二区蜜桃| 99久久久精品免费观看国产蜜| 欧美日韩极品在线观看一区| 久久精品无码一区二区三区| 亚洲午夜三级在线| 国产99精品国产| 欧美哺乳videos| 日韩高清中文字幕一区| 色天使色偷偷av一区二区| 久久久久久久综合日本| 五月天一区二区三区| 色老汉av一区二区三区| 中文字幕中文乱码欧美一区二区| 久久99精品一区二区三区| 欧美一区二区啪啪| 午夜精品久久久久影视| 91亚洲精华国产精华精华液| 国产精品毛片大码女人| 成人av在线资源网站| 日韩激情av在线| 欧美系列亚洲系列| 亚洲一级不卡视频| 欧美国产欧美综合| 麻豆精品一区二区三区| 2024国产精品| 成人激情免费电影网址| 国产日产精品1区| 盗摄精品av一区二区三区| 日韩一区二区中文字幕| 青青国产91久久久久久 | 国产精品欧美综合在线| 亚洲成av人片一区二区梦乃| 91麻豆精品国产自产在线观看一区| 一区二区三区在线观看动漫| 欧美性猛片xxxx免费看久爱| 亚洲国产视频a| 欧美成人乱码一区二区三区| 亚洲电影激情视频网站| 久久电影国产免费久久电影| 91麻豆文化传媒在线观看| 中国av一区二区三区| 国产99一区视频免费 | 日韩精品最新网址| 免费不卡在线观看| 日韩免费观看2025年上映的电影| 男男视频亚洲欧美| 欧美一级久久久久久久大片| 男人的j进女人的j一区| 欧美乱熟臀69xxxxxx| 日本aⅴ亚洲精品中文乱码| 免费高清成人在线| 91麻豆swag| 亚洲欧美在线另类| 色呦呦一区二区三区| 日本欧美一区二区| 欧美第一区第二区| 东方欧美亚洲色图在线| 亚洲激情第一区| 欧美成人a视频| 精品污污网站免费看| 精品中文av资源站在线观看| 亚洲欧洲国产日本综合| 欧美一区二区三区四区高清| 91在线视频观看| 韩国精品主播一区二区在线观看 | 一本到不卡免费一区二区| 日本亚洲视频在线| 综合欧美亚洲日本| 国产精品不卡在线观看| 国产精品久久久久一区二区三区共| 国产午夜精品一区二区三区四区| 一区二区三区精品视频在线| 午夜精品久久久久久久久久久 | 精品一二三四在线| 免费成人美女在线观看.| 欧美日韩成人综合天天影院| 久久99国产精品免费|