中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何從設計和規范上規避RDS性能問題?

發布時間:2020-08-10 03:37:23 來源:ITPUB博客 閱讀:150 作者:tianxiaoxu 欄目:數據庫

【本文轉自云棲社區 作者neo.Wang】
在初創型互聯網公司中,開發們整天想的唯一一件事,就是“把功能做出來”。而當公司業務量逐漸上漲、甚至翻了好幾番之后,最開始的程序上的問題,就一個接一個地暴露了出來。
其中,最明顯的,就是數據庫的壓力問題。下文提到的數據庫,都指RDS for MYSQL

場景一:寬表

現象

開發在設計表結構的時候,很大程度上是在參考產品原型的設計。通常會把產品原型中,需要一起查詢的條件、一起展示的字段,都放在同一張表中。而互聯網公司的產品迭代又是非常快的,新功能層出不窮,開發沒有時間重新梳理數據庫結構,就盲目地在原來的表上增加冗余字段,為了使功能盡快開發完成。這就使得某些“老古董”的表,越來越寬,七八十個字段以上的大寬表越來越多。

建議

(1)單個InnoDB表的字段數,建議少于50個;
(2)大字段,例如:text、blob類型,考慮單獨存放;

場景二:列表的行數查詢

現象

在后臺或者部分前端的功能中,常常會出現類似MIS系統的列表查詢功能。一般這種功能,都是按照選定的查詢條件,先查出行數,再按照分頁規則查詢出第一頁的數據。于是,就出現了這樣的幾種情況:
(1)查詢列表明細,是需要使用多表關聯查詢的。開發為了方便,直接把這個查詢明細的“多表關聯”的SQL拿過來,把select后邊的字段改成count(*),就直接作為查詢行數的SQL,甚至連order by都不去掉。而從業務上來說,查詢行數的時候,只需要查詢其中一張表就可以了;
(2)代碼邏輯的設計不合理,導致某些開發,直接套用“首頁”邏輯,查詢后續每一頁的時候,都重新查詢了一遍行數;

建議

(1)增加SQL審核機制,不合規范的SQL不允許上線;
(2)增加代碼審核機制;

場景三:查詢不走索引

現象

很常見的情況是,某些表最開始的數據量很小,后來由于產品功能重心的調整,變成了大表。之前做好的程序、SQL、表結構卻沒有跟著調整。就出現了很多大表查詢,沒走索引,導致的慢查詢。而慢查詢堆積多了,整個數據庫就癱瘓了,于是就出現了“次要業務拖累主要業務”的現象。

建議

(1)根據查詢場景,設置合理的索引,組合索引優先;
(2)當組合索引和單字段索引同時存在時,建議刪掉單字段索引,避免優化器做“無用功”;

場景四:線上數據和線下數據沒有隔離

現象

這里說的線上數據,指的是直接面對廣大用戶的數據;線下數據,是面向公司內部客服、運營的后臺系統用到的數據。后臺系統由于工作職責的不同,會有各種各樣的查詢需求,有的可能會很大、很復雜,比如導出一整個月、一整個季度的數據。會直接導致數據的壓力非常大,進而影響了整個數據庫實例,導致線上系統發生故障。

建議
  • 線上數據的特點是:

    1. 訪問量大;
    2. 每個用戶只查自己的數據,可以命中索引;
    3. 查詢條件簡單;
    4. 返回條數少;
    5. 對響應時間要求極高;
    6. 對數據的時效性要求高;
  • 線下數據的特點是:

    1. 訪問量小;
    2. 后臺同事會查詢整個平臺的數據,不容易命中索引;
    3. 查詢條件復雜;
    4. 返回條數大;
    5. 對響應時間要求不高;
    6. 對數據的時效性要求不是特別高;

綜上,兩類數據從各個方面都是完全不同的。要把線上數據和線下數據隔離開來。更新時,統一更新線上數據;查詢時,線上查線上,線下查線下。線上數據通過DTS等實時數據同步的方式更新到線下。

場景五:過于依賴MYSQL,沒有考慮其他的存儲

現象

某些列表查詢類場景,可能涉及到10~20個查詢條件,而且檢索數據量一般也很大。此時再使用MYSQL就比較吃力了,索引幾乎無法覆蓋。

建議

除了關系型數據庫之外,我們有很多不同的數據存儲的選擇,比如:搜索引擎類、NOSQL類、時序類、緩存類,等等。應當根據不同的查詢場景,選擇最適合的數據存儲方式。企圖用MYSQL解決一切問題,是不明智的。

場景六:沒有站在數據庫的角度去思考

現象

比如,子查詢。開發站在人類的角度思考問題,就會出現形如:

SELECT * FROM table1 WHERE id IN ( SELECT id FROM table2 ); 

這種子查詢。而MYSQL在處理子查詢的時候,是拿外層的每一條數據,去內層掃描,結果就是掃描了table1的行數 × table2的行數次。

建議

避免使用子查詢,改為通過索引做表關聯等方式;

場景七:直接在數據庫中做計算

現象

部分開發會在SQL中寫例如case when、group by + count/sum等的計算。MYSQL擅長的是,數據的查詢與存儲,并不擅長做計算——雖然它可以做。導致出現了很多慢SQL。MYSQL只對查詢做了優化,并沒有對計算做優化。

建議

(1)group by + count/sum可以考慮進行預計算;
(2)case when可以在業務端或者前端進行;
(3)要有效利用每個工具最擅長做的事。

場景八:在索引字段上用函數

現象

部分表在bigint類型的、存放時間戳的字段上做了索引,而查詢的條件是精確到天的。某些開發就會把SQL寫成:

WHERE from_unixtime(create_timestamp) >= '2018-01-01' AND from_unixtime(create_timestamp) < '2018-02-01' 

這樣。在索引字段上使用函數,索引就起不到作用,掃描數據的時候依然是全表掃描,并對每一行數據的create_timestamp做from_unixtime運算。

建議

如:

WHERE from_unixtime(create_timestamp) >= '2018-01-01' AND from_unixtime(create_timestamp) < '2018-02-01' 

這種場景,可以改為:

WHERE create_timestamp >= unix_timestamp('2018-01-01')
AND create_timestamp < unix_timestamp('2018-02-01') 

這樣,只會計算一次,然后直接去匹配索引。避免了全表掃描。

場景九:沒有充分利用緩存

現象

部分對數據實時性要求不高的場景。會有相同條件的查詢頻繁執行的情況,甚至于并發執行多個相同查詢條件的查詢。這時候如果每次都查詢數據庫,勢必造成了資源的浪費。

建議

把這部分查詢結果,緩存到redis中。把大部分請求量引到redis去。

場景十:單表數據量過大

現象

由于對MYSQL依賴嚴重,導致很多更適合存在NOSQL數據庫的數據,也被存到了MYSQL中,而且行數非常多。這樣的表,無論是查詢、還是更新、或是DDL操作,都需要停服之后、花大量時間去做。

建議

(1)單表不要超過1千萬行,大小不要超過5G;如果超過,可以考慮分庫分表;
(2)根據場景,考慮用其他數據存儲工具、或其他業務上的邏輯來解決大表的問題;

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

庆阳市| 新宾| 临城县| 崇州市| 丹巴县| 灌阳县| 大竹县| 乐清市| 临海市| 纳雍县| 太谷县| 新田县| 温泉县| 寿光市| 铜川市| 禹州市| 县级市| 莎车县| 满城县| 元江| 逊克县| 襄城县| 徐闻县| 重庆市| 古浪县| 开远市| 白河县| 浦北县| 泰安市| 东乌珠穆沁旗| 丹东市| 曲水县| 壤塘县| 逊克县| 南部县| 辽宁省| 剑河县| 正宁县| 开原市| 翁源县| 酒泉市|