如何解决在 SQL Server 2012 SP 2 中过滤数据,最好的方法是什么
我正在使用 EF Core 2.2,我会在感觉舒适时更新到 5。
目前我正在尝试寻找任何在大表格中搜索的来源,我有很好的建模表格 1 个主表格和一些表格,用于性别、地址、上次购买、评论产品等功能。
- EF 在这方面真的很慢,所以我使用了 dapper 并调用了一个存储的 程序。
- 我想过滤大约 5.5GB(470k 行,它是 要更大,31 列,7 个表,每个表 +15 列)。
- 我有 5 个不同的过滤器,它必须很快。因为程序 响应时间估计为 1 分钟
查询应该使用动态参数
我必须做这样的事情我尝试了一些不同的方法但仍然很慢。我有 5 个过滤器和 1 个日期声明。用户可以发送 5、4 或 3 个过滤器,也可以不发送。
where (SaOr.InsertDate between ISNULL(@StartDate,'1900-01-01') and ISNULL(DATEADD(DAY,1,@DueDate),@TOMORROW))
and (@ProductName is null or SaOrPr.Name like '%' + @ProductName + '%')
and (@PaymentType is null or LEN(@PaymentType)> LEN(REPLACE(@PaymentType,PaymentMethodId,'')) )
and (@Channel is null or LEN(@Channel)> LEN(REPLACE(@Channel,SaOr.ChannelId,'')))
and (@SalesType is null or LEN(@SalesType)> LEN(REPLACE(@SalesType,SalesOrderTypeId,'')) )
and (@Salesstatus is null or LEN(@Salesstatus)> LEN(REPLACE(@Salesstatus,StatusId,'')) )
- 我尝试过的方法,没有“或”,但它比 1 慢。
where (SaOr.InsertDate between ISNULL(@StartDate,'1920-01-01') and ISNULL(DATEADD(DAY,@TOMORROW))
AND (SELECT CHARINDEX(ISNULL(ISNULL(@ProductName,SaOrPr.[Name]),' '),ISNULL(SaOrPr.[Name],' '))) >0
AND (SELECT CHARINDEX(ISNULL(CAST(PaymentMethodId AS VARCHAR(38)),ISNULL(ISNULL(@PaymentType,PaymentMethodId),' '))) >0
AND (SELECT CHARINDEX(ISNULL(CAST(SaOr.ChannelId AS VARCHAR(38)),ISNULL(ISNULL(@Channel,SaOr.ChannelId),' '))) >0
AND (SELECT CHARINDEX(ISNULL(CAST(SalesOrderTypeId AS VARCHAR(38)),ISNULL(ISNULL(@SalesType,SalesOrderTypeId),' '))) >0
AND (SELECT CHARINDEX(ISNULL(CAST(StatusId AS VARCHAR(38)),ISNULL(ISNULL(@Salesstatus,StatusId),' '))) >0
3.method 使用动态查询
declare @query varchar(max)= 'insert into #TmpResult
select
some fields
FROM #tmpSales SaOr
where ( FilteredCount between @pagination and @pagination + @PageSize - 1) '
+ CASE WHEN @PaymentType IS NOT NULL THEN
' AND LEN(@PaymentType)> LEN(REPLACE(@PaymentType,CONVERT(varchar(38),SaOr.PaymentMethodId),'''')) ' ELSE '' END
+ CASE WHEN @Channel IS NOT NULL THEN
' AND LEN(@Channel)> LEN(REPLACE(@Channel,'''')) ' ELSE '' END
+ CASE WHEN @SalesType IS NOT NULL THEN
' AND LEN(@SalesType)> LEN(REPLACE(@SalesType,SaOr.SalesOrderTypeId),'''')) ' ELSE '' END
+ CASE WHEN @Salesstatus IS NOT NULL THEN
' AND LEN(@Salesstatus)> LEN(REPLACE(@Salesstatus,SaOr.StatusId),'''')) ' ELSE '' END
+ ' OPTION (RECOMPILE);';
解决方法
您需要执行几个步骤。
- 将表分成 2 或 3 个部分,例如过滤产品和付款,然后插入 #Temptable 并应用 INNER 加入其他表,例如 Channel 并获取过滤后的数据 #Temptable2 THEN Join 2nd Temptable with Sales 和 SalesType
- 用于过滤的列,在所有列上创建索引。
如果您一次从所有表中获取数据并应用将一次过滤数百万条记录的过滤器。因此,如果您划分表格,则过滤器将应用于较少的记录。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。