交代一下背景,這算是一次專案經驗吧,屬於公司乙個已上線平台的功能,這算是離職人員挖下的坑,隨著資料越來越多,原本的sql查詢變得越來越慢,使用者體驗特別差,因此sql優化任務交到了我手上。
這個sql查詢關聯兩個資料表,乙個是攻擊ip使用者表主要是記錄ip的資訊,如第一次攻擊時間,位址,ip等等,乙個是ip攻擊次數表主要是記錄每天ip攻擊次數。而需求是獲取某天攻擊ip資訊和次數。(以下sql語句測試均在測試伺服器上上,正式伺服器的效能好,查詢時間快不少。)
檢視表的行數:
未優化前sql語句為:
select
attack_ip,
country,
province,
city,
line,
info_update_time as attack_time,
sum( attack_count ) as attack_times
from
`blacklist_attack_ip`
inner join `blacklist_ip_count_date` on `blacklist_attack_ip`.`attack_ip` = `blacklist_ip_count_date`.`ip`
where
`attack_count` > 0
and `date` between '2017-10-13 00:00:00'
and '2017-10-13 23:59:59'
group by
`ip`
limit 10 offset 1000
先explain分析一下:
這裡看到索引是有的,但是ip攻擊次數表blacklist_ip_count_data也用上了臨時表。那麼這sql不優化直接第一次執行需要多久(這裡強調第一次是因為mysql帶有快取功能,執行過一次的同樣sql,第二次會快很多。)
實際查詢時間為300+秒,這完全不能接受呀,這還是沒有其他搜尋條件下的。
那麼我們怎麼優化呢,這裡用的是內聯表查詢,大家都是知道子查詢完全是可以代替內聯表查詢的,只不過sql語句複雜了不少,那麼我們分析一下這sql,兩個表分表提供了什麼?
1、ip攻擊次數表blacklist_ip_count_data主要提供的指定時間條件查詢,攻擊次數條件查詢後的ip和每個ip符合條件下的具體攻擊次數。
2、攻擊ip使用者表blacklist_attack_ip主要是具體ip的資訊,如第一次攻擊時間,位址,ip等等。
那麼我們一步步來:
1、ip攻擊次數表blacklist_ip_count_data獲取符合時間條件和攻擊次數的ip並且以ip分組:
2、攻擊ip使用者表blacklist_attack_ip指定具體的ip獲取資訊:
然後結合在一起:
可見,取出來的資料完全一模一樣,可是優化後效率從原來的330秒變成了0.28秒,這裡足足提公升了1000多倍的速度。這也基本滿足了我們的優化需求。
我們explain了解一下情況:
mysql千萬級如何優化?
1 查詢語句上,只寫必要的字段,建好索引,注意一下查詢條件的使用,多表查詢不要用框架 自己寫sql 2 一定要分頁 一些小表也養成習慣,哪怕你在前台設定多一點可選記錄數選項 如,10,50,100,500,1000 區域網環境 不能再多了孩子 3 在一定數量的基礎上,做好表分割槽 4 拆表 5 拆庫...
千萬級MySQL分頁優化
對於只有幾萬條資料的表這樣做當然沒問題,也不會在使用者體驗上有何不妥,但是要是面對成百萬上千萬的資料表時,這樣就不足以滿足我們的業務需求了,如何做到對千萬級資料表進行高效分頁?首先要學會使用 explain 對你的sql進行分析,如果你還不會使用 explain 分析sql語句 傳送門 一丶合理使用...
MySQL 對於千萬級的大表的優化?
第一 優化你的sql和索引 第二 加快取,memcached,redis 第三 以上都做了後,還是慢,就做主從複製或主主複製,讀寫分離,可以在應用層做,效率高,也可以用三方工具,第三方工具推薦360的atlas,其它的要麼效率不高,要麼沒人維護 第四 如果以上都做了還是慢,不要想著去做切分,mysq...