Oracle遷移到MySQL效能下降的注意點

2021-09-23 18:04:32 字數 3285 閱讀 5246

背景:最近有較多的客戶系統由原來由oracle改造到mysql後出現了效能問題cpu 100%,或是後台的crm系統複雜sql在業務高峰的時候出現堆積導致業務故障。在我的記憶裡面**最初從oracle遷移到mysql期間也遇到了很多sql的效能問題,記憶最為深刻的子查詢,當初的版本是mysql5.1,這個版本對子查詢的優化較差,導致了很多從oracle遷移到mysql的系統出現過效能問題,所以後面的開發規範中規定前台交易系統不要有複雜的表join。接下來我將列舉一些常見從oracle遷移到mysql過程中可能出現問題的點:

1). 當客戶進行去o資料遷移時,存在必須改、不用改和可改可不改的三大類sql。對於可改可不改的,我們應提供一些指導性的建議,幫助使用者規避將來碰到可能存在的問題。

2). 指導資料庫研發人員、資料庫管理員合理使用mysql,發揮mysql最優性能。

1 並行處理

由於mysql不支援並行處理,所以當應用從oracle遷移到mysql後,需要特別注意使用了並行處理的sql語句。處理建議:

(1)、在阿里雲平台上可以使用ads這樣的分析型資料庫產品來處理oracle中的並行分析查詢。

(2)、將複雜sql語句進行業務分解,拆解為單條的sql語句,將計算結果放到應用中進行處理。

2 sql執行邏輯讀,物理讀,消耗時間2.2 改造建議

mysql對於簡單的sql語句執行是非常快的,對於oracle應用中邏輯讀,物理讀或者執行時間非常高的sql遷移到mysql後則不在適合了,需要進行改造:

(1)、單錶查詢邏輯讀,物理讀和執行時間比較長的情況,sql可能發生了全表掃瞄(dump需求)或者索引不優,可以使用唯讀節點來承受dump或者對索引進行優化。

(2)、多表查詢邏輯讀,物理讀和執行時間比較長的情況,可以使用ads分析型資料庫產品來處理;

(3)、多表查詢邏輯讀,物理讀和執行時間比較長的情況,可以進行業務分解,拆解為單條的sql語句,將計算結果放到應用中進行處理。

備註: 邏輯讀和物理讀如果超過100w,執行時間超過5s,則屬於較大的sql查詢。

3.in (…..)

3.1 背景介紹

oracle中對in(….)的引數限制是1000個,在mysql中雖然沒有個數限制但有sql長度的限制,同時優化器在對in(…)的查詢進行優化的時候採用二分查詢,所以in(...)的個數越多效能會越差,所以建議控制in的數目,不要超過100個。

3.2 改造建議

oracle:select * from t where id in(id1,id2…..id1000);

mysql:select * from t where id in(id1,id2…..id100);

4 子查詢

4.1 背景介紹

mysql在5.6版本以前處理子查詢的時候由於優化器只支援nested loop演算法,所以當關聯表較大的時候會帶來效能瓶頸。筆者曾經參加過一次大型專案從oracle遷移的mysql的遷移,當時資料庫的版本是5.5,原oracle應用中存在大量的子查詢,當遷移到mysql後sql執行出現堆積,連線數打滿,資料庫的cpu很快耗完,最後將子查詢修改後系統才恢復。

典型子查詢

select first_name

from employees

where emp_no in

(select emp_no from salaries_2000 where salary = 5000);

mysql的處理邏輯是遍歷employees表中的每一條記錄,代入到子查詢中中去

4.2 改造建議

改寫子查詢

select first_name

from employees emp,

(select emp_no from salaries_2000 where salary = 5000) sal

where emp.emp_no = sal.emp_no;

備註:子查詢在5.1,5.5版本中都存在較大風險,將子查詢改為關聯。

使用mysql 5.6的版本,可以避免麻煩的子查詢改寫的問題。

5 檢視優化

5.1 背景介紹

普通的檢視並沒有儲存實際的資訊,它所操作的資料來自於基本表,所以在普通檢視上不可以建立索引。那當需要對檢視進行大量查詢,而查詢效率較低時,如何處理呢?oracle 中有物化檢視,物化檢視是物理真實存在的,可以建立索引。而mysql並不支援物化檢視,所以當oracle中的檢視遷移到mysql後由於沒有物化檢視,可能導致效能下降。

5.2 改造建議

將檢視進行業務拆分,由應用進行實現。

6 函式索引

6.1 背景介紹

基於函式的索引,類似於普通的索引,只是普通的索引是建立在列上,而它是建立在函式上。當然這回對插入資料有一定影響,因為需要通過函式計算一下,然後生成索引。但是插入資料一般都是少量插入,而查詢資料一般資料量比較大。為了優化查詢速度,稍微降低點插入速度是可以承擔的。

mysql並不支援函式索引,所以當oracle中有使用函式索引的sql語句遷移到mysql後,由於無法使用索引導致全表掃瞄會出現效能下降。

比如執行如下一條sql語句:

select * from emp where date(gmt_create) = '2017-02-20'

即使在gmt_create上建立了索引,還是會全表掃瞄emp表,將裡面的gmt_create欄位去除掉時分秒後進行比較。如果我們建立乙個基於函式的索引,比如:create index emp_upper_idx on emp(date(gmt_create)); 這個時候,我們只需要按區間掃瞄小部分資料,然後獲取rowid取訪問表中的資料,這個速度是比較快的。

6.2 改造建議

通過sql改寫去除欄位上的函式,從而可以使用欄位上的索引:

select * from emp where gmt_create>='2017-01-20 00:00:00』 and gmt_created<』2017-01-21 00:00:00』

7 總結

(1).mysql不支援並行查詢,需要進行改造(關鍵字:parallel)。

(2).mysql優化器較弱,對於邏輯讀,物理讀和執行時間較長的sql需要注意。

(3).mysql對於in(…)引數數目建議不要超過100個。

(4).mysql對於子查詢優化不是很好,建議改造子查詢或者使用5.6資料庫版本。

(5).mysql不支援物化檢視,建議應用改造檢視。

(6).mysql不支函式索引,建議應用改寫sql避免索引無法使用。

Oracle遷移到MySQL總結

日期 2012 06 01 字型 大中小 這兩個星期裡一直都在忙於一件事兒,就是oracle資料庫的遷移問題。沒有做的時候感覺這是一件十分輕鬆的事兒,可是等到實實在在去做去實現的時候,自己傻眼了。這種糾結啊,在這裡先說下遇到的問題 1。資料庫的表結構問題 資料型別不同需要解決varchar2 var...

將MySQL資料遷移到Oracle

因為專案的原因,今晚將mysql資料庫的內容嘗試遷移到oracle,雖然結果失敗,不過學到了不少,下次就不一定了,哈哈 因為之前專案是使用mysql資料庫的,現在因為新公司要求使用oracle 公司大得很 不得不嘗試將以前專案進行遷移。經過查詢相關文件,最終選定使用oracle sql develo...

oracle遷移到mysql 僅使用指令碼

一直用oracle,最近研究了下mysql,先列舉下mysql奇怪的特性 1.不能儲存毫秒精度的時間.2.如果有varchar,char就會自動變varhar.3.timestamp時間範圍比datatime小,精度一樣,而且就算你不insert update,它的值也會自動改變.4.沒有seque...