在Azure上,我遇到了复杂的EF6查询的SQL性能问题。环境被配置为弹性池。在开发领域,由于查询计划的生成,经常通过CPU的使用来达到eDTU的限制。
应用程序是相当通用的,因此EF查询非常复杂,但是在查询的核心部分通常有一个包含IN子句的子查询。
SELECT Id FROM Event E WHERE E.Name IN (@p__linq__1, @p__linq__2, @p__linq__3)
或
SELECT Id FROM Event E WHERE E.Name IN (@p__linq__4, @p__linq__5)
尽管查询的其余部分是相同的,但是会生成新的SQL查询计划,因为文本由于参数的数量不同而不同。
以前,在另一个项目中,我通过在JOIN而不是WHERE子句中使用TVP来增加计划重用。
SELECT Id FROM Event E INNER JOIN @p_tvp_strings T ON E.Name = T.[Value]
我想不出如何在EF中用IQueryable的方式来完成这个任务。
我已经尝试过创建DataTable并将其解析为参数,但是context.Database.SqlQuery不返回IQueryable。它立即执行命令。
var nameArray = new string[]
{
"Bob", "Fred", "Bill",
};
var nameTable = CreateDataTable(nameArray);
var parameter = new SqlParameter("tvp", nameTable);
parameter.SqlDbType = SqlDbType.Structured;
parameter.TypeName = "StringSet";
var names = context.Database.SqlQuery<string>("SELECT [Value] FROM @tvp", parameter).AsQueryable();
var people = context.People.Where(p => names.Contains(p.Name)).ToList();
不幸的是,这会产生两个查询。
declare @p3 dbo.StringSet
insert into @p3 values(N'Bob')
insert into @p3 values(N'Fred')
insert into @p3 values(N'Bill')
exec sp_executesql N'SELECT [Value] FROM @tvp',N'@tvp [StringSet] READONLY',@tvp=@p3
SELECT
[Extent1].[Id] AS [Id],
[Extent1].[Name] AS [Name],
[Extent1].[Title] AS [Title],
[Extent1].[Age] AS [Age]
FROM
[dbo].[People] AS [Extent1]
WHERE
[Extent1].[Name] IN (N'Bill', N'Bob', N'Fred')
在使用EF时,有人知道如何在WHERE子句中使用TVP吗?
发布于 2018-06-13 11:05:40
从SQL Server 2016+和Azure开始,引入了QueryStore功能来监视性能。它提供了对查询计划选择和性能的深入了解。
它还提供了一个部队执行计划功能,这在这里可能有帮助。
它不是跟踪事件或扩展事件的完全替代,但是随着它从一个版本发展到另一个版本,我们可能会在SQL Server的未来版本中获得一个功能齐全的查询存储。查询存储的主要流程
- Query Store is not active for new databases by default.
- You cannot enable the query store for the master or `tempdb` database.
- Available DMV [`sys.database_query_store_options`](https://docs.microsoft.com/en-us/sql/relational-databases/system-catalog-views/sys-database-query-store-options-transact-sql) (Transact-SQL)
- **Query Plan Store:** Persisting the execution plan information and it is accountable for capturing all information that is related to query compilation.
- **Runtime Stats Store:** Persisting the execution statistics information and it is probably the most frequently updated store. These statistics represent query execution data.
- **Query Wait Stats Store:** Persisting and capturing wait statistics information.
注:查询等待数据存储仅在SQLServer 2017+中可用
https://stackoverflow.com/questions/-100004873
复制相似问题