Linq to sql 如何加快linq to sql函数的速度?

Linq to sql 如何加快linq to sql函数的速度?,linq-to-sql,optimization,Linq To Sql,Optimization,我有一个函数(称为“powersearch”,讽刺的是!),它在一堆(~5)字段中搜索一组字符串。 单词作为一个字符串输入,并用空格分隔。 某些字段可以具有精确匹配,其他字段应该具有“contains” (为布莱维蒂剪下) (耗时3626毫秒) 审核注销(3673毫秒) 执行sp_重置_连接(0毫秒) 审核登录 exec sp_executesql N' SELECT COUNT(*) AS [value] FROM [dbo].[CLR] AS [t0] INNER JOIN [dbo].[C

我有一个函数(称为“powersearch”,讽刺的是!),它在一堆(~5)字段中搜索一组字符串。 单词作为一个字符串输入,并用空格分隔。
某些字段可以具有精确匹配,其他字段应该具有“contains”

(为布莱维蒂剪下)

(耗时3626毫秒) 审核注销(3673毫秒) 执行sp_重置_连接(0毫秒) 审核登录

exec sp_executesql N'
SELECT COUNT(*) AS [value]
FROM [dbo].[CLR] AS [t0]
INNER JOIN [dbo].[CO] AS [t1] ON [t1].[CO_ID] = [t0].[CO_ID]
WHERE 
    ([t1].[LONG_NM] LIKE @p0)
    OR ([t0].[EUR_STK_CD] LIKE @p1)
    OR (EXISTS(
        SELECT NULL AS [EMPTY]
        FROM [dbo].[PAINT_CD] AS [t2]
        WHERE ([t2].[PAINT_CD] LIKE @p2)
            AND ([t2].[CLR_ID] = [t0].[CLR_ID])
            AND ([t2].[CUSTOM_ID] = [t0].[CUSTOM_ID])
        )
    )OR (EXISTS(
        SELECT NULL AS [EMPTY]
        FROM [dbo].[CLR_NM] AS [t3]
        WHERE ([t3].[CLR_NM] LIKE @p3)
            AND ([t3].[CLR_ID] = [t0].[CLR_ID])
            AND ([t3].[CUSTOM_ID] = [t0].[CUSTOM_ID])
        )
    ) OR (EXISTS(
        SELECT NULL AS [EMPTY]
        FROM [dbo].[CO_MODL] AS [t4]
        INNER JOIN [dbo].[MODL] AS [t5] ON [t5].[MODL_ID] = [t4].[MODL_ID]
        WHERE ([t5].[MODL_NM] = @p4)
            AND ([t4].[CO_ID] = [t1].[CO_ID])
        )
    )
',N'@p0 varchar(10),@p1 varchar(10),@p2 varchar(10),@p3 varchar(10),@p4 varchar(8)',@p0='%mercedes%',@p1='%mercedes%',@p2='%mercedes%',@p3='%mercedes%',@p4='mercedes'
exec sp_executesql N'
SELECT TOP (30) 
[t0].[CLR_ID] AS [Id],
[t0].[CUSTOM_ID] AS [CustomId],
[t0].[CO_ID] AS [CompanyId], 
[t0].[EUR_STK_CD] AS [StockCode], 
[t0].[SPCL_USE_CD] AS [UseCode], 
[t0].[EFF_IND] AS [EffectIndicator]
FROM [dbo].[CLR] AS [t0]
INNER JOIN [dbo].[CO] AS [t1] ON [t1].[CO_ID] = [t0].[CO_ID]
WHERE 
    ([t1].[LONG_NM] LIKE @p0)
    OR ([t0].[EUR_STK_CD] LIKE @p1)
    OR (EXISTS(
        SELECT NULL AS [EMPTY]
        FROM [dbo].[PAINT_CD] AS [t2]
        WHERE ([t2].[PAINT_CD] LIKE @p2)
            AND ([t2].[CLR_ID] = [t0].[CLR_ID])
            AND ([t2].[CUSTOM_ID] = [t0].[CUSTOM_ID])
        )
    )
    OR (EXISTS(
        SELECT NULL AS [EMPTY]
        FROM [dbo].[CLR_NM] AS [t3]
        WHERE ([t3].[CLR_NM] LIKE @p3)
            AND ([t3].[CLR_ID] = [t0].[CLR_ID])
            AND ([t3].[CUSTOM_ID] = [t0].[CUSTOM_ID])
        )
    )
    OR (EXISTS(
        SELECT NULL AS [EMPTY]
        FROM [dbo].[CO_MODL] AS [t4]
        INNER JOIN [dbo].[MODL] AS [t5] ON [t5].[MODL_ID] = [t4].[MODL_ID]
        WHERE ([t5].[MODL_NM] = @p4)
            AND ([t4].[CO_ID] = [t1].[CO_ID])
        )
    )'
,N'@p0 varchar(10),@p1 varchar(10),@p2 varchar(10),@p3 varchar(10),@p4 varchar(8)',@p0='%mercedes%',@p1='%mercedes%',@p2='%mercedes%',@p3='%mercedes%',@p4='mercedes'
(耗时3368毫秒)


遗憾的是,数据库结构不在我的控制之下。它来自美国,出于兼容性原因,必须保持完全相同的格式。尽管大多数重要字段确实已编制索引,但它们在(不必要的)聚集主键中编制索引。对此,我无能为力。

好吧,让我们来详细分析一下——您首先感兴趣的测试用例是一个非年度的,所以我们所能做的就是:

q = q.Where(c => c.Company.Name.Contains(myKey)
            || c.StockCode.Contains(myKey)
            || c.PaintCodes.Any(p => p.Code.Contains(myKey))
            || c.Names.Any(n => n.Label.Contains(myKey))
            || c.Company.CompanyModels.Any(m => m.Model.Name.Equals(myKey))
我说得对吗?如果是这样,SQL看起来像什么?在SQL分析器中执行SQL语句需要多长时间?探查器说执行计划是什么样子的?所有适当的列都有索引吗?

使用编译的查询

如果不这样做,您将损失高达5-10倍的性能,因为LINQ to SQL必须在每次调用查询时从查询生成SQL

当您在LINQtoSQL中使用非常量时,情况会变得更糟,因为获取它们的值非常慢

这假设您已经有索引和sane DB模式


顺便说一句,我不是在开5-10倍的玩笑。

谢谢。是的,我认为这是一个很好的起点。我会更新OP来回答你的问题。这不是linq 2 sql,boris。对不起。我不知道这是怎么发生的。我的意思是修改标题,在linq和sql之间添加一个空格(它是linqtosql)。我的脑子一定在别的地方。也就是说,为什么你对标题的命名这么有弹性呢?因为恰当的标题名称可以提供更好的谷歌搜索结果,IMHO,尽管我承认“to”是一个可能无关紧要的流行语。也许只是我的OC,对不起,没问题。你可能是对的,搜索更好。很高兴我们能像正常人一样解决这个小问题,而不必走极端。另外:“OC”?我的方法有大约12个可选字段,其中powersearch键只有一个。我检查每个字段,如果该字段已填写,则添加另一个where子句。在这种情况下,编译后的查询场景仍然合理吗?
q = q.Where(c => c.Company.Name.Contains(myKey)
            || c.StockCode.Contains(myKey)
            || c.PaintCodes.Any(p => p.Code.Contains(myKey))
            || c.Names.Any(n => n.Label.Contains(myKey))
            || c.Company.CompanyModels.Any(m => m.Model.Name.Equals(myKey))