首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在EF6查询中使用TVP?(而不是存储的proc)

如何在EF6查询中使用TVP?(而不是存储的proc)
EN

Stack Overflow用户
提问于 2018-06-13 01:34:39
回答 1查看 0关注 0票数 0

在Azure上,我遇到了复杂的EF6查询的SQL性能问题。环境被配置为弹性池。在开发领域,由于查询计划的生成,经常通过CPU的使用来达到eDTU的限制。

应用程序是相当通用的,因此EF查询非常复杂,但是在查询的核心部分通常有一个包含IN子句的子查询。

代码语言:txt
复制
SELECT Id FROM Event E WHERE E.Name IN (@p__linq__1, @p__linq__2, @p__linq__3)

代码语言:txt
复制
SELECT Id FROM Event E WHERE E.Name IN (@p__linq__4, @p__linq__5)

尽管查询的其余部分是相同的,但是会生成新的SQL查询计划,因为文本由于参数的数量不同而不同。

以前,在另一个项目中,我通过在JOIN而不是WHERE子句中使用TVP来增加计划重用。

代码语言:txt
复制
SELECT Id FROM Event E INNER JOIN @p_tvp_strings T ON E.Name = T.[Value]

我想不出如何在EF中用IQueryable的方式来完成这个任务。

我已经尝试过创建DataTable并将其解析为参数,但是context.Database.SqlQuery不返回IQueryable。它立即执行命令。

代码语言:txt
复制
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();

不幸的是,这会产生两个查询。

代码语言:txt
复制
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吗?

EN

回答 1

Stack Overflow用户

发布于 2018-06-13 11:05:40

从SQL Server 2016+和Azure开始,引入了QueryStore功能来监视性能。它提供了对查询计划选择和性能的深入了解。

它还提供了一个部队执行计划功能,这在这里可能有帮助。

它不是跟踪事件或扩展事件的完全替代,但是随着它从一个版本发展到另一个版本,我们可能会在SQL Server的未来版本中获得一个功能齐全的查询存储。查询存储的主要流程

  1. SQLServer现有组件通过使用查询存储管理器与查询存储进行交互。
  2. 查询存储管理器确定应该使用哪个存储库,然后将执行传递给该存储区(计划或运行时统计或查询等待统计)
    • 计划存储-持久化执行计划信息
    • 运行时统计存储-持久执行统计信息
    • 查询等待数据存储-持久化等待统计信息。
  3. 计划、运行时统计和等待存储使用查询存储作为SQLServer的扩展。

  1. 启用查询存储查询存储在服务器上的数据库级别上工作。
代码语言:txt
复制
- 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)

  1. 在查询存储中收集信息:我们使用QueryStoreDMV(DataManagementViews)从这三个商店收集所有可用的信息。
代码语言:txt
复制
- **Query Plan Store:**  Persisting the execution plan information and it is accountable for capturing all information that is related to query compilation.
代码语言:txt
复制
- **Runtime Stats Store:**  Persisting the execution statistics information and it is probably the most frequently updated store. These statistics represent query execution data.
代码语言:txt
复制
- **Query Wait Stats Store:**  Persisting and capturing wait statistics information.

注:查询等待数据存储仅在SQLServer 2017+中可用

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/-100004873

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档