MySQL 5.6,5.7的優化器對於count(*)的處理方式
最近看了很多阿里同學的MySQL文章,阿里核心同學的文章一言不合就上程式碼,不光讓我們看到了結果,還能有程式碼可讀,如果碰到了類似的問題,這樣的解讀確實是很難得的。
今天做了一個小的測試,發現MySQL 5.7中對於count(*)的處理好像有點霸道,沒想象中那麼好。
為了對比,我找了一套5.6的環境。
總體而言5.6的環境中對於count(*)的處理可塑性很強,很隨和,你讓我怎麼查我就怎麼查。初始資料為100萬。
+----------+
| count(*) |
+----------+
| 1000000 |
+----------+
建表的語句如下:
>show create table test\G
*************************** 1. row ***************************
Table: test
Create Table: CREATE TABLE `test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`a` int(11) DEFAULT NULL,
`b` int(11) DEFAULT NULL,
`c` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `mrrx` (`a`,`b`),
KEY `xx` (`c`)
) ENGINE=InnoDB AUTO_INCREMENT=1000001 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)一直以來MySQL中count(*)的用法都是不被提倡,或者說是惡名遠揚,這一點讓很多學習Oracle的同學很不理解,其實他們是身在福中不知福。
這樣的一個count(*)的查詢,在5.6中的效果是這樣的,估算的時候預設是走了索引xx
>explain select count(*) from test\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: test
type: index
possible_keys: NULL
key: xx
key_len: 5
ref: NULL
rows: 998396
Extra: Using index
1 row in set (0.01 sec)
如果我們強制走mrrx索引,優化器說也行,於是就走了mrrx的索引,估算的資料情況和上面有一些小的差別。
>explain select count(*) from test force index(mrrx)\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: test
type: index
possible_keys: NULL
key: mrrx
key_len: 10
ref: NULL
rows: 947698
Extra: Using index
1 row in set (0.00 sec)或者我們顯式指定就要xx索引了,優化器說好,然後估算得到的行數和第一個差別很小。
>explain select count(*) from test force index(xx)\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: test
type: index
possible_keys: NULL
key: xx
key_len: 5
ref: NULL
rows: 947698
Extra: Using index
1 row in set (0.00 sec)如果換一種姿勢,如果指定索引列c,指定一個條件,再來看看,就會看到前後的結果差別就很大了。
>explain select count(*) from test where c > 0\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: test
type: range
possible_keys: xx
key: xx
key_len: 5
ref: NULL
rows: 473849
Extra: Using where; Using index
1 row in set (0.00 sec)這麼看來,5.6裡面的一個硬傷還是對於統計資訊這塊的評估差別較大,沒有了統計資訊還是有很大的侷限性,不過優化器還是很隨和的。
我們看看5.7的表現
同樣的語句和資料量,在5.7中明顯做了過濾處理,
> explain select count(*) from test\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: NULL
partitions: NULL
type: NULL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: NULL
filtered: NULL
Extra: Select tables optimized away
1 row in set, 1 warning (0.02 sec)
這表示在優化器階段已經被優化了。
而接下來同樣的語句也都是同樣的處理方式。
> explain select count(*) from test force index(mrrx)\G
> explain select count(*) from test force index(xx)\G
Extra: Select tables optimized away
而如果我們還是像之前一樣給定索引列c一個過濾條件,優化器就一下子變得溫和起來。很明顯這個執行的效果要好很多。
> explain select count(*) from test where c > 0\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: test
partitions: NULL
type: range
possible_keys: xx
key: xx
key_len: 5
ref: NULL
rows: 498949
filtered: 100.00
Extra: Using where; Using index
1 row in set, 1 warning (0.02 sec)
從某種程度來說,5.7這樣的處理也算是一種變相的退步啦。
這一點,阿里的同學已經開了case.
https://bugs.mysql.com/bug.php?id=81854
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23718752/viewspace-2141602/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Mysql優化系列之——優化器對子查詢的處理MySql優化
- Mysql最佳化器對in list的處理MySql
- Oracle優化器內部處理的表連線方式Oracle優化
- 【MySQL】效能優化之 count(*) VS count(col)MySql優化
- MySQL優化COUNT()查詢MySql優化
- 百萬資料 mysql count(*)優化MySql優化
- count(*) 優化優化
- count(*)優化優化
- javascript對於if條件語句程式碼的優化方式JavaScript優化
- 【案例】MySQL count操作優化案例一則MySql優化
- 關於mysql的優化MySql優化
- sql對於字串的處理SQL字串
- Mysql RELICATION對存過的處理MySql
- count(*)小優化優化
- MySQL 關於毫秒的處理薦MySql
- MyBatis多對多的兩種處理方式MyBatis
- sql server對於日期的處理SQLServer
- 對於死鎖的處理流程:
- sqlserver 針對預處理sql傳入引數的處理方式SQLServer
- 【優化】COUNT(1)、COUNT(*)、COUNT(常量)、COUNT(主鍵)、COUNT(ROWID)等優化
- MySQL的COUNT語句--count(*)、 count(常量)、 count(列名)MySql
- 關於圓角的5種處理方式
- TiDB與MySQL優化器對照TiDBMySql優化
- MySQL的count(*)的優化,獲取千萬級資料表的總行數MySql優化
- Oracle的優化器的RBO和CBO方式Oracle優化
- error的處理方式Error
- 你知道前端對圖片的處理方式嗎?前端
- Oracle優化器的RBO和CBO方式Oracle優化
- Java虛擬機器對內部鎖的四種優化方式Java虛擬機優化
- 對於信用證不符點的處理
- Autoprefixer:一個以最好的方式處理瀏覽器字首的後處理程式瀏覽器
- 介紹幾種提高mysql的效能和對於sql的優化的方法MySql優化
- 多對一處理 和一對多處理的處理
- MySQL 針對 like 條件的優化MySql優化
- Linux 4.21包含對AMD Rome處理器中新的Zen 2架構重要的新優化Linux架構優化
- HBase協處理器載入的三種方式
- 伺服器負載過高的處理方式伺服器負載
- mysql 大表中count() 使用方法以及效能優化.MySql優化