我現在為提高效率多執行緒向同一張表插入,會出現超時的問題,可以并發插入資料庫快取,然后讓他自己再插入嗎?MySQL有這種方式,不知道ORACLE該如何實作?
uj5u.com熱心網友回復:
Oracle從oracle7i開始就支持并行,即多執行緒,具體的使用方法有:
--1.修改表并行
alter table 表名稱 parallel;
--2.查詢設定并行度(即:執行緒數)
select /*+ parallel(table_name) */* from table_name ;
select /*+ parallel(t,8) */ * from table_name t;
select /*+ parallel(8) */ * from table_name t;
select /*+ parallel */ * from table_name t;
uj5u.com熱心網友回復:
高并發插入最常見的問題:主鍵遞增,主鍵索引分裂爭用——將主鍵索引調整為磁區hash全域索引,具體磁區數可參考最高并發數,如果主鍵上不存在范圍掃描,可以將該索引進一步調整為反向索引;遞增主鍵因為可能由sequence提供,所以序列上可能也會發生爭用,調整sequence cache可以一定程度上緩減這種爭用。
當然還有很多其他原因會導致并發插入的性能問題,需要更多資訊,比如插入時候的等待事件,甚至是插入時間段的AWR報告,以作進一步診斷。
uj5u.com熱心網友回復:
另外,默認情況下,Oracle的絕大多數操作都是通過buffer cache,資料快取區的。uj5u.com熱心網友回復:
你好,我在多執行緒向同一張表插入時,每條執行緒批量插入40萬條資料,會出現鎖表的現象啊。會導致有的執行緒操作不執行啊。
錯誤提示:ORA-00054: 資源正忙, 但指定以 NOWAIT 方式獲取資源, 或者超時失效 。
想請教您一下。
uj5u.com熱心網友回復:
也是插入的時候報資源正忙?而不是插入的時候做其他DDL操作,比如創建索引、修改表結構什么的?另外insert陳述句是怎么寫的?本身有沒有打開并行DML,使用append提示等等?但即使是這樣,照理說也應該是等待,或者報出其他錯誤,而不是資源正忙才對。
uj5u.com熱心網友回復:
另外,查下表一級是否打開了parallel屬性,表上是否有位圖索引,咱們來玩猜猜猜吧
uj5u.com熱心網友回復:
另外,查下表一級是否打開了parallel屬性,表上是否有位圖索引,咱們來玩猜猜猜吧
public void BulkToDB(DataTable dt, string targetTable)
{
// lock (syncRoot)
{
string err = "大批量插入時產生錯誤";
OracleConnection conn = Connect("test", "test");
if (conn.State != ConnectionState.Open)
{ conn.Open(); }
OracleBulkCopy bulkCopy = new OracleBulkCopy(conn, OracleBulkCopyOptions.Default);
bulkCopy.BatchSize = pageSize;
bulkCopy.BulkCopyTimeout = 260;//260
bulkCopy.DestinationTableName = targetTable;
try
{
if (conn.State != ConnectionState.Open)
{
conn.Open();
}
// conn.Open();
if (dt != null && dt.Rows.Count != 0)
{
bulkCopy.WriteToServer(dt);
// m_OraTrans.Commit();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
// BulkToDB(dtt,targetTablee);
}
finally
{
conn.Close();
if (bulkCopy != null)
bulkCopy.Close();
}
}
就是用的這個ONP.NET ORACLE的批量插入方法。多執行緒呼叫他,你看,我上面要是加鎖讓執行緒排隊就沒事,不過就會執行緒爭奪資源,比單執行緒還慢
uj5u.com熱心網友回復:
另外,查下表一級是否打開了parallel屬性,表上是否有位圖索引,咱們來玩猜猜猜吧
我問了一下別人說同時往一張表里差,因為有事務隔離等級,肯定會鎖表的,是不是只能單執行緒插入啊?
uj5u.com熱心網友回復:
另外,查下表一級是否打開了parallel屬性,表上是否有位圖索引,咱們來玩猜猜猜吧
public void BulkToDB(DataTable dt, string targetTable)
{
// lock (syncRoot)
{
string err = "大批量插入時產生錯誤";
OracleConnection conn = Connect("test", "test");
if (conn.State != ConnectionState.Open)
{ conn.Open(); }
OracleBulkCopy bulkCopy = new OracleBulkCopy(conn, OracleBulkCopyOptions.Default);
bulkCopy.BatchSize = pageSize;
bulkCopy.BulkCopyTimeout = 260;//260
bulkCopy.DestinationTableName = targetTable;
try
{
if (conn.State != ConnectionState.Open)
{
conn.Open();
}
// conn.Open();
if (dt != null && dt.Rows.Count != 0)
{
bulkCopy.WriteToServer(dt);
// m_OraTrans.Commit();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
// BulkToDB(dtt,targetTablee);
}
finally
{
conn.Close();
if (bulkCopy != null)
bulkCopy.Close();
}
}
就是用的這個ONP.NET ORACLE的批量插入方法。多執行緒呼叫他,你看,我上面要是加鎖讓執行緒排隊就沒事,不過就會執行緒爭奪資源,比單執行緒還慢
我本來想看的是SQL……比單執行緒慢是正常的,無論什么樣的系統,并發總是有拐點的,而且你每批次插入幾十萬資料,爭用會更明顯,但總體是要比單條插入效率高的,你少開幾個并發試試。
另外,順澩正忙報錯的是啥情況下報的?
uj5u.com熱心網友回復:
另外,查下表一級是否打開了parallel屬性,表上是否有位圖索引,咱們來玩猜猜猜吧
public void BulkToDB(DataTable dt, string targetTable)
{
// lock (syncRoot)
{
string err = "大批量插入時產生錯誤";
OracleConnection conn = Connect("test", "test");
if (conn.State != ConnectionState.Open)
{ conn.Open(); }
OracleBulkCopy bulkCopy = new OracleBulkCopy(conn, OracleBulkCopyOptions.Default);
bulkCopy.BatchSize = pageSize;
bulkCopy.BulkCopyTimeout = 260;//260
bulkCopy.DestinationTableName = targetTable;
try
{
if (conn.State != ConnectionState.Open)
{
conn.Open();
}
// conn.Open();
if (dt != null && dt.Rows.Count != 0)
{
bulkCopy.WriteToServer(dt);
// m_OraTrans.Commit();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
// BulkToDB(dtt,targetTablee);
}
finally
{
conn.Close();
if (bulkCopy != null)
bulkCopy.Close();
}
}
就是用的這個ONP.NET ORACLE的批量插入方法。多執行緒呼叫他,你看,我上面要是加鎖讓執行緒排隊就沒事,不過就會執行緒爭奪資源,比單執行緒還慢
我本來想看的是SQL……
比單執行緒慢是正常的,無論什么樣的系統,并發總是有拐點的,而且你每批次插入幾十萬資料,爭用會更明顯,但總體是要比單條插入效率高的,你少開幾個并發試試。
另外,順澩正忙報錯的是啥情況下報的?
Oracle.DataAccess.Client.OracleException ORA-00604: 遞回 SQL 級別 1 出現錯誤
ORA-00054: 資源正忙, 但指定以 NOWAIT 方式獲取資源, 或者超時失效 在 Oracle.DataAccess.Client.OracleException.HandleErrorHelper(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object src, String procedure, Boolean bCheck)
在 Oracle.DataAccess.Client.OracleException.HandleError(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, Object src)
在 Oracle.DataAccess.Client.OracleBulkCopy.PerformBulkCopy()
在 Oracle.DataAccess.Client.OracleBulkCopy.WriteDataSourceToServer()
在 Oracle.DataAccess.Client.OracleBulkCopy.WriteToServer(DataTable table, DataRowState rowState)
在 Oracle.DataAccess.Client.OracleBulkCopy.WriteToServer(DataTable table)
在 ConsoleApp7.CopyDataUtil.BulkToDB(DataTable dt, String targetTable) 位置 D:\WPF\ConsoleApp7\ConsoleApp7\CopyDataUtil.cs:行號 207
uj5u.com熱心網友回復:
另外,查下表一級是否打開了parallel屬性,表上是否有位圖索引,咱們來玩猜猜猜吧
public void BulkToDB(DataTable dt, string targetTable)
{
// lock (syncRoot)
{
string err = "大批量插入時產生錯誤";
OracleConnection conn = Connect("test", "test");
if (conn.State != ConnectionState.Open)
{ conn.Open(); }
OracleBulkCopy bulkCopy = new OracleBulkCopy(conn, OracleBulkCopyOptions.Default);
bulkCopy.BatchSize = pageSize;
bulkCopy.BulkCopyTimeout = 260;//260
bulkCopy.DestinationTableName = targetTable;
try
{
if (conn.State != ConnectionState.Open)
{
conn.Open();
}
// conn.Open();
if (dt != null && dt.Rows.Count != 0)
{
bulkCopy.WriteToServer(dt);
// m_OraTrans.Commit();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
// BulkToDB(dtt,targetTablee);
}
finally
{
conn.Close();
if (bulkCopy != null)
bulkCopy.Close();
}
}
就是用的這個ONP.NET ORACLE的批量插入方法。多執行緒呼叫他,你看,我上面要是加鎖讓執行緒排隊就沒事,不過就會執行緒爭奪資源,比單執行緒還慢
我本來想看的是SQL……
比單執行緒慢是正常的,無論什么樣的系統,并發總是有拐點的,而且你每批次插入幾十萬資料,爭用會更明顯,但總體是要比單條插入效率高的,你少開幾個并發試試。
另外,順澩正忙報錯的是啥情況下報的?
Oracle.DataAccess.Client.OracleException ORA-00604: 遞回 SQL 級別 1 出現錯誤
ORA-00054: 資源正忙, 但指定以 NOWAIT 方式獲取資源, 或者超時失效 在 Oracle.DataAccess.Client.OracleException.HandleErrorHelper(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object src, String procedure, Boolean bCheck)
在 Oracle.DataAccess.Client.OracleException.HandleError(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, Object src)
在 Oracle.DataAccess.Client.OracleBulkCopy.PerformBulkCopy()
在 Oracle.DataAccess.Client.OracleBulkCopy.WriteDataSourceToServer()
在 Oracle.DataAccess.Client.OracleBulkCopy.WriteToServer(DataTable table, DataRowState rowState)
在 Oracle.DataAccess.Client.OracleBulkCopy.WriteToServer(DataTable table)
在 ConsoleApp7.CopyDataUtil.BulkToDB(DataTable dt, String targetTable) 位置 D:\WPF\ConsoleApp7\ConsoleApp7\CopyDataUtil.cs:行號 207
我們公司現在就是單執行緒順序插入嘛,一次插入10萬左右,現在想要插入更快,我就想著多執行緒一起插入可不可以
uj5u.com熱心網友回復:
另外,查下表一級是否打開了parallel屬性,表上是否有位圖索引,咱們來玩猜猜猜吧
public void BulkToDB(DataTable dt, string targetTable)
{
// lock (syncRoot)
{
string err = "大批量插入時產生錯誤";
OracleConnection conn = Connect("test", "test");
if (conn.State != ConnectionState.Open)
{ conn.Open(); }
OracleBulkCopy bulkCopy = new OracleBulkCopy(conn, OracleBulkCopyOptions.Default);
bulkCopy.BatchSize = pageSize;
bulkCopy.BulkCopyTimeout = 260;//260
bulkCopy.DestinationTableName = targetTable;
try
{
if (conn.State != ConnectionState.Open)
{
conn.Open();
}
// conn.Open();
if (dt != null && dt.Rows.Count != 0)
{
bulkCopy.WriteToServer(dt);
// m_OraTrans.Commit();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
// BulkToDB(dtt,targetTablee);
}
finally
{
conn.Close();
if (bulkCopy != null)
bulkCopy.Close();
}
}
就是用的這個ONP.NET ORACLE的批量插入方法。多執行緒呼叫他,你看,我上面要是加鎖讓執行緒排隊就沒事,不過就會執行緒爭奪資源,比單執行緒還慢
我本來想看的是SQL……
比單執行緒慢是正常的,無論什么樣的系統,并發總是有拐點的,而且你每批次插入幾十萬資料,爭用會更明顯,但總體是要比單條插入效率高的,你少開幾個并發試試。
另外,順澩正忙報錯的是啥情況下報的?
Oracle.DataAccess.Client.OracleException ORA-00604: 遞回 SQL 級別 1 出現錯誤
ORA-00054: 資源正忙, 但指定以 NOWAIT 方式獲取資源, 或者超時失效 在 Oracle.DataAccess.Client.OracleException.HandleErrorHelper(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object src, String procedure, Boolean bCheck)
在 Oracle.DataAccess.Client.OracleException.HandleError(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, Object src)
在 Oracle.DataAccess.Client.OracleBulkCopy.PerformBulkCopy()
在 Oracle.DataAccess.Client.OracleBulkCopy.WriteDataSourceToServer()
在 Oracle.DataAccess.Client.OracleBulkCopy.WriteToServer(DataTable table, DataRowState rowState)
在 Oracle.DataAccess.Client.OracleBulkCopy.WriteToServer(DataTable table)
在 ConsoleApp7.CopyDataUtil.BulkToDB(DataTable dt, String targetTable) 位置 D:\WPF\ConsoleApp7\ConsoleApp7\CopyDataUtil.cs:行號 207
我們公司現在就是單執行緒順序插入嘛,一次插入10萬左右,現在想要插入更快,我就想著多執行緒一起插入可不可以
我是從資料源多執行緒批量匯出,這樣讀取快,然后想著多執行緒批量匯入
uj5u.com熱心網友回復:
多執行緒當然可以,但是執行緒數肯定不是可以無限上漲的,也許你得找找這個拐點,看來報資源正忙不是一下子就報的,而是執行時間長了之后再報的,那么可能還是一些非高級佇列鎖的爭用,如果想找找是否還有優化的余地,最好能有精確的問題時段的AWR報告uj5u.com熱心網友回復:
多執行緒當然可以,但是執行緒數肯定不是可以無限上漲的,也許你得找找這個拐點,看來報資源正忙不是一下子就報的,而是執行時間長了之后再報的,那么可能還是一些非高級佇列鎖的爭用,如果想找找是否還有優化的余地,最好能有精確的問題時段的AWR報告
如果獲取AWR報告有困難,那么可以在程式執行的時候,查下v$session.event欄位,看看插入的那些執行緒都在經歷一些什么等待,多次查詢,看看會不會有什么變化
uj5u.com熱心網友回復:
就是我多線執行緒批量讀取,然后每一個讀取的執行緒讀到,就立刻開一個寫的執行緒去寫多執行緒當然可以,但是執行緒數肯定不是可以無限上漲的,也許你得找找這個拐點,看來報資源正忙不是一下子就報的,而是執行時間長了之后再報的,那么可能還是一些非高級佇列鎖的爭用,如果想找找是否還有優化的余地,最好能有精確的問題時段的AWR報告
好的,那我試試吧,謝謝啦
uj5u.com熱心網友回復:
采用分表模式,一個執行緒操作一個表。轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/28118.html
標籤:開發
上一篇:如何用crystal ball做IPO valuation
下一篇:sqlplus執行腳本時出現錯誤
