在SQL Server 2012 SP 2中筛选数据的最佳方法是什么
我正在使用EF Core 2.2,当我感觉舒适时,我会更新到5 目前,我正试图在大表中寻找搜索源,我有很好的建模表1主表和一些功能表,如性别、地址、上次购买、已审核产品等在SQL Server 2012 SP 2中筛选数据的最佳方法是什么,sql,sql-server,database,entity-framework,dapper,Sql,Sql Server,Database,Entity Framework,Dapper,我正在使用EF Core 2.2,当我感觉舒适时,我会更新到5 目前,我正试图在大表中寻找搜索源,我有很好的建模表1主表和一些功能表,如性别、地址、上次购买、已审核产品等 EF在这方面真的很慢,所以我使用了dapper和调用存储 程序 我想过滤这个几乎5.5GB(470k行)的数据,它是 转到更大的,31列,7个表,每个表+15列) 我有5个不同的过滤器,它必须很快。因为程序 预计响应时间为1分钟 查询应使用动态参数 我必须这样做,我尝试了一些不同的方法,但仍然很慢。我有5个过滤器和1个日期
- EF在这方面真的很慢,所以我使用了dapper和调用存储 程序
- 我想过滤这个几乎5.5GB(470k行)的数据,它是 转到更大的,31列,7个表,每个表+15列)
- 我有5个不同的过滤器,它必须很快。因为程序 预计响应时间为1分钟
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,CONVERT(varchar(38),SaOr.ChannelId),'''')) ' ELSE '' END
+ CASE WHEN @SalesType IS NOT NULL THEN
' AND LEN(@SalesType)> LEN(REPLACE(@SalesType,CONVERT(varchar(38),SaOr.SalesOrderTypeId),'''')) ' ELSE '' END
+ CASE WHEN @SalesStatus IS NOT NULL THEN
' AND LEN(@SalesStatus)> LEN(REPLACE(@SalesStatus,CONVERT(varchar(38),SaOr.StatusId),'''')) ' ELSE '' END
+ ' OPTION (RECOMPILE);';
你需要做几个步骤
如果您一次从所有表中获取数据,并应用过滤器,将一次过滤数百万条记录。因此,如果您划分表,则筛选器将应用于较少的记录。动态构建查询并使用sp_executesql运行。您的建议不是使用过程,而是在后端准备查询然后执行,是吗?建议您阅读有关这类查询的内容。但你的第二种方法远比第一种糟糕。将所有内容转换为字符串,然后使用charindex在逻辑上存在缺陷,这对优化器来说是致命的,因为这些表达式根本无法使用索引。您也可以在sql过程中构建查询。感谢厨房水槽,这是一个很棒的示例我使用了类似的示例。然后,我使用临时表#user for users(估计3万行),#sales for sales的主要功能(10万行),#sales orders for each products(47万行)。我对#sales使用过滤器,获得数据,然后加入其他临时表。为什么我使用临时表,我已经读到了临时表索引的好处
where (SaOr.InsertDate between ISNULL(@StartDate,'1920-01-01') and ISNULL(DATEADD(DAY, 1, @DueDate),@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
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,CONVERT(varchar(38),SaOr.ChannelId),'''')) ' ELSE '' END
+ CASE WHEN @SalesType IS NOT NULL THEN
' AND LEN(@SalesType)> LEN(REPLACE(@SalesType,CONVERT(varchar(38),SaOr.SalesOrderTypeId),'''')) ' ELSE '' END
+ CASE WHEN @SalesStatus IS NOT NULL THEN
' AND LEN(@SalesStatus)> LEN(REPLACE(@SalesStatus,CONVERT(varchar(38),SaOr.StatusId),'''')) ' ELSE '' END
+ ' OPTION (RECOMPILE);';