2012-02-10 83 views
2

我們需要將存儲在SQL Server表中的所有記錄編入索引(在ASP.NET中)。該表在每行中都有大約2M個記錄(nvarchar)數據。從SQL Server中選擇百萬條記錄

是否可以一次取出所有記錄,因爲我們需要索引它們(用於搜索)?另一種選擇是什麼(我想避免分頁)?

注意:我沒有顯示這些記錄,只需要一個一個地去做這些記錄,這樣我就可以通過後臺線程爲它們編制索引。

我是否需要爲我的查詢設置任何超時時間?如果是,如果我正在從ASP.NET頁面運行查詢,那麼設置較長超時的最有效方法是什麼?

+0

抓取它們,你的意思是'select * from table'?是的,你可以做到這一點,然後你從sql中逐行讀取它們。避免將它們都放在記憶中,然後採取行動。 – Aristos 2012-02-10 23:31:36

+0

'索引'他們如何,爲了什麼目的?我假設你不是指像SQL索引那樣,因爲你通常只是告訴數據庫管理者構建它認爲它需要的任何索引...... – 2012-02-10 23:32:08

+0

@ X-Zero我認爲海報意味着從clob字段和用於在另一個表中搜索關鍵字aka store的「索引」。 – 2012-02-10 23:33:40

回答

0

我不認爲一個頁面是一個好的地方,不管。應該有一個不同的過程或程序來做到這一點。在一個相關的說明可能像http://incubator.apache.org/lucene.net/會幫助你嗎?

0

可以一次提取所有記錄,因爲我們需要爲它們編制索引 (用於搜索)嗎?另一種選擇是什麼(我想避免分頁)?

內存管理問題/性能問題

你可以面對系統內存溢出異常的你帶來2百萬的記錄 正如你將保持在數據集中的所有這些記錄和數據集存儲情況將在RAM中。


我是否需要設置任何長期超時爲我的查詢?如果是,如果我正在從ASP.NET頁面運行 查詢,那麼 最有效的方法是設置更長的超時時間?

using (System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand()) 
{ 
    cmd.CommandTimeout = 0; 
} 

建議

  1. 這是更好地從數據庫級別篩選出的記錄...
  2. 從數據庫中獲取的所有記錄,並將其保存在一個文件中。訪問該文件進行任何中間操作。
1

如果我需要這樣的東西,只要從數據庫端考慮它,我可能會將它導出到一個文件。然後該文件可以很容易地移動。移動大數據集對所有參與者來說都是巨大的痛苦。您可以在批處理命令中使用SSIS,sqlcmd甚至bcp來完成它。

然後,你只需要擔心你在應用程序端做了什麼,不用擔心在導出數據庫時鎖定了所有的數據。

0

您在提取轉換加載(ETL)中描述的內容。有2個選項我所知道的:

  1. SSIS這是SQL Server的一部分
  2. Rhino.ETL

我喜歡Rhino.Etl因爲它comletely C#語言編寫,可以在創建腳本Boo,測試和編寫ET​​L過程要容易得多。並且該庫的目的是處理大量數據,因此內存管理是內置的。

最後一點:儘管asp.net可能是啓動索引過程的入口,但我不會在因爲它可能需要幾分鐘或幾小時,這取決於記錄和處理的數量。

取而代之的是有asp.net作爲觸發後臺任務來處理記錄的切入點。理想情況下,完全獨立於asp.net,以避免任何超時或關閉問題。

0

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