分批处理您的记录。你将会遇到两个主要问题。 (1)您需要索引所有现有记录。 (2)您需要更新索引,添加,更新或删除记录。它可能听起来像eaiser只是放弃索引并重新创建它,但应尽可能避免它。以下是以批处理10,000条记录从AdventureWorks2008R2
数据库处理[Production].[TransactionHistory]
的示例。它不会将所有记录加载到内存中。我的本地计算机上的输出产生Processed 113443 records in 00:00:00.2282294
。显然,这不考虑每个记录的远程计算机和处理时间。
class Program
{
private static string ConnectionString
{
get { return ConfigurationManager.ConnectionStrings["db"].ConnectionString; }
}
static void Main(string[] args)
{
int recordCount = 0;
int lastId = -1;
bool done = false;
Stopwatch timer = Stopwatch.StartNew();
do
{
done = true;
IEnumerable<TransactionHistory> transactionDataRecords = GetTransactions(lastId, 10000);
foreach (TransactionHistory transactionHistory in transactionDataRecords)
{
lastId = transactionHistory.TransactionId;
done = false;
recordCount++;
}
} while (!done);
timer.Stop();
Console.WriteLine("Processed {0} records in {1}", recordCount, timer.Elapsed);
}
/// Get a new open connection
private static SqlConnection GetOpenConnection()
{
SqlConnection connection = new SqlConnection(ConnectionString);
connection.Open();
return connection;
}
private static IEnumerable<TransactionHistory> GetTransactions(int lastTransactionId, int count)
{
const string sql = "SELECT TOP(@count) [TransactionID],[TransactionDate],[TransactionType] FROM [Production].[TransactionHistory] WHERE [TransactionID] > @LastTransactionId ORDER BY [TransactionID]";
return GetData<TransactionHistory>((connection) =>
{
SqlCommand command = new SqlCommand(sql, connection);
command.Parameters.AddWithValue("@count", count);
command.Parameters.AddWithValue("@LastTransactionId", lastTransactionId);
return command;
}, DataRecordToTransactionHistory);
}
// funtion to convert a data record to the TransactionHistory object
private static TransactionHistory DataRecordToTransactionHistory(IDataRecord record)
{
TransactionHistory transactionHistory = new TransactionHistory();
transactionHistory.TransactionId = record.GetInt32(0);
transactionHistory.TransactionDate = record.GetDateTime(1);
transactionHistory.TransactionType = record.GetString(2);
return transactionHistory;
}
private static IEnumerable<T> GetData<T>(Func<SqlConnection, SqlCommand> commandBuilder, Func<IDataRecord, T> dataFunc)
{
using (SqlConnection connection = GetOpenConnection())
{
using (SqlCommand command = commandBuilder(connection))
{
using (IDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
T record = dataFunc(reader);
yield return record;
}
}
}
}
}
}
public class TransactionHistory
{
public int TransactionId { get; set; }
public DateTime TransactionDate { get; set; }
public string TransactionType { get; set; }
}
抓取它们,你的意思是'select * from table'?是的,你可以做到这一点,然后你从sql中逐行读取它们。避免将它们都放在记忆中,然后采取行动。 – Aristos 2012-02-10 23:31:36
'索引'他们如何,为了什么目的?我假设你不是指像SQL索引那样,因为你通常只是告诉数据库管理者构建它认为它需要的任何索引...... – 2012-02-10 23:32:08
@ X-Zero我认为海报意味着从clob字段和用于在另一个表中搜索关键字aka store的“索引”。 – 2012-02-10 23:33:40