[英]Enhance performance of large slow dataloading query
我正在嘗試將數據從oracle加載到sql server(很抱歉,以前沒有寫過此信息)
我有一個表(實際上是一個視圖,其中包含來自不同表的數據)至少具有一百萬條記錄。 我以一種具有業務邏輯功能的方式設計了程序包,並直接在select查詢中調用它們。
例如:
X1(id varchar2)
x2(id varchar2, d1 date)
x3(id varchar2, d2 date)
Select id, x, y, z, decode (.....), x1(id), x2(id), x3(id)
FROM Table1
注意:我的表有20列,我至少要6-7列調用5個不同的函數。 一些功能比較傳遞給審計表的參數並執行邏輯
我如何才能提高查詢性能,或者有更好的方法來做到這一點
我嘗試用C#代碼執行此操作,但是記錄的初始選擇足以容納數據集,並且出現內存不足的異常。
我的函數會選擇並執行邏輯,例如:
Function(c_x2, eid)
Select col1
into p_x1
from tableP
where eid = eid;
IF (p_x1 = NULL) THEN
ret_var := 'INITIAL';
ELSIF (p_x1 = 'L') AND (c_x2 = 'A') THEN
ret_var:= 'RL';
INSERT INTO Audit
(old_val, new_val, audit_event, id, pname)
VALUES
(p_x1, c_x2, 'RL', eid, 'PackageProcName');
ELSIF (p_x1 = 'A') AND (c_x2 = 'L') THEN
ret_var := 'GL';
INSERT INTO Audit
(old_val, new_val, audit_event, id, pname)
VALUES
(p_x1, c_x2, 'GL', eid, 'PackgProcName');
END IF;
RETURN ret_var;
我正在獲取每一行並在C#中執行邏輯,然后插入
如果可能,請從SELECT中插入:
INSERT INTO YourNewTable
(col1, col2, col3)
SELECT
col1, col2, col3
FROM YourOldTable
WHERE ....
這將運行多單查詢顯著更快哪里,那么你在結果集循環,並為每個行的一個INSERT。
編輯作為OP問題編輯:
您應該能夠在查詢中替換對普通SQL的函數調用。 使用LEFT JOIN tableP模仿“ initial”,並且可以使用CASE計算“ RL”或“ GL”。
根據OP最近的評論進行編輯 :
由於您是將數據從Oracle加載到SQL Server中,所以我會這樣做:大多數可以幫助您的人已經繼續前進,不會再閱讀此問題,因此在您說一個新問題的地方打開一個新問題:1)您需要加載數據(從Oracle(版本)到SQL Server版本2)當前,您正在通過一個查詢來加載它,並處理C#中的每一行並將其插入SQL Server,這很慢。 以及所有其他詳細信息。 有很多更好的方法將數據批量加載到SQL Server。 對於這個問題,您可以接受答案,在解釋您需要提出新問題的地方回答自己,或者不接受。
我的建議是不要使用函數,然后在其他SELECT語句中調用它們。 這個:
SELECT t.id, ...
x1(t.id) ...
FROM TABLE t
...相當於:
SELECT t.id, ...
(SELECT x.column FROM x1 x WHERE x.id = t.id)
FROM TABLE t
像在使用C#/ etc一樣,封裝在SQL中不起作用。 盡管該方法使維護更加容易,但是由於子選擇將針對返回的每一行執行,因此性能會受到影響。
更好的方法是將支持功能更新為在SELECT中包括where x.id = t.id
條件(即:缺少真實值的“ where x.id = t.id
”):
SELECT x.id
x.column
FROM x1 x
...因此您可以將其用作JOIN:
SELECT t.id, ...
x1.column
FROM TABLE t
JOIN (SELECT x.id,
x.column
FROM MY_PACKAGE.x) x1 ON x1.id = t.id
我更喜歡為了維護而不得不將函數邏輯合並到查詢中,但是有時它無濟於事。
我個人將創建一個SSIS導入來執行此任務。 使用大容量插件可以顯着提高速度,而SSIS可以在批量插入后處理功能部件。
在表上創建一個排序的intex。
SQL Server Indizes簡介 ,其他RDBMS相似。
編輯,因為您編輯了問題:
使用視圖更為不理想,尤其是在從視圖查詢單行時。 我認為您的“業務功能”實際上類似於存儲過程嗎?
就像其他人建議的那樣,在SQL中總是基於集合。 我以為您已經做到了,因此開始使用索引的提示。
一些提示:
INSERT
變慢,但SELECT
快。 首先,您需要找到實際的性能問題所在。 然后,您可以查看嘗試解決它的方法。
視圖的表現如何? 在沒有任何函數調用的情況下視圖執行需要多長時間? 嘗試運行命令
它的表現如何? 需要1分鍾還是1小時?
\n 創建表the_view_table\n 如\n 選擇 *\n 從the_view;\n
功能執行得如何? 根據描述,您將進行大約500萬個函數調用。 他們最好效率很高! 也定義為deterministic
的功能。 如果使用deterministic
關鍵字定義函數,則Oracle有機會優化一些調用。
有沒有減少函數調用次數的方法? 一旦對視圖進行了評估並且數百萬行的數據可用,就會調用該函數。 但是所有輸入值都來自查詢的最高級別嗎? 可以將函數調用嵌入到較低級別的視圖中。 考慮以下兩個查詢。 哪個會更快?
選擇 \n f.dim_id, \n d.dim_col_1, \n long_slow_function(d.dim_col_2)as dim_col_2\n 來自large_fact_table f\n 加入small_dim_table d on(f.dim_id = d.dim_id)
選擇 \n f.dim_id, \n d.dim_col_1, \n d.dim_col_2\n 來自large_fact_table f\n 加入(\n 選擇 \n dim_id, \n dim_col_1, \n long_slow_function(d.dim_col_2)as dim_col_2\n 來自small_dim_table)d on(f.dim_id = d.dim_id)
理想情況下,第二個查詢應運行得更快,因為它調用函數的次數更少。
性能問題可能出在任何這些地方,並且在您調查問題之前,很難知道將調整工作定向到何處。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.