我最近继承了一些Oracle / Fluent NHibernate / .NET MVC项目,但存在一些重大的性能问题。我对NHibernate并不熟悉。
进行优化我得出的结论是,以前的程序员使用ORM并不鼓励高效的设计,我想问一下效率设计应该是什么样子。
简化让我们考虑3个表的简单模型:
Readers: (1000)
id : int
FirstName : nvarchar(50)
SecondName : nvarchar(50)
Books: (1000)
id : int
Title : nvarchar(50)
Relation: (50000)
book_id : int
reader_id : int
任务是显示报告:
FirstName,SecondName,Title 对于所有关系。
我遇到的是控制器操作,或多或少有以下代码:
var reportResult = session.Query<Relation>().Select(x =>
new ReportModel(){
FirstName = x.Reader.FirstName,
SecondName = x.Reader.SecondName,
Title = x.Book.Title
}).ToList();
return Ok(reportResult);
该代码导致每个报告请求从SQL向Web Server发送7 Mb数据,因为它已被翻译为如下所示:
SELECT R.FirstName,R.SecondName,B.Title FROM Readers R JOIN Relations RL ON
RL.reader_id = R.id JOIN Books B ON B.id = RL.book_id
我所做的是将LINQ查询拆分为3,转换为3个请求:
SELECT R.id,R.FirstName,R.SecondName FROM Readers R WHERE R.id IN
(SELECT DISTINCT reader_id FROM Relations RL)
SELECT B.id,B.Title FROM Books B WHERE B.id IN
(SELECT DISTINCT book_id FROM Relations RL)
SELECT RL.book_id,R.reader_id FROM Relations
这导致限制SQL Server和Web Server之间的流量3次,因此报告加载时间(因为我发送每个关系只有两个int而不是3个varchars)。当然我需要在Web服务器上加入它们而不是在SQL Server上(其他几行linq代码)。
我的问题是:
这种情况有什么出路?
是否有原始的linq查询被ORM引擎解析为三个高效查询而不是一个效率不高的问题,或者我应该将Fluent NHibernate视为花哨的LINQ to SQL翻译器?