Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.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
在SQL Server 2012 SP 2中筛选数据的最佳方法是什么_Sql_Sql Server_Database_Entity Framework_Dapper - Fatal编程技术网

在SQL Server 2012 SP 2中筛选数据的最佳方法是什么

在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 Core 2.2,当我感觉舒适时,我会更新到5

目前,我正试图在大表中寻找搜索源,我有很好的建模表1主表和一些功能表,如性别、地址、上次购买、已审核产品等

  • EF在这方面真的很慢,所以我使用了dapper和调用存储 程序
  • 我想过滤这个几乎5.5GB(470k行)的数据,它是 转到更大的,31列,7个表,每个表+15列)
  • 我有5个不同的过滤器,它必须很快。因为程序 预计响应时间为1分钟
查询应使用动态参数

我必须这样做,我尝试了一些不同的方法,但仍然很慢。我有5个过滤器和1个日期声明。用户可以发送5个、4个或3个过滤器,或者什么都不发送

  • 我尝试过的方法,我从博客上读到使用“或”确实降低了性能
  • 我尝试过的方法,没有“或”,但比1慢
  • 3.方法采用动态查询

    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);';
    

    你需要做几个步骤

  • 将表分为2或3个部分,如过滤产品和付款,然后插入到#tetrable中,并与其他表(如Channel)应用内部联接并获取过滤数据#tetrable 2,然后将第二个tetrable与Sales和SalesType联接
  • 用于筛选的列在其中,对所有列创建索引

  • 如果您一次从所有表中获取数据,并应用过滤器,将一次过滤数百万条记录。因此,如果您划分表,则筛选器将应用于较少的记录。

    动态构建查询并使用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);';