mysql - 一個sql的問題
問題描述
stat表 字段 uid,act,time我想取出每個uid最近的一個act我現在的sql:
select * from (select * from stat order by uid,time desc) a group by uid
這個表數據量比較大,查起來有點慢,有沒有更好的辦法
甚至這個:
select act,count(*) num from (select * from (select * from stat order by uid,time desc) a group by uid) b group by act
表:
CREATE TABLE `stat` ( `uid` varchar(40) COLLATE utf8_unicode_ci NOT NULL, `act` bigint(20) NOT NULL, `time` bigint(20) DEFAULT NULL, PRIMARY KEY (`uid`,`act`), KEY `index_time` (`time`) USING BTREE, KEY `index_act` (`act`) USING BTREE) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
問題解答
回答1:先說一下我的看法吧,如果有錯誤的地方,歡迎指正。首先,我覺得題主的SQL語句是錯的,看起來結果正確只不過是寄希望于數據庫在執(zhí)行group by的實現機制。比如說如果把排序順序變一下結果就錯了。在使用group by之后,題主能夠查詢的字段要么是在聚集函數里面,要么就是group by的字段,類似于’select * from a group by uid’這樣的寫法不規(guī)范,因為數據庫在按照uid分組之后,會隨機選取一組act和time的字段值。題主的SQL看起來工作正常應該是在排序之后,數據庫默認選取了排序最靠前的。我認為正確的SQL應該是這樣的:
select stat.* from stat ,(select uid,max(time) as time from stat group by uid) tmp where stat.uid=tmp.uid and stat.time=tmp.time;
先分組查詢出每個人執(zhí)行時間最晚的時間,然后根據uid和time去獲取完整的操作信息。如果題主的數據庫對uid加了索引的話,這個 SQL的查詢效率應該還在可以接受的程度。一點個人看法。
我在原來的基礎之上,做了一丟丟修改,在本地測試性能有微小的提升,我本地是三萬組測試數據,題主可以試一下:
select stat.* from stat ,(select uid,max(time) as time from stat group by uid order by null) tmp where stat.time=tmp.time and stat.uid=tmp.uid;回答2:
給查詢條件的那幾個列建立索引試試,B數索引呀,B+數索引呀等等
具體怎么建立你可以去百度搜一下
回答3:這個語句為什么要嵌套子查詢,一條語句不行嗎,不是很清楚邏輯,,,不過正常情況下我都是用explain打印一下查詢信息
回答4:一條group by就足夠了為什么要寫兩層
相關文章:
1. javascript - vscode alt+shift+f 格式化js代碼,通不過eslint的代碼風格檢查怎么辦。。。2. javascript - 如何將一個div始終固定在某個位置;無論屏幕和分辨率怎么變化;div位置始終不變3. html5 - 有可以一次性把所有 css外部樣式轉為html標簽內style=" "的方法嗎?4. javascript - 有什么比較好的網頁版shell前端組件?5. java - 如何寫一個intellij-idea插件,實現編譯時修改源代碼的目的6. javascript - 原生canvas中如何獲取到觸摸事件的canvas內坐標?7. java 中Long 類型如何轉換成Double?8. javascript - 求解答:實例對象調用constructor,此時constructor內的this的指向?9. html - vue項目中用到了elementUI問題10. javascript - [js]為什么畫布里不出現圖片呢?在線等
