分批處理您的記錄。你將會遇到兩個主要問題。 (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