Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/86.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
EF核心生成导致SQL Server超时的基本查询_Sql_Sql Server_Entity Framework_Entity Framework Core - Fatal编程技术网

EF核心生成导致SQL Server超时的基本查询

EF核心生成导致SQL Server超时的基本查询,sql,sql-server,entity-framework,entity-framework-core,Sql,Sql Server,Entity Framework,Entity Framework Core,对于一个看起来非常基本的用例,EntityFramework核心正在生成一个无限期运行的查询,最终超时 这是导致问题的一段代码: if (criteria.Filters.Contains(JobFilteringOptions.OnlyUnpaid)) query = query.Where(job => !job.IsPaid || job.ChildJobs.Any(childJob => !childJob.IsPaid)); 我立刻发现奇怪的是,相反的结果并没有引

对于一个看起来非常基本的用例,EntityFramework核心正在生成一个无限期运行的查询,最终超时

这是导致问题的一段代码:

if (criteria.Filters.Contains(JobFilteringOptions.OnlyUnpaid))
    query = query.Where(job => !job.IsPaid || job.ChildJobs.Any(childJob => !childJob.IsPaid));
我立刻发现奇怪的是,相反的结果并没有引起这个问题:

if (criteria.Filters.Contains(JobFilteringOptions.OnlyPaid))
    query = query.Where(job => job.IsPaid && job.ChildJobs.All(childJob => childJob.IsPaid));
我想我会非常聪明,稍微调整一下代码,使其更像第二个示例,但这也失败了!:

if (criteria.Filters.Contains(JobFilteringOptions.OnlyUnpaid))
    query = query.Where(job => !job.IsPaid || !job.ChildJobs.All(childJob => childJob.IsPaid));
我已经花了很多时间调试这个问题,最终跟踪到SQL Server本身

在调试过程中,我还尝试将SQL Server更新为最新版本,但没有成功

我查看了正在生成的SQL查询,将其切片,然后将其归结为最简单的示例:

SELECT
    *
FROM
    [Jobs] AS [ParentJob]
WHERE
    [ParentJob].[ParentJobId] IS NULL
AND
    ([ParentJob].[IsPaid] <> 1 OR EXISTS (SELECT 1 FROM [Jobs] AS [ChildJob] WHERE [ChildJob].[ParentJobId] = [ParentJob].[Id] AND [ChildJob].[IsPaid] <> 1))
ORDER BY [ParentJob].[Id]
OFFSET 0 ROWS
FETCH NEXT 31 ROWS ONLY;
菱形运算符更改为
=
等于运算符。这很有效

SELECT
    *
FROM
    [Jobs] AS [ParentJob]
WHERE
    [ParentJob].[ParentJobId] IS NULL
AND
    ([ParentJob].[IsPaid] = 0 OR EXISTS (SELECT 1 FROM [Jobs] AS [ChildJob] WHERE [ChildJob].[ParentJobId] = [ParentJob].[Id] AND [ChildJob].[IsPaid] = 0))
ORDER BY [ParentJob].[Id];
SELECT
    *
FROM
    [Jobs] AS [ParentJob]
WHERE
    [ParentJob].[ParentJobId] IS NULL
AND
    ([ParentJob].[IsPaid] = 0 OR EXISTS (SELECT 1 FROM [Jobs] AS [ChildJob] WHERE [ChildJob].[ParentJobId] = [ParentJob].[Id] AND [ChildJob].[IsPaid] = 0))
ORDER BY [ParentJob].[Id]
OFFSET 0 ROWS
FETCH NEXT 31 ROWS ONLY;
SELECT
    *
FROM
    [Jobs] AS [ParentJob]
WHERE
    [ParentJob].[ParentJobId] IS NULL
AND
    EXISTS (SELECT 1 FROM [Jobs] AS [ChildJob] WHERE [ChildJob].[ParentJobId] = [ParentJob].[Id] AND [ChildJob].[IsPaid] <> 1)
ORDER BY [ParentJob].[Id]
OFFSET 0 ROWS
FETCH NEXT 31 ROWS ONLY;
删除父作业上的
[ParentJob].[IsPaid]1
检查。这很有效

SELECT
    *
FROM
    [Jobs] AS [ParentJob]
WHERE
    [ParentJob].[ParentJobId] IS NULL
AND
    ([ParentJob].[IsPaid] = 0 OR EXISTS (SELECT 1 FROM [Jobs] AS [ChildJob] WHERE [ChildJob].[ParentJobId] = [ParentJob].[Id] AND [ChildJob].[IsPaid] = 0))
ORDER BY [ParentJob].[Id];
SELECT
    *
FROM
    [Jobs] AS [ParentJob]
WHERE
    [ParentJob].[ParentJobId] IS NULL
AND
    ([ParentJob].[IsPaid] = 0 OR EXISTS (SELECT 1 FROM [Jobs] AS [ChildJob] WHERE [ChildJob].[ParentJobId] = [ParentJob].[Id] AND [ChildJob].[IsPaid] = 0))
ORDER BY [ParentJob].[Id]
OFFSET 0 ROWS
FETCH NEXT 31 ROWS ONLY;
SELECT
    *
FROM
    [Jobs] AS [ParentJob]
WHERE
    [ParentJob].[ParentJobId] IS NULL
AND
    EXISTS (SELECT 1 FROM [Jobs] AS [ChildJob] WHERE [ChildJob].[ParentJobId] = [ParentJob].[Id] AND [ChildJob].[IsPaid] <> 1)
ORDER BY [ParentJob].[Id]
OFFSET 0 ROWS
FETCH NEXT 31 ROWS ONLY;
选择
*
从…起
[Jobs]作为[ParentJob]
哪里
[ParentJob]。[ParentJobId]为空
及
存在(从[Jobs]中选择1作为[ChildJob],其中[ChildJob].[ParentJobId]=[ParentJob].[Id]和[ChildJob].[IsPaid]1)
由[ParentJob]订购。[Id]
偏移0行
只取下31行;
我敢肯定,在我的薪酬等级之上的查询计划背后一定有某种东西在起作用。我希望有人能给我指出正确的方向

我需要找到一种方法使SQLServer不超时,或者使EF Core生成一个实际工作的查询


我不知道如何解决这个问题。请帮忙

job
表中是否有一行具有相同的
id
ParentJobId
列值?EF核心查询正是它应该的,因此您不应该在这里执行任何操作。它必须是db端的东西。您是否有非标准的附加索引?例如,如果使用EF Core为您创建db模型,则在
ParentJobId
上会有一个索引。但是您可能已经在
IsPaid
上创建了一个?在这两种情况下,最好用
(ParentJobId,IsPaid)
上的单个复合索引替换它/它们,因为它既可以服务于正常关系,也可以服务于类似的查询。没错,这解决了it jobBuilder.HasIndex(o=>新的{o.ParentJobId,o.IsPaid});鉴于IsPaid列是我唯一需要查询的关于这个孩子的列,希望这是我第一次也是最后一次遇到这个问题。为了记录在案,我已经在IsPaid上有了一个索引,但它对我没有任何好处。jobBuilder.HasIndex(o=>o.IsPaid);我不认为让索引保持原样有什么害处,是吗?每个索引都会对插入/更新/删除操作产生一些影响。还可能导致查询计划效率低下。您的表是分层的,PK/FK服务索引非常重要,最好由查询使用。例如,仅仅删除该索引也可以解决原始问题。总的来说,最好不要有不必要的索引。删除原始索引是我尝试的第一件事之一-没有骰子:)不过,这一点很重要,谢谢你的帮助!