問題用戶登錄log表1000w以上查詢,[統計未登陸用戶]
2014-03-01 2016-03-31[也就到現在的
全部數據]到現在 2700w
解決方案:1
二級索引,2 between and代替 大於小於 > <
sql如下:
SELECT count(DISTINCT(uid)) FROM login_log WHERE uid>=0 between 1396195200 and 1459353600
耗時:14.793s[第二次查詢1s內,走query cache]
SELECT DISTINCT(uid) FROM login_log WHERE uid>=0 between 1396195200 and 1459353600
耗時:1.414s
千萬級log查全部 這個query時間還可以接受
從60s以上減到 秒類 基本最優了。
[補充]
另外如果普通1000w級數據查詢,基本都是取20條之類,分頁等 這樣query基本都可以到毫秒
結論
1. 沒有任何條件的查詢不一定走的是主鍵索引,mysql優化器會使用認為是最小代價的索引
2. 在count(*)的時候,采用主鍵索引比二級索引要慢,而且慢的原因不是因為兩者的索引的長度不同
3. Count(*)在沒有查詢條件的情況下,對innodb引擎的mysql會進行全表掃描,而myasm引擎的mysql無需進行全表掃描,因為myasm的引擎記錄了每個表的多少記錄。但是當有查詢條件的時候,兩者的查詢效率一致。
4. 經過后來查詢大量的資料,主鍵索引count(*)的時候之所以慢
l InnoDB引擎
[1] 數據文件和索引文件存儲在一個文件中,主鍵索引默認直接指向數據存儲位置。
[2] 二級索引存儲指定字段的索引,實際的指向位置是主鍵索引。當我們通過二級索引統計數據的時候,無需掃描數據文件;而通過主鍵索引統計數據時,由於主鍵索引與數據文件存放在一起,所以每次都會掃描數據文件,所以主鍵索引統計沒有二級索引效率高。
[3] 由於主鍵索引直接指向實際數據,所以當我們通過主鍵id查詢數據時要比通過二級索引查詢數據要快。
l MyAsm引擎
[1] 該引擎把每個表都分為幾部分存儲,比如用戶表,包含user.frm,user.MYD和user.MYI。
[2] User.frm負責存儲表結構
[3] User.MYD負責存儲實際的數據記錄,所有的用戶記錄都存儲在這個文件中
[4] User.MYI負責存儲用戶表的所有索引,這里也包括主鍵索引。