MySQLcount(*)很慢
Server version: 5.7.24-log MySQL Community Server (GPL)
select count(*) from api_runtime_log;
mysql> select count(*) from api_runtime_log;
+----------+
| count(*) |
+----------+
| 5718952 |
+----------+
1 row in set (42.95 sec)
CREATE TABLE `api_runtime_log` (
`BelongXiaQuCode` varchar(50) DEFAULT NULL,
`OperateUserName` varchar(50) DEFAULT NULL,
`OperateDate` datetime DEFAULT NULL,
`Row_ID` int(11) DEFAULT NULL,
`YearFlag` varchar(4) DEFAULT NULL,
`RowGuid` varchar(50) NOT NULL,
......
`apiid` varchar(50) DEFAULT NULL,
`apiname` varchar(50) DEFAULT NULL,
`apiguid` varchar(50) DEFAULT NULL,
PRIMARY KEY (`RowGuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
通過執行計劃,我們看下是否可以找到什麼問題點。
mysql> explain select count(*) from api_runtime_log \G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: api_runtime_log
partitions: NULL
type: index
possible_keys: NULL
key: PRIMARY
key_len: 152
ref: NULL
rows: 5718952
filtered: 100.00
Extra: Using index
簡單介紹下原理:
-
聚簇索引:每一個 InnoDB 儲存引擎下的表都有一個特殊的索引用來儲存每一行的資料,稱為聚簇索引(通常都為 主鍵),聚簇索引實際儲存了 B-Tree 索引和行資料,所以大小實際上約等於為表資料量 -
二級索引:除了聚集索引,表上其他的索引都是二級索引,索引中僅僅儲存了對應索引列及主鍵列
那麼如何解決呢?
答案就是:建二級索引。
-
走聚集索引:從第一頁翻到最後一頁,知道總頁數;
-
走二級索引:通過目錄直接知道總頁數。
建立二級索引後,再次執行 SQL 及檢視執行計劃。
mysql> create index idx_rowguid on api_runtime_log(rowguid);
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> select count(*) from api_runtime_log;
+----------+
| count(*) |
+----------+
| 5718952 |
+----------+
1 row in set (0.89 sec)
mysql> explain select count(*) from api_runtime_log \G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: api_runtime_log
partitions: NULL
type: index
possible_keys: NULL
key: idx_rowguid
key_len: 152
ref: NULL
rows: 5718952
filtered: 100.00
Extra: Using index
1 row in set, 1 warning (0.00 sec)
測試過程如下:
測試結果如下:
查詢當前記憶體緩衝區狀態,結果為空證明不快取測試表資料。
mysql> select * from sys.innodb_buffer_stats_by_table where object_schema = 'test';
Empty set (1.92 sec)
mysql> select count(*) from test.sbtest1;
+----------+
| count(*) |
+----------+
| 5188434 |
+----------+
1 row in set (5.52 sec)
再次檢視記憶體緩衝區,發現快取了 sbtest1 表上 1G 多的資料,基本等於整個表資料量。
mysql> select * from sys.innodb_buffer_stats_by_table where object_schema = 'test' \G;
*************************** 1. row ***************************
object_schema: test
object_name: sbtest1
allocated: 1.08 GiB
data: 1.01 GiB
pages: 71081
pages_hashed: 0
pages_old: 28119
rows_cached: 5189798
最後我們再來看下執行計劃,確實走的是主鍵索引,放在最後執行是為了避免影響緩衝區。
mysql> explain select count(*) from test.sbtest1 \G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: sbtest1
partitions: NULL
type: index
possible_keys: NULL
key: PRIMARY
key_len: 4
ref: NULL
rows: 5117616
filtered: 100.00
Extra: Using index
2. 二級索引
建立二級索引 idx_id,檢視 sbtest1 表上主鍵索引與二級索引的資料量。
mysql> create index idx_id on sbtest1(id);
Query OK, 0 rows affected (12.97 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> SELECT sum(stat_value) pages ,index_name ,
(round((sum(stat_value) * @@innodb_page_size)/1024/1024)) as MB
FROM mysql.innodb_index_stats
WHERE table_name = 'sbtest1'
AND database_name = 'test'
AND stat_description = 'Number of pages in the index'
GROUP BY index_name;
+-------+------------+------+
| pages | index_name | MB |
+-------+------------+------+
| 72000 | PRIMARY | 1125 |
| 3492 | idx_id | 55 |
+-------+------------+------+
重啟 MySQL,再次檢視緩衝區同樣為空,證明沒有快取測試表上的資料。
mysql> select * from sys.innodb_buffer_stats_by_table where object_schema = 'test';
Empty set (1.49 sec)
mysql> select count(*) from test.sbtest1;
+----------+
| count(*) |
+----------+
| 5188434 |
+----------+
1 row in set (2.92 sec)
再次檢視記憶體緩衝區,發現僅僅快取了 sbtest1 表上的 50M 資料,約等於二級索引的資料量。
mysql> select * from sys.innodb_buffer_stats_by_table where object_schema = 'test' \G;
*************************** 1. row ***************************
object_schema: test
object_name: sbtest1
allocated: 49.48 MiB
data: 46.41 MiB
pages: 3167
pages_hashed: 0
pages_old: 1575
rows_cached: 2599872
最後確認下執行計劃,確實走的是二級索引。
mysql> explain select count(*) from test.sbtest1 \G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: sbtest1
partitions: NULL
type: index
possible_keys: NULL
key: idx_id
key_len: 4
ref: NULL
rows: 5117616
filtered: 100.00
Extra: Using index
另:專案上由於磁碟效能層次不齊,所以當遇上這種情況時,效能較差的磁碟更會放大這個問題;一張超級大表,統計行數時如果走了主鍵索引,後果可想而知~
About Me
........................................................................................................................ ● 本文作者:小麥苗,部分內容整理自網路,若有侵權請聯絡小麥苗刪除 ● 本文在個人微 信公眾號( DB寶)上有同步更新 ● QQ群號: 230161599 、618766405,微信群私聊 ● 個人QQ號(646634621),微 訊號(db_bao),註明新增緣由 ● 於 2020年11月完成 ● 最新修改時間:2020年11月 ● 版權所有,歡迎分享本文,轉載請保留出處 ........................................................................................................................ ● 小麥苗的微店: https://weidian.com/s/793741433?wfr=c&ifr=shopdetail ● 小麥苗出版的資料庫類叢書: http://blog.itpub.net/26736162/viewspace-2142121/ ● 小麥苗OCP、OCM、高可用、DBA學習班: http://blog.itpub.net/26736162/viewspace-2148098/ ● 資料庫筆試面試題庫及解答: http://blog.itpub.net/26736162/viewspace-2134706/ ........................................................................................................................ 請掃描下面的二維碼來關注小麥苗的微 信公眾號( DB寶)及QQ群(230161599、618766405)、新增小麥苗微 信(db_bao), 學習最實用的資料庫技術。
........................................................................................................................ |
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26736162/viewspace-2733787/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 在Linux中,假如公司網站訪問速度變的很慢很慢,該如何處理?Linux網站
- 為什麼說DOM操作很慢
- [20230204]執行很慢的分析.txt
- Linux——ssh登入很慢解決方法Linux
- 在Java中使用Optional效能很慢 - pkolaczkJava
- 解決pod install update很慢的問題
- ts程式碼提示很慢問題解決
- SSH登入很慢問題的解決
- 為什麼網站訪問速度很慢網站
- win10啟動blue stacks很慢怎麼辦_win10啟動blue stacks很慢的修復方法Win10
- win10開啟系統盤很慢怎麼辦 win10進入系統盤很慢解決方法Win10
- Playground中擼Swift程式碼很慢怎麼辦?Swift
- “車馬很慢”的中國郵政變快了
- RocketMQ 很慢?引出了一個未解之謎MQ
- 解決訪問Github與clone很慢的問題Github
- 解決訪問 GitHub 與 clone 很慢的問題Github
- blender拖動視角到一定程度很慢
- weblogic10.3.6軟體打補丁很慢問題Web
- deepin系統安裝成功後網速很慢怎麼辦?deepin系統安裝成功後網速很慢的解決辦法
- 為什麼IIS網頁每天首次開啟速度很慢?網頁
- ubuntu下程式kidle_inject致使編譯軟體很慢Ubuntu編譯
- xshell 連線本地虛擬機器很慢解決方法虛擬機
- 訪問Github速度很慢以及解決方法(系統通用)Github
- safari瀏覽網頁開啟速度很慢如何解決網頁
- win10區域網內傳檔案很慢怎麼辦 win10區域網內檔案傳輸很慢如何處理Win10
- 資料量很大,分頁查詢很慢,該怎麼優化?優化
- 解決hive資料庫 插入資料很慢的問題Hive資料庫
- UnrealEngine Setup即使掛了代理也很慢的解決辦法Unreal
- 為什麼使用海外HTTP代理後,網速變得很慢?HTTP
- 香港雲伺服器網站開啟很慢該怎麼辦?伺服器網站
- Python 潮流週刊#64:Python 的函式呼叫還很慢麼?(摘要)Python函式
- 如果你訪問一個網站很慢,怎麼排查和解決?網站
- android開發flutter專案每次執行都很慢的解決方法AndroidFlutter
- win10系統更新後開機變得很慢怎麼解決Win10
- win10系統下小娜cortana搜尋速度很慢如何解決Win10
- Android studio 解決編譯速度慢 Download maven-metadata.xml速度很慢Android編譯MavenXML
- Laravel 頁面突然變得很慢 原因竟然是開啟了 sudosu 外掛Laravel
- Windows10系統開啟excel2013檔案時很慢如何解決WindowsExcel