Giữa linq to sql và store procedure cái nào thực thi nhanh hơn đối với số lượng dữ liệu lớn

Linq to sql và store procedure cái nào nhanh hơn ?

Chào mọi người , mình có một thắc mắc mong mọi người giải đáp giúp mình

Mình có làm demo về web asp.net mvc tìm kiếm và phân trang dữ liệu . (với dữ liệu khoảng hơn 100000 dòng)

Cách 1 : mình sử dụng phân trang bằng toPageList của mvc . Danh sách mình trả về mình viết bằng linq thuần và mình trả ra một IQueryable ,sau đó đổ dữ liệu ra view

Cách 2 : mình custom phân trang bằng tay , không sử dụng toPageList . Mình viết một store procedure phân trang sẵn trong sql và gọi nó bằng linq ,sau đó đổ dữ liệu ra view

Mình test thử cả 2 trường hợp thì mình thấy sử dụng toPageList trả ra một IQueryable nhanh hơn việc gọi store procedure đã phân trang sẵn trong sql . Mình không hiểu tại sao mình đã phân trang sẵn trong sql mà vẫn chậm hơn so với việc gọi linq trực tiếp , vì mình thấy mọi người hay nói gọi store sẽ trả dữ liệu nhanh hơn khi gọi linq . Mình có tham khảo một số trang trên mạng ,cả trang của microsoft cũng phân trang với dữ liệu lớn cũng gọi store .Vậy cái nào mới đúng nếu dùng với số lượng dữ liệu lớn

2 Likes

Chào Long, cách đây 6 năm mình viết website cho CiOne thì mình cũng dùng ASP MVC (giờ qua Nodejs rồi) và cũng đã từng test như bạn. Kết quả tương tự như bạn là Linq sẽ cho tốc độ nhanh hơn. Mình là 1 tín đồ của việc làm store procedure nhưng sau này được nhiều expert khuyến khích chuyển qua dùng Linq bởi có 1 số lý do sau:

  1. Không phụ thuộc vào hệ quản trị cơ sở dữ liệu. Tầng quản lý cớ sở dữ liệu hãy để app làm, và .NET cũng có tầng đó, gọi là Data Access đúng không nào? Sau này có move qua hệ quản trị cơ sở dữ liệu khác cũng khỏi lo.

  2. Về tốc độ, cái này mình cũng thắc mắc như bạn thôi nhưng theo mình nghĩ thì Entity Framework nó có cơ chế cache và xử lý giúp mình hết rồi. Có điều kiện thì bạn thử nghiên cứu framework đó thì chắc sẽ có câu trả lời cho bạn. Chúc bạn sớm đào sâu được vấn đề này.

Mong rằng vài ý chia sẻ cá nhân nhưng có ích cho Long nhé.

3 Likes

Dữ liệu nó đẩy lên cache lại chả nhanh.
nếu 1 dòng là 1kb -> 100000 dòng ~100mb, đẩy lên cache vô tư… thử dữ liệu với >2 tỉ record xem thê nào. viết store để xử lý vẫn tốt hơn.

3 Likes

Chào Ca, mình đồng ý với bạn và cũng xin đưa thêm 1 vài ý cá nhân dựa trên kinh nghiệm của 1 người trong team củ đang làm hệ thống chính phủ của Singapore. Dưới đây là ý kiến của anh ta (Hoàng Bảo Duy)

Đồng ý với bạn ấy là 1-2ty record thi store procedure sẽ nhanh hơn. Nhưng với điều kiện là sp phải được optimize . Việc optimize 1 sp là không đơn giản phải có tool hỗ trợ để đánh giá performance tool cho enterprice, mà những tool này thì khá mắc. Thường job đó sẽ là backend db to db nên không ai dùng entity framework. Caching là một vấn dề khác, tuỳ theo mục đích và cache ở đâu. Load 1-2ty lên memory cách là chết server ngay. Thường caching người ta sẽ dùng documment db và document distribution caching. Cái này available trên azure cho enterprise subscription. On-prime thì dùng couch base

Còn entity framework là cho các application that help to generate and optimize the sql query automatically
Load data len application không bao giờ select * from table cả mà ngừoi ta sẽ paging nó và entity framework hỗ trợ paging rất tốt

Mong rằng ý kiến này hữu ích tới các bạn đang quan tâm.

2 Likes

Chính xác đúng là thường backend db to db :stuck_out_tongue: và thường chạy batch job để xử lý phân tích dữ liệu nhỏ hơn đẩy vào hệ thống khác, hệ thống này có thể sử dụng ORM để đẩy dữ liệu sau khi phân tích lên cho người dùng xem. Một cái lợi của viết procedure(wrap trong package) là có thể gọi nó ở shell script hay các ngôn ngữ khác.
Bên mình trước cũng có dùng distribution catch vơi halzecast (java).

3 Likes

Cám ơn mọi người , mình đã phần nào hiểu được vấn đề rồi . Vì mình nghe anh pm trong công ty nói là phải sử dụng store để làm chứ hạn chế dùng entity framework , dùng entity framework chỉ để gọi store thôi . Mình cũng đã tìm hiểu thêm thì đúng là phải tối ưu hóa câu lệnh store thì tốc độ mới nhanh được

ah quên nữa như bạn @Cione nói thì các expert khuyên nên dùng linq như những lý do mà bạn nêu lên . Mà anh pm trong công ty mình lại khuyến khích dùng store để phân trang .Bạn giải thích hộ mình với

Mình thì quan điểm ngược lại, nên hạn chế gọi Store:

  • Gọi Store đành rằng nhanh hơn, nhưng với LingQ đã hỗ trợ cache, thậm chí compiled statement … nên tốc độ không hề kém Store Proc.
  • Viết Store là viết business ở cả 2 nơi: code C# và code DB. Nhanh lúc đầu, nhưng sau maintain cực kỳ vất vả. Chỉ nên viết Store khi các business logic tương đối ổn định rồi và ít thay đổi.
2 Likes

Như bạn Ca nói thì việc sử dụng linq sẽ hỗ trợ cache nên tốc độ thực thi nhanh , nhưng giả sử có 1->2 tỷ record thì việc cache có thể làm chết server nên mình nghĩ việc dùng store vẫn tốt hơn

Việc query cache ở tầng Linq đâu phải là nó scan cả CSDL hay bảng và cache vào mem/hard-disk đâu bạn. Khi thực thi lần đầu, nó sẽ cache và lần sau nó lấy luôn ra kết quả mà không cần touch vào CSDL.

Với case của bạn, nếu query trả về 1->2 tỷ record thì kể cả dùng Proc. thì server vẫn chết như thường (dữ liệu collect quá lớn, gây tràn mem, … rồi send cái đống data đó qua net sẽ nghẽn mạng, … ngay cả việc đọc cái đống đata này dưới client cũng khiến client đi luôn ý chứ … Cứ thử tưởng tượng bạn mở 1 file 100GB bằng notepad xem).

Còn việc xóa cache của Linq thì quá đơn giản.
C1: Invalidate cái object tracking đi

DataContext dc = new DataContext();
Item item = dc.GetTable<Item>().FirstOrDefault();
if(item != null)
{
 item.Value = "New Value";
 dc.SubmitChanges(); //Updates Item
}

Cái này work arround để báo là dữ liệu đã thay đổi, Linq xóa cache trước. Còn tất nhiên, nếu bạn xóa data bằng tay thì dùng cái snippet này để xóa cache.

C2: Tạo 1 cái datacontext mới toe và dùng.

p/s: nói chung, việc bạn lo lắng cache gây ảnh hưởng về MEM thì proc cũng bị nhé. Còn vụ lo lắng cái object tracking đó làm sai data thì … trên production, đừng insert/update bằng tay ^^ Nếu thực hiện như vậy, phải invalidate nó bằng các snippet nhỏ hoặc restart lại app cho nó dùng Dbcontext mới, … hoặc set invalidate time nhỏ đi.

Một nhược điểm nữa của Proc là: rất khó làm unit test. Trước kia, mình làm 1 dự án, khách hàng họ maintain Proc. Đến lúc test, kết quả sai mà debug mãi không ra, hoá ra là Proc sai cho 1 case. Vì thế, dự án nào đi theo TDD thì không nên dùng Proc, test unit không ổn.

1 Like

Mình mới chỉ dừng ở mức làm phần mềm môn học, toàn phải vừa tìm tòi vừa gánh team cho bọn kia có thời gian đi tán gái :)) Nên không bao giờ dùng sp vì nhiều lúc thay đổi cấu trúc csdl liên tục XD

Chào Long, mình xin trả lời cho bạn như sau:

Thường các PM không mạnh về technical mà thế mạnh của họ là quản lý project sao cho kịp tiến đô, rồi về phân công con người, tính chi phí,… Những người mạnh về technical là TA, đó là mình thấy sự phân biết rõ ràng ở các tập đoàn lớn như CSC, Havarnash,… Nếu muốn dùng công nghệ gì đó cần phải có master về lĩnh vực đó. Entity Framework không đơn giản chỉ là Data Access layer mà nó còn hỗ trợ giải quyết một đống thức khác liên quan đến connectivity giữa db và application. Develop một application bao giờ cũng tính đến 2 yếu tố là flexible và scalable. Entity Framework rất mạnh cho vấn đề này. Đặc biết nếu muốn develop những microservice that compatible with cloud then Entity Framework is useful.

Bạn muốn biết khi nào nên và không nên dùng EF thì xem thêm ở đây nhé. http://www.entityframeworktutorial.net/what-is-entityframework.aspx

Mong rằng câu trả lời đáp ứng được câu hỏi của bạn.

2 Likes

Bạn gừi cho PM của bạn link này để anh ta tham khảo nhé

1 Like

Mọi người cho em hỏi với những Câu Lệnh SQL tương đối phức tạp. kiểu như một cái báo cáo chẳng hạn. truy vấn lồng nhau, …
Thì LINQ có đáp ứng đc không ạ. Hay lại dùng LINQ gọi SP?

Mình nghĩ đối với những truy vấn phức tạp thì nên gọi store

Vậy Store đó mình phải vào SQL để viết à bạn? hay viết trực tiếp trong code first luôn để lúc deploy đỡ phải vào SQL?

Bạn viết trong sql rồi gọi store trong linq á

1 Like
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?