如何优化这个 Nhibernate 查询(835ms)
我有来自 NHibernate Profiler 的查询
var temp = from x in ActiveRecordLinq.AsQueryable<Circuits>()
where x.User_Created == false
orderby x.Description
select x;
查询时长
-仅数据库:7ms
-总计:835ms
生成的查询:
SELECT this_.Circuit_ID as Circuit1_35_0_,
this_.[Description] as column2_35_0_,
this_.[User_Created] as column3_35_0_
FROM dbo.Circuit this_
WHERE this_.[User_Created] = 0 /* @p0 */
ORDER BY this_.[Description] asc
这似乎是一个非常简单的查询。它返回 6821 行。我用它来填充下拉列表。
提前致谢
I have this query
var temp = from x in ActiveRecordLinq.AsQueryable<Circuits>()
where x.User_Created == false
orderby x.Description
select x;
From NHibernate Profiler
Query duration
-Database only: 7ms
-Total: 835ms
The query generated:
SELECT this_.Circuit_ID as Circuit1_35_0_,
this_.[Description] as column2_35_0_,
this_.[User_Created] as column3_35_0_
FROM dbo.Circuit this_
WHERE this_.[User_Created] = 0 /* @p0 */
ORDER BY this_.[Description] asc
It seems like a pretty straightforward query. It returns 6821 rows. All I'm using this for is to populate a dropdownlist.
Thanks in advance
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
好的,如果您坚持 7k(我真的相信您应该停止重新思考您的设计...但是...),您可以尝试执行 HQL 查询来仅选择您需要的字段对象,而不是查询对象本身。
根据您编写的查询,nHibernate 正在从数据库加载数据,正如您所注意到的,这发生得非常快。但是,基于您编写的 Linq 查询,它正在初始化、填充并返回 7k Circuit 对象。这可能需要一段时间......
并且由于在这种情况下您实际上并没有以任何有意义的方式使用“对象”(只是下拉列表的文本和值对),您实际上不需要 nHibernate 来构建对象。
尝试更改代码以仅使用 HQL 或 LinqToNHibernate 返回文本/值对。
HQL 看起来像这样:
我知道你也可以使用 LinqToNhibernate 来做到这一点,我只是手头没有任何快速示例。
Ok, if you insist on the 7k (I REALLY believe you should stop to rethink your design... but...), you could try doing an HQL query to just select the fields you need from the object, instead of querying for the objects themselves.
With the query you have written, nHibernate is loading the data from the database which occurs pretty quickly as you have noted. But THEN based on the Linq query you have written it is initializing, populating and returning 7k Circuit objects. which is probably taking it a while...
And since you aren't actually using the "object" in any meaningful way in this case (just a text and value pair for the dropdown) you really don't need nHibernate to build the objects.
Try changing your code to just return the text/value pair with HQL or LinqToNHibernate.
the HQL would look something like this:
I know you can do this with LinqToNhibernate as well, I just don't have any quick examples at hand.
等等...您要将近 7000 个项目放入下拉列表中?我的理解正确吗?
如果是这样,是否可以使用带有ajax或类似设计的依赖下拉列表?
如果这是在网络上,您可能正在查看一个相对较大的页面,需要向下传输到客户端计算机,因此优化 NH 查询可能是一个过早的优化......
Wait... you are putting nearly 7k items in a dropdown list? Am I understanding that correctly?
If so, would it be possible to use dependent dropdown lists with ajax or some similar design?
If this is on the web, you are likely looking at a relatively large page that needs to be transmitted down to a client computer, so optimizing the NH query may be a premature optimization...
下拉列表中的 7k 条目不利于用户体验。由于您已经按描述订购,我假设您的用户已经(至少部分)知道他们想要选择的内容。所以给出完整的列表实际上是在阻碍用户。
既然您问自动完成器是什么,
请想象一个用户输入多个字符的输入字段。当用户输入他想要的内容时,就会触发查询。该字符串参数将用于进一步限制结果集的大小。
所以你的查询实现类似于这个伪代码:
查询的实际实现以及你是否决定实现'%foo%'或'foo%'等,这是你的决定。
用户体验将简化为在输入字段中写入“foo”,并且结果将仅获取用户将在其上选择他想要的内容的相关电路。如果结果集仍然太大,用户可以将“b”添加到已经输入的“foo”中,形成“foob”,再次触发查询,返回更有限的结果集。
当你在谷歌上输入时,它会即时给你建议,这是一个自动完成器实现
7k entries on a dropdown list is bad for the user experience. Since you are already ordering by Description i assume the your users already know (at least partially) what they want to select. So giving a full list is actually hindering the user.
Since you are asking what an autocompleter is
imagine an input field where the user types a number of characters. When the user types what he wants, then the query will fire. This string parameter will be used to further limit down the size of the result set.
so your query implementation is something like this pseudocode:
The actual implementation on both the query as well as if you decide to implement '%foo%' or 'foo%' etc it's your decision.
The user experience will be reduced to writing 'foo' in the input field and the results will only fetch the relevant
Circuits
on which the user will select what he wants. If the result set is still too large the user can add 'b' to the already typed 'foo' making a 'foob' where again the query fires again returning an even more limited result set.When you type at google and it gives you suggestions on the fly its an autocompleter implementation