1. 程式人生 > >mysql千萬資料表管理介面

mysql千萬資料表管理介面

這段時間,系統一步步走來,使用者資料由原來的上百萬到現在的幾千萬,除了前臺介面做了很多改變,管理介面的修改也不少,資料量上來後,一個小的需求可能就涉及到大量的改造。這裡介紹下管理介面時候的查詢改變。

服務介紹:

A表現在業務分,一張2000W,一張幾百萬,
還有一張1000W的使用者表,更新操作較多,

資料庫伺服器,32G記憶體,16核,centos,mysql5.7

分佈查詢count 處理

在單表還是幾百萬的時候,分佈資料查詢就很慢了,10條資料的請求查了10來秒,而且還是有索引的情況下,

關鍵是那個count,之前的分頁外掛都是把count一起帶過來的,而count會消耗掉10S中的9S,為了使用者體驗,我們做了兩點操作:

  • 把count非同步化,即查10條資料時不去count,返回到介面後用ajax請求拿到count返回到介面。由於是非同步,前臺介面可能會被使用者點多次,如果前面的查詢比後面的返回晚,則count值會被覆蓋,可以採用時間戳引數方式,返回時識別此次請求的時間戳是否一致,一致則用此count.
  • count的查詢請求採用引數合集作為key,值存count和時間進行快取,1天失效,這樣在第一次請求的時候需要count後續都直接取快取,

快取的key可以採用 支付介面常常使用的 資料摘要方式進行加密.即把
第一步,設所有傳送或者接收到的資料為集合M,將集合M內非空引數值的引數按照引數名ASCII碼從小到大排序(字典序),使用URL鍵值對的格式(即key1=value1&key2=value2…)拼接成字串stringA.
第二步,對stringA進行MD5運算,再將得到的字串所有字元轉換為大寫,得到sign值signValue。

分頁查詢緩慢

但過了一定階段,對查詢條件加了索引,但limit 還是有點慢,後來發現是 order 慢,業務上有時間,這個時間我們是存string的,採用這個來order發現效果不太理想,於是採用timestamp新建了一個欄位,採用mysql自動更新的機制,發現效果比較好,速度也提了不少, 實際效果是,2000W那張表查詢前面的頁數也是毫秒查,無壓力 。

一些其它情況

期間發生過幾次情況,這裡進行描述.

一個是加索引的情況

大表加索引是個比較頭疼的問題,如果你的表只是insert還好,直接加即可,不會鎖住,如果表有update,則要想想辦法了,思路是用tmp 表和 原表 rename,然後給原表加索引,加完後再rename回來,完成資料的切換。具體可參考另一篇

http://blog.csdn.net/mingover/article/details/78588208

orderby時緩慢(時間花在Creating sort index )

如果遇到limit 前幾頁的時候也會緩慢,而相應的索引也加了,有可能是order by 的欄位沒有在where裡面引起的,可嘗試把column加到where語句中.具體可參考http://blog.csdn.net/mingover/article/details/79066064

其它

  • 聯表的問題
    聯表雖然有時好用,但業務分庫後就是很大的問題,這些邏輯不好理,所以強烈建議是多個小查詢 替換聯表查。而且一般來說聯表比程式碼邏輯可讀性要差。建議是在程式碼層面提供更多的crud方法,讓業務開發儘量少寫sql,寫也要註明單表查。
  • 沒加索引,導致mysql伺服器壓力巨大
    有一段時間發現mysql的cpu壓力巨大,16核在高峰時會全佔滿,剛開始還以為是業務訪問大,後來發現是有定時器的 幾條sql引起的。雖然只有幾條sql,但卻佔用了mysql的大量資源(時間主要花在Sending data),所以需要時刻注意會話中的長時間sql,可以採用“select * from information_schema.PROCESSLIST where state is not null and state !=” ORDER BY TIME DESC;”來查,也可以直接去訪問 慢查詢檔案看看。
  • sql的問題,
    count不能加 != ” ,發現加了這個後,1000S完不成一個查詢(1000w的表), like 千萬不能 前面加%.類似這些可以直接百度多瞭解一下.

結尾

關於大表的橫向切分內總部討論過多次,優先肯定業務切分,已經切過幾次了,效果挺好,改動也小。但對於一些難以用業務分的,則要考慮hash切或時間切,時間切的難度相對小,hash的話改動較大,需要謹慎。如果資料庫服務有壓力,可考慮先業務分庫.