MIS性能優化常見問題與方案(輔助項目組性能優化的總結貼)

最近幫忙公司的幾個項目組進行了不一樣方面的性能優化,發現幾個項目都出現了一些共性的問題。這裏寫一篇文章,總結一下這幾類問題,以及其對應的解決方案。方便其它項目組參考。css

 

常見問題一:打開頁面很是慢,有的項目打開一個頁面居然要 20 多秒。 html


優化步驟:前端

  1. 下降每個頁面的請求數:使用瀏覽器跟蹤打開頁面後全部的請求,並逐一排查,把沒有必要向服務端發起的請求優化掉,減小 Round Trip 次數。
  2. 針對每個請求進行優化:對請求逐一排查,看看分別是哪些請求佔用了較多的時間。
    若是該請求是 JS 文件,則考慮使用壓縮版本(例如正在使用的 EXTJS,應該使用 ext-all.js 1.9M,而不是 ext-all-debug.js 4.5M)。
    靜態資源要儘可能啓用緩存。
  3. 將每次請求所對應的數據庫訪問次數下降到最低:這一步屬於後端優化。
    每個請求到達服務端後,都會作一系列的操做,例如:初始化當前用戶、角色、權限、當前模塊、業務邏輯、日誌等。
    對於前四個操做,每每是全部頁面都須要初始化的,那麼咱們須要使用 Session 或 Cache 等技術來優化,以防止每次請求都從新訪問數據庫。
    對於業務邏輯、日誌等,咱們主要解決的是《ORM 中的 N+1 問題》、優化掉多餘的數據庫訪問(須要記住,每一次數據庫訪問,其實都是一次遠程訪問)。
  4. 另外,Web 頁面的前端優化,還能夠參考《 YAHOO Web 優化的 14 條法則》。

 

常見問題二:單條 SQL 語句執行較慢 算法


在數據量較大的狀況下,一些 SQL 語句執行得很是慢。數據庫

優化步驟:後端

  1. 是否 SQL 自己有性能問題?
  2. 是否創建了表分區?
    http://www.cnblogs.com/leiOOlei/archive/2012/06/08/2541306.html
    http://blog.csdn.net/hijiankang/article/details/9173877
  3. 是否對主要查詢的字段創建了索引?
  4. 測試數據是否有效?(儘可能按照真實場景來準備測試數據)
  5. 是否須要限制用戶的數據查詢範圍?
  6. 是否須要優化業務結構?
    是否真的須要爲用戶提供一個查看幾十萬頁的數據的頁面?這樣的數據對於用戶來講,每每是沒用的。咱們應該在功能模塊方面從新設計?
  7. 不要使用 JOIN,而是使用 IN 語句。
  8. 不要查詢全字段,而是隻查詢 ID。

 

例如,下面這個 SQL,在壓力測試 1000 萬行數據時,已經須要 8 秒左右:瀏覽器

SELECT * FROM
(
    SELECT T.*, ROWNUM RN
    FROM 
    (
SELECT *
FROM "T_PRIMITIVEDETAIL" "T0"
WHERE "T0"."ORDERGOODSDATE" >= :p0 AND "T0"."ORDERGOODSDATE" <= :p1 AND "T0"."CORPORATION" = :p2 AND "T0"."DBI_ISPHANTOM" = :p3
ORDER BY "T0"."ID" ASC
    ) T
    WHERE ROWNUM <= 5000010
)
WHERE RN >= 5000000
--Parameters:2016/5/1 0:00:00,2016/5/31 23:59:59,"惠州酷友網絡科技有限公司","0"

 

ID 列和 ORDERGOODSDATE 列都是創建了索引的,同時也爲 ORDERGOODSDATE 列創建了表分區。通過幾回測試,發現經過索引列排序進行查詢速度仍是較慢(索引 Id 列:首次5秒,後面都是2.3秒;有索引的時間列:6秒;不排序:2秒)。緩存

同時,咱們還對分頁 SQL 進行的測試。目前有三種較爲通用的分頁格式:安全

1.根據ROWID來分
select * from t_xiaoxi where rowid in(
  select rid from (
    select rownum rn,rid from(
     select rowid rid,cid from
     t_xiaoxi  order by cid desc
    ) where rownum<10000
  ) where rn>9980
)
order by cid desc;
2.按分析函數來分
select * from (
  select t.*,row_number() over(order by cid desc) rk from t_xiaoxi t
) where rk<10000 and rk>9980;
3.按ROWNUM來分
select * from(
  select t.*,rownum rn from(
    select * from t_xiaoxi order by cid desc
  ) t where rownum<10000
) where rn>9980;性能優化

結果發現,原來的分頁格式,效率是最高的。下面的 SQL 查詢須要 4 秒:

select * from (
  select t.*,row_number() over(order by id ASC) rk from T_ENTERPRISETRANSACTION t
) where rk <= 5000010 and rk >= 5000000

因爲咱們的分頁 SQL 是自動生成的,因此格式方面咱們要保留必定的通用性,同時性能不能太差。因此仍是決定繼續保留原有的格式。

前面幾個優化方案沒有成功。咱們就看了一下測試人員插入的一千條數據。原來這些數據的時間都是同一天的!!!形成了分區和索引失效。將數據按照真實場景錄入後,不到 1s 就查詢出來了。

另外,第 6 條:有 50 萬頁數據的頁面,不該該設計給客戶看到。因此我讓項目組的同這考慮是否須要刪除這個頁面,換一種實現方案。

第8條,不查全字段,只查 ID:測試後,也有了比較明顯的效果。

SELECT ID FROM
(
    SELECT T.*, ROWNUM RN
    FROM 
    (
SELECT ID
FROM "T_ENTERPRISETRANSACTION" "T0" 
--order by T0.Id desc
--order by T0.DBI_CreatedTime
--order by T0.tradeDate
    ) T
    WHERE ROWNUM <= 5000010
)
WHERE RN >= 5000000
--0.6秒
SELECT * FROM "T_ENTERPRISETRANSACTION" "T0" WHERE ID IN (7853679,7853680,7853681,7853682,7853683,7853684,7853685,7853686,7853687,7853688,7853689)
--0.1秒

一共只須要 0.7 秒。

 

常見問題三:大數據導入性能優化


公司產品的一個重要模塊是一個數據導入引擎。基於 WF4 引擎,配合必定的活動,來實現從文件到數據庫的導入。即:讀取文件 –> 大量數據格式轉換邏輯 & 大量業務邏輯 –> 導入數據庫。

因爲邏輯很是複雜,因此咱們並無把這些邏輯放到數據庫中去編寫存儲過程,而是基於內存中的領域實體來執行業務邏輯。

對於此程序的優化步驟:

  1. 經過性能監控工具,找到性能損耗的核心位置,再針對該位置出方案進行優化。
    這一步應該做爲第一個步驟。開發者在對性能進行優化時,每每出現「想固然」地去分析、優化的行爲,最終是花費了時間也沒有優化到點上!因此這裏首重提出這一步驟。先讓工具去幫咱們找到這些核心位置!
  2. 下降數據庫訪問次數。(此項檢查是全部數據庫訪問程序的首要優化方案,也是最容易出現問題的地方)。
    1.1 解決 ORM 中的 N+1 問題。
    1.2 在內存中一次性準備好數據後,再插入到數據庫中。
    1.3 對於導入大數據量到數據庫中,採用批量導入方案,而非逐條導入方案。
  3. 多線程技術。
    因爲數據導入程序是 IO 密集型 + CPU 密集型操做,可是兩者的運行階段不一樣。因此合理地採用多線程,能夠大大提高執行效率。
    使用多線程時,要注意線程安全的問題:儘可能不要有太多的共享資源(文件、數據庫中的行);共享資源要加鎖(文件加鎖、內存加鎖、數據庫事務(事務的級別))。
    另外,提早爲各個線程準備好一些共用的數據,也能夠優化一些沒必要要的 IO。
  4. 優化核心大數據的循環,以及嵌套循環的核心循環中的代碼便可。這些位置的代碼,須要到處當心,優化到極致。
    核心循環中,不要用 LINQ To Object:一個 Linq To Object 操做,至少生成了三個輕量級對象:一個委託、一個實現 IEnumerable 接口的對象,以及遍歷集合時,生成的一個 Enumerator。
    核心循環中,要儘可能減小循環的次數。例如:1000萬數據和100萬數據作循環匹配,不優化的循環就須要執行 1000萬*100萬次。因此咱們須要引入一些算法來優化沒必要要的循環次數。
    只須要優化核心循環,不須要優化全部的代碼。LINQ To Object 該用的時候,還要用。微笑 

 

小結


本文對公司幾個項目遇到的共性問題進行了總結。

但願能對其它的項目組有所幫助。也但願能收集到更多的優化建議。

相關文章
相關標籤/搜索