myisam 將乙個表的總行數存在了磁碟裡面,使用的時候直接讀出來,很快。(如果有where 條件,就需要按行統計了,就不能那麼快)
innodb則是將資料一條條讀出來統計,所以資料越多越慢。
innodb這樣設計是因為事務,事務的併發版本控制,乙個事務中的查詢,只能對看到自己事務隔離級別的資料,也就需要判斷是否可見,
就不能簡單的直接存個總數在磁碟了。
innodb統計的時候會選擇盡可能小的索引樹去查詢,因為邏輯相同相同的情況下,盡可能減少掃瞄行數。
show table status 執行很快,可以看到結果中有個rows,行數。 但是這個之前也說過,是通過取樣統計出來的,官方都說有40%到50%的誤差,因此不能直接用。
解決大表count,首先要count 有索引的字段,如果資料實在太多,那麼需要用到快取,將count快取起來,但是不能簡單的快取到redis裡面,
事務表裡面是有事務的,直接存redis ,然後去redis中取,就跟myisam那樣直接存磁碟沒有區別了。比如說事務a在count中加了1,然後事務b去redis中取count ,如果事務a還沒提交,那麼事務a的操作應該是對事務b不可見的,但是事務b卻讀到了最新的+1之後的count。
因此,如果分頁頁面要統計count,那麼可以在第一頁查詢的時候將count統計出來,存到頁面上,點翻頁的時候,再將count回填回去
這樣翻頁就不需要在去統計count了。
如果資料量更大,那就只能將count單獨存到乙個表裡面。使用的時候去這個表裡面查,innodb的表 是支援事務的,就不會跟存redis一樣存在可見性的問題。
16.2 count的區別
count(*) :
count(1):
count(列名):
count是乙個聚合函式,在innodb裡面是一行行取數,如果count函式的引數不為空,統計值就+1 ,否則不加,然後返回累計值。
因此對於 count(*) ,count(1),count(id) ,函式的引數都不會為空,所以就是統計的是滿足條件的所有行。
count(列名),則是統計的是滿足條件且列不為空的記錄。
count(id) ,innodb會遍歷整個表,把每一行的id值都取出來,返回給server層, server層拿到id之後,判斷是否為空,如果不是,就加1,如果是
就不加,id是不可能為空的。 所以count(id)就是統計的符合條件的所有行。
count(1) 則是 innodb會遍歷整個表,但是不取值,然後返回1 ,server層判斷是否為空,也不可能是空的,所以也是統計符合條件的所有行
因此count(1) 效率比count(id) 要好一點,因為不用取數。
count(字段) ,遍歷整個表,然後取值,判斷是否為空,如果為空不加,不為空+1
count(*) 做了優化,如果肯定不為空的,不取值 直接+1。 而且會自動優化決定去怎麼找,使用哪個列。
僅僅從執行效率上說,count(1)和count()高。
功能則各有側重點,count(1) count(id) count() 統計全部 ,count(列) 只統計列為非空。
mySQL筆記(十二) DML語言
dml data manipulation language 資料操縱語言 涉及到的關鍵字 insert update delete 對錶中的資料的增刪改 dml語言 一 資料的插入 語法 插入單行 insert into 表名 欄位名1,欄位名2 values 值1,值2,插入多行 insert ...
C C 學習筆記 基礎入門系列(十二)
第一部分 helloworld的起點 第二部分 初探資料型別 一 第三部分 初探資料型別 二 第四部分 認識運算子 一 第五部分 認識運算子 二 第六部分 理清思路,寫好邏輯結構 一 第七部分 理清思路,寫好邏輯結構 二 第八部分 理清思路,寫好邏輯結構 三 第九部分 資料處理神器之陣列 一 第十部...
SpringCloud系列十二 Zuul
zuul包含了對請求的路由和過濾兩個最主要的功能 其中路由功能負責將外部請求 到具體的微服務例項上,是實現外部訪問統一入口的基礎而過濾器功能則負責對請求的處理過程進行干預,是實現請求校驗 服務聚合等功能的基礎。zuul和eureka進行整合,將zuul自身註冊為eureka服務治理下的應用,同時從e...