LINQ to SQL 查询优化
主要从事java工作,对LINQ很陌生,所以我需要一些关于此查询性能的建议。我有3个表,
1. Products --> ProductID | Name | Price | VendorID
2. Category --> CategoryID | Label
3. SubCategory--> SubCategoryID | Label | ParentID
4. Product_SubCategory_Mapping--> ProductID | SubCategoryID
5. Vendor --> VendorID | VendorName
我想从产品表中选择所有产品及其任何给定子类别的供应商。以下查询应该正常工作吗?或者需要什么优化?
var list = (from p in Products
join cat in Product_SubCategory_Mapping
on p.UserId equals cat.UserId
join sub in SubCategories
on cat.SubCategoryId equals sub.SubCategoryId
where sub.CategoryId == 19 && CustomFunction(p.ID) > 100
select new { p, p.Vendor, trend = CustomFunction(p.ID) })
.Skip((pageNum - 1) * pageSize)
.Take(pageSize);
我将创建一个与查询结果匹配的自定义类。
- 在这种情况下,创建视图/存储过程是更好的方案吗?
- 可以命名 CustomFunction(p.ID)>100 以便函数不会被调用两次吗?它是数据库中的自定义函数。
- 对于分页,Skip 和 take 表现良好吗?
Have been working mainly on java and new to LINQ so I need some suggestion regarding performance of this query .I have 3 tables
1. Products --> ProductID | Name | Price | VendorID
2. Category --> CategoryID | Label
3. SubCategory--> SubCategoryID | Label | ParentID
4. Product_SubCategory_Mapping--> ProductID | SubCategoryID
5. Vendor --> VendorID | VendorName
I want to select all products from product table along with its Vendors for any given subcategory .Should following query work fine ? Or it needs any optimization ?
var list = (from p in Products
join cat in Product_SubCategory_Mapping
on p.UserId equals cat.UserId
join sub in SubCategories
on cat.SubCategoryId equals sub.SubCategoryId
where sub.CategoryId == 19 && CustomFunction(p.ID) > 100
select new { p, p.Vendor, trend = CustomFunction(p.ID) })
.Skip((pageNum - 1) * pageSize)
.Take(pageSize);
I will be creating a custom class that will match result of query .
- Is creating a view/Stored procedure a better scenario in case like this ?
- Can CustomFunction(p.ID)>100 be named so function is not called twice ? Its a custom function in Database.
- For paging will Skip and take perform well ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的方向是正确的,但 LINQ to SQL 无法理解
CustomFunction()
,因此您需要先使用AsEnumerable()
切换到 LINQ to Objects可以调用它。您还可以使用let
捕获CustomFunction()
的结果一次,以便在查询中的其他地方使用:更新: 要回答列出的问题:
let
。IQueryable
上的Skip()
和Take()
(如上面的listFromSql
)将转换为适当的 SQL,限制通过线路发送的结果集。IEnumerable<>
上的Skip()
和Take()
只是枚举序列以获取请求的结果,但对完整结果进行操作从 SQL 返回的集合。You're on the right track, but LINQ to SQL won't understand
CustomFunction()
so you'll need to switch to LINQ to Objects withAsEnumerable()
before you can call it. You can also uselet
to capture the result ofCustomFunction()
once for use elsewhere in the query:Update: To answer your listed questions:
let
above.Skip()
andTake()
on anIQueryable<>
(likelistFromSql
above) will translate into the appropriate SQL, limiting the result set sent across the wire.Skip()
andTake()
on anIEnumerable<>
just enumerate the sequence to get the requested results, but operate on the full result set returned from SQL.由于 CustomFunction 是数据库中的 ScalarFunction,因此 LINQ to SQL 应该能够有效地评估它。您可能希望使用 LET 提取一次值,但请检查生成的 SQL 和查询执行计划,看看它是否提供了任何改进,或者 SQL Server 是否在内部自动进行了适当的优化。
如果元素之间存在关联,您可能需要使用它们而不是联接。它不会(太多)改变生成的查询,但可能更易于维护,因为连接是由模型中建立的关联抽象出来的。
Since CustomFunction is a ScalarFunction in the database, LINQ to SQL should be able to evaulate it effectively. You may want to use LET to pull the value once, but check the generated SQL and the Query Execution Plan to see if it offers any improvement or if SQL Server automatically makes the appropriate optimizations internally.
If there are associations between your elements, you may want to use them rather than joins. It doesn't change the generated query (much), but may be a bit more maintainable since the joins are abstracted out by the associations established in the model.