Trang 1 / 2 12 LastLast
Hiển thị kết quả từ 1 đến 10 / 16
  1. #1
    Tham gia
    06-08-2009
    Bài viết
    27
    Like
    0
    Thanked 0 Times in 0 Posts

    DataSet với 1 lượng dữ liệu lớn

    nếu table của mình có cả chục triệu record thì nếu load hết lên dataset bỏ trên datagrid winform làm việc có hiệu quả không.

    mình biết ở bên asp.net / các web application thì có cơ chế phân trang, nhưng trên winform thì nên làm như thế nào đê xử lý 1 lượng dữ liệu quá lớn như vậy
    Quote Quote

  2. #2
    Tham gia
    20-02-2009
    Location
    Ninh Bình
    Bài viết
    567
    Like
    0
    Thanked 34 Times in 31 Posts
    Quote Được gửi bởi katatunix9x View Post
    nếu table của mình có cả chục triệu record thì nếu load hết lên dataset bỏ trên datagrid winform làm việc có hiệu quả không.

    mình biết ở bên asp.net / các web application thì có cơ chế phân trang, nhưng trên winform thì nên làm như thế nào đê xử lý 1 lượng dữ liệu quá lớn như vậy
    Đây là một câu hỏi mà bất cứ một lập trình gia nào cũng tự hỏi chính mình sau khi rời ghế nhà trường và thực sự bắt tay vào những lập trình thực dụng.

    Trước hết, hãy phân tích về số lượng của bộ nhớ. Một máy vi tính trung bình của những người xử dụng (không phải là máy chủ) chỉ có tối đa là 4GB RAM. Trên thực tế, chỉ thường là 2GB. Và đây là máy vi tính của những người làm việc tại Hoa Kỳ, máy của họ được thay đổi mỗi 2 năm, hoặc 3 năm.

    Hãy lấy con số 2GB làm căn bản. Với 2GB, sau khi đã trừ ra hết những phần mềm linh tinh lang tang, thì mỗi máy chỉ còn chưa tới 1GB. Và bộ phận quản lý bộ nhớ sẽ lấy ra từng 64K một để chứa những dữ liệu lấy từ CSDL ra.

    Một bảng có vài chục triệu records, thì chắc chắn là bộ nhớ còn lại không đủ để dự trữ. Nhưng Windows có bộ nhớ ảo (virtual memory) dùng để chứa dữ liệu, cho nên có khả năng đọc được hết vài chục triệu record. Tuy nhiên, bộ nhớ ảo chỉ là disk-space, cho nên, cái câu tự hỏi là, tại sao lại đọc dữ liệu từ CSDL được tồn trữ trong disk-space, để rồi lại viết trở vào disk qua hình thức bộ nhớ ảo?

    Vấn đề thứ hai. Tốc độ tối đa, trong những điều kiện tốt nhất, mà một phần mềm có thể đọc được dữ liệu từ một CSDL là 10 ngàn records một giây. Nhưng thông thường, chỉ đọc được vào khoảng từ 1 ngàn đến 2 ngàn record một giây. Vậy thì tốn bao nhiêu thời gian để có thể đọc ra hết vài chục triệu records? Mà trên phương diện hiển thị (UI), thì mỗi một giây là một ...khoảng thời gian bất tận (eternity) đối với người xử dụng. Dĩ nhiên, đọc tới đây, sẽ có nhiều người cho ý kiến rằng, khi đọc dược khoảng 1 trang, lập tức hiển thị liền, và số records còn lại sẽ được đọc từ từ ở một thread khác cho đến khi nào hết thì thôi (background processing). Việc này có thể làm được, nhưng kinh nghiệm cho biết, với tổng số records như thế, việc này thì khả khi, nhưng bất khả dụng, bởi vì Windows sẽ tốn rất nhiều thời gian để tráo đổi (swap) dữ liệu từ bộ nhớ chính qua bộ nhớ ảo. Disk-drive của bạn sẽ quay bất tận liên hồi.

    Thành thử ra, câu trả lời còn tuỳ thuộc rất nhiều vào cái bảng đó. Bảng đó cấu trúc như thế nào, có những cột gì. Người xử dụng thường (bao nhiêu phần trăm) sẽ muốn hiển thị những records nào, hoặc thường sẽ làm gì? Thay đổi record, tạo record mới, vân vân...

    Thí dụ như, cho một phần mềm kế toán, thì cái bảng lớn nhất, có thể có vài chục triệu records, chính là bảng dùng để chứa những transaction chi thu hàng ngày. Bảng này thường có transaction date, posted date. Và 90% là người xử dụng muốn nhìn thấy những transactions trong tuần lễ hiện tại, hoặc trong tháng hiện tại. Đặt trên căn bản này, người ta có thể chia record ra làm nhiều phần: chia theo năm, chia theo tháng, chia theo tuần, và chia theo ngày, để hiển thị những transactions theo cấu trúc như thế.

    Nếu không thể chia được như thế vì bảng không có đặt trên một căn bản cấu trúc nào, thì records sẽ được sort như thế nào? Và trên căn bản của sorting đó, có thể nào nhận dạng chính xác từng record hay không? Nếu nhận dạng chính xác được, thì có thể đọc mỗi lần 1000 records thôi. Khi NXD đi xuống hàng cuối cùng, thì đọc và bỏ vào gridview 1000 record kế tiếp. Cách này không đến nỗi dở, nhưng nếu NXD cứ tiếp tục đi xuống hoài, khi gridview đã cả trăm ngàn records trở lên, thì tốc độ lại giảm thiểu đi rất nhiều, cho nên cũng không phải là giải pháp tối ưu.

    Cách tốt nhất, theo kinh nghiệm "lâm sàng", là gridview chỉ nên có tối đa là 2 ngàn record, được chia là làm hai ...phần (sections). Khi NXD đi xuống quá phần 1500 records, thì 1000 records đầu tiên sẽ được xoá đi, và một background processing sẽ đọc tiếp 1000 records kế tiếp. Ngược lại cũng như thế. Khi NXD đi ngược lên, quá con số 1500 tính ở dưới lên, thì background process lại xóa 1000 records ở dưới, và lấy 1000 ở phía trên từ CSDL để đổ vào gridview. Dĩ nhiên, đây không phải là một việc dễ làm, vì nó đòi hỏi nhiều...thủ thuật không phu. Phải có background thread, phải chủ động để biết con chuột vừa mới được bấm ở đâu, NXD vừa bấm vào nút nào trên bàn phím. Tuy rằng không dễ, nhưng cũng không khó, vì tất cả những hàm của gridview đã có sẵn.

  3. #3
    Tham gia
    16-03-2008
    Bài viết
    17
    Like
    0
    Thanked 2 Times in 2 Posts
    Quá Hay. Cám ơn về bài viết của bạn !

  4. #4
    Tham gia
    18-02-2008
    Bài viết
    54
    Like
    0
    Thanked 0 Times in 0 Posts
    Quote Được gửi bởi katatunix9x View Post
    nếu table của mình có cả chục triệu record thì nếu load hết lên dataset bỏ trên datagrid winform làm việc có hiệu quả không.

    mình biết ở bên asp.net / các web application thì có cơ chế phân trang, nhưng trên winform thì nên làm như thế nào đê xử lý 1 lượng dữ liệu quá lớn như vậy
    - bạn có thể thêm các điều kiện lọc vào để lấy dữ liệu ra, càng nhiều điều kiện lọc càng tốt.ko ai lấy 1 phát từng ấy dòng ra cả.
    - hoặc là bạn có thể load từng phần, ví dụ load 10 sản phẩm / 1 trang. bạn cung cấp cho người dùng nút Next, Prv, nếu người dùng kích Next thì load tiếp 10 bản ghi tiếp theo, cứ như vậy ... cái này làm giống phân trang trong asp.net ấy.

  5. #5
    Tham gia
    03-03-2009
    Bài viết
    353
    Like
    0
    Thanked 1 Time in 1 Post
    chả ai load 1 lượng lớn dữ liệu lên dataset, thường load nhiều lắm là 1000 record.

    Chỉ load lên những dữ liệu nào cần thôi, chứ chẳng ai dùng hơn 1000 record trên 1 trang

  6. #6
    Tham gia
    02-05-2009
    Bài viết
    1
    Like
    0
    Thanked 0 Times in 0 Posts

    Ngạc nhiên reply sớm nhé!

    trong .net thường làm theo cơ chế DB-->DATASOURCE--->DATASET/DATATABLE--->APPLICATION.
    khi móc csdl từ DATASOURCE đổ lên DTSET/DTTABLE-Thì nó sẽ lưu ở đâu?
    (có ai từng đặt câu hỏi này chưa?)
    vay tại sao không dùng XML? ở đây.

  7. #7
    Tham gia
    09-10-2003
    Location
    HN
    Bài viết
    853
    Like
    0
    Thanked 6 Times in 6 Posts
    thế paging để làm jì ý nhở

    PS: còn nếu nói về việc tổng kiểm tra tính tồn kho vào cuối năm chẳng hạn. Mà trong đó có 1 đơn hàng nào đó vào ngày nào đó đã được chỉnh sửa. Thì việc tính toán dữ liệu lại khá đơn giản. Chẳng hạn tổng số sp của cty tui là 1000 chẳng hạn, thì tui sẽ chẳng ngại jì mà kô cache nó lại. Mỗi lần lấy đơn hàng lên có SP tui sẽ update lại thông tin cho SP này. Xử lý có thể chia ra thành từng block để tính.
    Trường cache thông tin Sp: ID, Name (có thể kô), TotalImport, TotalExport.

  8. #8
    Tham gia
    10-01-2008
    Bài viết
    29
    Like
    0
    Thanked 0 Times in 0 Posts
    Minh cũng thấy phân trang là cách tốt. Nếu bạn không muốn phức tạp như chạy background + vị trí chuột ... thì chỉ việc viết 2 button < > hoac << < combobox > >>. tùy vào page mà truyền xưống storeprocedure mà chạy và lấy dữ liệu lên. nên xài objectdatasource để uyển chuyển trong việc lấy dữ liệu, bind dữ liệu cũng nên bằng code.

  9. #9
    Tham gia
    05-05-2008
    Bài viết
    183
    Like
    0
    Thanked 8 Times in 6 Posts
    Làm việc với đống data như vậy cũng oải lắm.
    Nếu ko thích phân trang thì bạn có thể dùng Virtual mode của DataGridView (Winform). Cho phép bạn load dữ liệu theo kiểu lazy-load, chỉ load khi cần nhưng nhìn trên scrollbar thì có cảm giác như đang load hết lên vậy (thực chất nó chỉ load những record bạn nhìn thấy), còn chuyện cache data ra sao thì tùy vào strategy của bạn thôi.

    Tham khảo tại đây http://msdn.microsoft.com/en-us/library/ms171622.aspx

    [=========> Bổ sung bài viết <=========]

    Còn 1 việc nữa là khi thao tác với dữ liệu nhiều như vậy, nếu đang dùng MS SQL sever 2000+, bạn nên dùng OpenXML nhanh gấp mấy chục lần gọi từng câu Query hay sử dụng DataAdapter, hơn nữa Dataset của .NET cho phép bạn xuất ra XML có thể dùng để kết hợp với OpenXML.
    Được sửa bởi littleNeo lúc 16:50 ngày 30-10-2009 Reason: Bổ sung bài viết

  10. #10
    Tham gia
    30-06-2008
    Bài viết
    438
    Like
    0
    Thanked 8 Times in 8 Posts
    Tại sao không pagging từ CSDL rồi lấy ra 1 tập nhỏ. Application cũng làm được mà. Bạn làm thêm mấy cái button First, Last, Next, Privuos . Tại sao mình không ra 1 giải pháp để đơn giản hóa bài toán nhỉ. Đó mới là vấn đề

Trang 1 / 2 12 LastLast

Bookmarks

Quy định

  • Bạn không thể tạo chủ đề mới
  • Bạn không thể trả lời bài viết
  • Bạn không thể gửi file đính kèm
  • Bạn không thể sửa bài viết của mình
  •