c# 从 SQL Server 2014 检索大量数据的更好方法?
c# Better way to retrieve large bulks of data from SQL Server 2014?
上下文:我检索大量数据以在 ElasticSearch 集群中为它们编制索引(它没有-sql 格式)。
我通过根据当前分析的 table 与我的 bulk_size
相比有多少行来确定我需要使用 for 循环创建多少委托,然后执行它们来执行此操作执行以下代码。
我用offset-fetch
。 tb
代表当前table,我的当前bulk_size
是5000。
我的代码如下所示:
using (SqlConnection db = new SqlConnection(tb.Conn))
{
int offset = i * BULK_SIZE;
int nextRows = BULK_SIZE;
string queryParams = string.Format(" ORDER BY {0} OFFSET {1} ROWS FETCH NEXT {2} ROWS ONLY", tb.FirstPK(), offset, nextRows);
string dataQuery = string.Format("SELECT * FROM dbo.{0} {1}", tb.TableName, queryParams);
try
{
db.Open();
object[,] bulk = new object[BULK_SIZE, 2];//[data[], id]
int n = 0;
object[] values;
using (SqlDataReader reader = new SqlCommand(dataQuery, db).ExecuteReader())
{
while (reader.Read())
{
string docId = string.Empty;
foreach (string pk in tb.PKeys)
{
docId += reader[pk].ToString() + '_';
}
docId = docId.Substring(0, docId.Length - 1);//delete last '_'
values = new object[reader.FieldCount];
reader.GetValues(values);
bulk[n, 0] = values;
bulk[n, 1] = docId;
n++;
}
reader.Close();
}
db.Close();
if (IsMemoryAvailable())//Waits for other delegates to finish
{
DataUpload(bulk, tb, mapper);
}
}
catch (Exception e)
{
Console.WriteLine(e.Message); Console.WriteLine(e.StackTrace); Console.ReadLine();
//throw e;
}
}
有更好的方法吗?
然后我得到批量,将其插入数组并在另一个任务中处理该批量。
问题是 SQL 服务器的内存不断增加(缓存太大),在后期批量提取中我得到超时异常等;它变慢了。
解决方案是创建一个仅包含主键的临时 table,然后使用连接从 table 和临时 table 来回查询。
这比 offset-fetch
的内存效率更高,而且速度更快。
上下文:我检索大量数据以在 ElasticSearch 集群中为它们编制索引(它没有-sql 格式)。
我通过根据当前分析的 table 与我的 bulk_size
相比有多少行来确定我需要使用 for 循环创建多少委托,然后执行它们来执行此操作执行以下代码。
我用offset-fetch
。 tb
代表当前table,我的当前bulk_size
是5000。
我的代码如下所示:
using (SqlConnection db = new SqlConnection(tb.Conn))
{
int offset = i * BULK_SIZE;
int nextRows = BULK_SIZE;
string queryParams = string.Format(" ORDER BY {0} OFFSET {1} ROWS FETCH NEXT {2} ROWS ONLY", tb.FirstPK(), offset, nextRows);
string dataQuery = string.Format("SELECT * FROM dbo.{0} {1}", tb.TableName, queryParams);
try
{
db.Open();
object[,] bulk = new object[BULK_SIZE, 2];//[data[], id]
int n = 0;
object[] values;
using (SqlDataReader reader = new SqlCommand(dataQuery, db).ExecuteReader())
{
while (reader.Read())
{
string docId = string.Empty;
foreach (string pk in tb.PKeys)
{
docId += reader[pk].ToString() + '_';
}
docId = docId.Substring(0, docId.Length - 1);//delete last '_'
values = new object[reader.FieldCount];
reader.GetValues(values);
bulk[n, 0] = values;
bulk[n, 1] = docId;
n++;
}
reader.Close();
}
db.Close();
if (IsMemoryAvailable())//Waits for other delegates to finish
{
DataUpload(bulk, tb, mapper);
}
}
catch (Exception e)
{
Console.WriteLine(e.Message); Console.WriteLine(e.StackTrace); Console.ReadLine();
//throw e;
}
}
有更好的方法吗?
然后我得到批量,将其插入数组并在另一个任务中处理该批量。
问题是 SQL 服务器的内存不断增加(缓存太大),在后期批量提取中我得到超时异常等;它变慢了。
解决方案是创建一个仅包含主键的临时 table,然后使用连接从 table 和临时 table 来回查询。
这比 offset-fetch
的内存效率更高,而且速度更快。