根据动态比较查找匹配的实体

Nat*_*ing 5 sql-server asp.net-web-api entity-framework-core

我不确定这个主题是否真的有意义,但我不确定如何说出来.这是设置:我有一个Item,有很多ItemLogic,每个都有一个Field.Item例如,每个ItemLogic实体都有25个实体.逻辑确定是否Item匹配表单中的给定输入.例如,Field X has a value greater than AField Y has a value equal to B等每个25场.

在当前版本的应用程序中,查询并循环所有相关实体,返回所有ItemLogic所在的第一个匹配项true.它有点贵,但代码简单,而且从来没有那么多项目要看.到现在.

现在,该应用需要过滤3000个项目才能找到匹配项.上一个查询至少有两个连接,在我们的SQL实例上大约需要45秒.这太长了.

存储过程看起来很自然,但这里有一个问题:数据对于每组Items都是动态的,它以字符串值的形式出现,并且通常需要被转换为不同的类型(DateTime或int最常见)来执行实际的比较,一些逻辑被忽略而不是比较.这是存储过程中的大量额外开销,至少它是如何打击我的.

或者,我可以对数据进行分块,但这对于试图匹配集合中最后一个项目的可怜人来说并没有太大的节省.

有什么方法可以加速比赛?

架构和一些示例数据:

CREATE TABLE [dbo].[Items](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](255) NOT NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

CREATE TABLE [dbo].[ItemLogic](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [ItemId] [int] NOT NULL,
    [FieldId] [int] NOT NULL,
    [Value] [nvarchar](max) NULL,
    [Comparison] [int] NOT NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

CREATE TABLE [dbo].[Fields](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Value] [nvarchar](max) NOT NULL,
    [Type] [int] NOT NULL,
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

INSERT INTO [dbo].[Fields] (Value, Type) VALUES ('abc', 0), ('def', 0), ('123', 1)

INSERT INTO [dbo].[Items] (Name) VALUES ('Item 1'), ('Item 2'), ('Item 3')

INSERT INTO [dbo].[ItemLogic] (ItemId, FieldId, Value, Comparison) VALUES (1, 1, 'xyz', 1), (1, 2, 'qrs', 1), (1, 3, '200', 0), (2, 1, 'abc', 1), (2, 2, 'xyz', 1), (2, 3, '123', 2), (3, 1, 'abc', 1), (3, 2, 'def', 1), (3, 2, '100', 0)
Run Code Online (Sandbox Code Playgroud)

对于该Comparison字段,它是枚举匹配:0 =大于,1 =等于,2 =忽略.对于该Type字段,它是枚举匹配:0 =字符串,1 = int.

上述匹配的预期结果应该Item 3是返回的.