2008-12-02 34 views
9

Điều nào sẽ nhanh hơn.Trình dữ liệu có nhanh hơn tập dữ liệu khi điền dữ liệu được không?

1) Looping một datareader và tạo ra một hàng tùy chỉnh và các cột dựa DataTable

2) Hoặc tạo ra một đối tượng DataAdapter dân cư và chỉ (.Fill) ing một DataTable.

Hiệu suất của một trình quản lý dữ liệu vẫn giữ đúng khi tạo động của một dữ liệu có thể định cấu hình được không?

Trả lời

9

DataAdapter sử dụng DataReader dưới mui xe để trải nghiệm của bạn có thể giống nhau.

Lợi ích của DataAdapter là bạn cắt ra rất nhiều mã cần bảo trì.

Cuộc tranh luận này là một chút của một vấn đề tôn giáo vì vậy chắc chắn nhìn xung quanh và quyết định những gì phù hợp nhất cho tình hình của bạn:

+0

Xem bài đăng của tôi: ít mã hơn sử dụng DataAdapter. –

3

Tôi không thể nói để điền vào một datatable mỗi nhưng sử dụng một bộ đọc dữ liệu là phương pháp đọc hiệu quả nhất.

+1

Tôi luôn tự hỏi liệu điều đó có phụ thuộc vào những gì chúng tôi làm với dữ liệu hay không. Vì DataReader dựa trên máy chủ cơ sở dữ liệu để đệm thông tin, do đó, trên một tập hợp kết quả lớn, nếu tính toán của chúng ta phức tạp, như xây dựng biểu đồ mạng, sẽ khó hơn với mỗi nút mới, nó sẽ làm tắc nghẽn database.true? – Haoest

7

Tùy chọn # 1 của bạn sẽ chậm hơn. Tuy nhiên, có một cách tốt hơn để chuyển đổi một datareader một DataTable vì thêm hàng tùy chỉnh bằng tay:

DataTable dt = new DataTable(); 

using (SqlConnection conn = GetOpenSqlConnection()) 
using (SqlCommand cmd = new SqlCommand("SQL Query here", conn) 
using (IDataReader rdr = cmd.ExecuteReader()) 
{ 
    dt.Load(rdr); 
} 

Tôi không thể bình luận về sự khác biệt giữa điều này và sử dụng .Fill().

+0

Cảm ơn! Tôi đã tìm kiếm cách tải một datatable từ một datareader vì tôi có một proc lưu trữ trả về nhiều bảng, nhưng tôi chỉ cần 'điền' một datatable từ một trong các bảng đầu ra. – Yoopergeek

1

Thật tuyệt khi có DataReader khi bạn cần ví dụ hiển thị tiến độ tải dữ liệu. Trong DataSet bạn không thể làm điều gì đó ở giữa tải dữ liệu.

Mặt khác, DataSet là đối tượng tất cả trong một. Vì vậy, DataSet chậm hơn nhiều. DataReader có thể cung cấp cho bạn tăng thêm ở những nơi trong mã của bạn nơi hoạt động dữ liệu rất chậm. Ở những nơi này, thay đổi nó từ DataSet thành DataReader. DataReader cũng mất ít không gian hơn trong bộ nhớ.

Tất nhiên phải mất nhiều thời gian hơn để viết mã DataReader tốt, nhưng nó đáng giá. Ví dụ: khi bạn chơi với hình ảnh hoặc nhạc được lấy từ cơ sở dữ liệu.

More on this topic in MSDN Magazine

2

Trình quản lý dữ liệu nhanh hơn. Và nếu bạn đang sử dụng 2.0+ bạn probablt thậm chí không phải sử dụng một datatable. Bạn có thể sử dụng danh sách chung của đối tượng của bạn.

+1

Tuyên bố của bạn từ năm 2008 giúp tôi vào cuối năm 2015 :) SqlDataAdapter và SqlDataReader mất 6,x phút để tải DataTable, nhưng Linq chỉ mất 1,7 giây để tải Danh sách (56460 Hàng). –

+0

@PalaniKumar: Bạn có thể vui lòng cho tôi biết rằng làm thế nào bạn sẽ trực tiếp tải kết quả thủ tục lưu trữ với danh sách bằng cách sử dụng trình đọc dữ liệu ?? –

+1

@Learning, tôi đã sử dụng EntityFramework để nhận được storedprocedure dưới dạng Danh sách đối tượng. Nếu bạn muốn chuyển đổi datareader thành danh sách thì hãy kiểm tra tại đây http: // stackoverflow.com/questions/1464883/how-can-i-dễ dàng chuyển đổi-datareader-to-listt –

11

Giả sử bạn thực sự muốn tất cả dữ liệu quay trở lại từ cơ sở dữ liệu, thời gian thực hiện tại cơ sở dữ liệu và trên mạng gần như chắc chắn làm giảm thời gian thực hiện để điền dữ liệu vào bộ nhớ. Có, trong một số trường hợp, bạn có thể tiết kiệm nhỏ bằng cách sử dụng DataReader - và đặc biệt nếu bạn muốn truyền dữ liệu, nó có thể hữu ích - nhưng nếu bạn thực sự cần tất cả, tôi sẽ đơn giản nhất mã.Nếu bạn tin rằng số liệu Số liệu dân số đang gây ra một vấn đề hiệu suất đáng kể, hãy cấu hình nó và rồi cố gắng cải thiện nó.

+0

+1 cho "tiểu sử". – Dan

1

Như với nhiều câu hỏi như thế này, câu trả lời là: phụ thuộc.

Nếu bạn không biết cấu trúc dữ liệu của mình ở phía trước và đang tạo TableAdapters một cách nhanh chóng thì DataTable động sẽ hiệu quả hơn. Có nhiều việc tạo mã liên quan đến việc tạo ra một TableAdapter.

Tuy nhiên, nếu bạn biết cấu trúc dữ liệu của mình ở phía trước thì câu hỏi sẽ trở thành, tôi cần bao nhiêu chức năng?

Nếu bạn cần triển khai CRUD đầy đủ thì có một số hiệu quả thu được bằng cách sử dụng TableAdapter thay vì tự viết tất cả mã CRUD đó. Ngoài ra, việc thực hiện TableAdapter là OK (không tuyệt vời). Nếu bạn cần một cái gì đó hiệu quả hơn sau đó bạn có thể tốt hơn bằng cách sử dụng nHibernate hoặc một số ORM khác.

Nếu bạn không cần triển khai CRUD đầy đủ (nghĩa là giải pháp chỉ đọc) và biết cấu trúc dữ liệu của bạn ở phía trước, thì bạn sẽ phải kiểm tra hiệu quả của việc thực thi chỉ đọc TableAdapter một DataTable được tạo động. Nếu tôi là một người cá cược tôi sẽ bỏ tiền của tôi vào việc thực hiện TableAdapter vì bạn liên kết dữ liệu một lần và đọc nó nhiều lần.

1

Đi theo là phương pháp tiếp cận một hàng một lần, chỉ chuyển tiếp, đọc dữ liệu tuần tự để bạn có được hồ sơ ngay sau khi được đọc khi được kết nối, sẽ là tốt nhất cho bộ nhớ và hiệu suất.

Điều đó nói rằng, giữa hai cách tiếp cận, tôi tìm thấy IDataAdapter.Fill nhanh hơn nhiều so với DataTable.Load. Tất nhiên điều đó phụ thuộc vào việc triển khai .. Dưới đây là một chuẩn mực giữa hai mà tôi được đăng here:

public DataTable Read1<T>(string query) where T : IDbConnection, new() 
{ 
    using (var conn = new T()) 
    { 
     using (var cmd = conn.CreateCommand()) 
     { 
      cmd.CommandText = query; 
      cmd.Connection.ConnectionString = _connectionString; 
      cmd.Connection.Open(); 
      var table = new DataTable(); 
      table.Load(cmd.ExecuteReader()); 
      return table; 
     } 
    } 
} 

public DataTable Read2<S, T>(string query) where S : IDbConnection, new() 
              where T : IDbDataAdapter, IDisposable, new() 
{ 
    using (var conn = new S()) 
    { 
     using (var da = new T()) 
     { 
      using (da.SelectCommand = conn.CreateCommand()) 
      { 
       da.SelectCommand.CommandText = query; 
       da.SelectCommand.Connection.ConnectionString = _connectionString; 
       DataSet ds = new DataSet(); //conn is opened by dataadapter 
       da.Fill(ds); 
       return ds.Tables[0]; 
      } 
     } 
    } 
} 

Cách tiếp cận thứ hai luôn luôn vượt trội so với lần đầu tiên.

Stopwatch sw = Stopwatch.StartNew(); 
DataTable dt = null; 
for (int i = 0; i < 100; i++) 
{ 
    dt = Read1<MySqlConnection>(query); // ~9800ms 
    dt = Read2<MySqlConnection, MySqlDataAdapter>(query); // ~2300ms 

    dt = Read1<SQLiteConnection>(query); // ~4000ms 
    dt = Read2<SQLiteConnection, SQLiteDataAdapter>(query); // ~2000ms 

    dt = Read1<SqlCeConnection>(query); // ~5700ms 
    dt = Read2<SqlCeConnection, SqlCeDataAdapter>(query); // ~5700ms 

    dt = Read1<SqlConnection>(query); // ~850ms 
    dt = Read2<SqlConnection, SqlDataAdapter>(query); // ~600ms 

    dt = Read1<VistaDBConnection>(query); // ~3900ms 
    dt = Read2<VistaDBConnection, VistaDBDataAdapter>(query); // ~3700ms 
} 
sw.Stop(); 
MessageBox.Show(sw.Elapsed.TotalMilliseconds.ToString()); 

Read1 trông tốt hơn trên đôi mắt, nhưng bộ chuyển đổi dữ liệu thực hiện tốt hơn (không phải để gây nhầm lẫn rằng một db vượt trội so với khác, các truy vấn đều khác nhau). Sự khác biệt giữa hai phụ thuộc vào truy vấn mặc dù. Lý do có thể là Load yêu cầu các ràng buộc khác nhau để kiểm tra hàng theo hàng from the documentation khi thêm hàng (phương thức của nó trên DataTable) trong khi Fill nằm trên DataAdapters được thiết kế chỉ để tạo nhanh DataTables.

Các vấn đề liên quan