如何在 SQL Server 中使用存储过程提高和加快获取数据的速度?

Posted

技术标签:

【中文标题】如何在 SQL Server 中使用存储过程提高和加快获取数据的速度?【英文标题】:How to improve and fast speed for the get data using stored procedure in SQL Server? 【发布时间】:2017-08-28 10:53:16 【问题描述】:

我创建了一个存储过程来获取数据。在这个存储过程中,我返回了 5+ 以上的表,表存储了 20k+ 以上的数据。所以现在我已经运行了存储过程,我在 1 分钟以上的时间内获得了数据。我只想在 1 秒内获取数据。我还设置了SET NOCOUNT ON; 并创建了缺失的索引。我仍然在同一时间获取数据。

这是我的查询 =>

SET NOCOUNT ON;

DECLARE @CurMon int
DECLARE @year nvarchar(max)
SELECT  @CurMon = month(getdate())
SELECT  @year = year(getdate())

SELECT 
    FORMAT(dateadd(MM, T.i, getdate()), 'MMM-yy') AS DateColumn, 
    CASE 
       WHEN uf.TotalCount IS NULL
          THEN 0  
          ELSE uf.TotalCount 
    END AS TotalCount
FROM 
    (VALUES (12-@CurMon),(11-@CurMon),(10-@CurMon),(9-@CurMon),(8-@CurMon),(7-@CurMon),(6-@CurMon), (5-@CurMon), (4-@CurMon), (3-@CurMon), (2-@CurMon), (1-@CurMon)) AS T(i)
OUTER APPLY
    (SELECT DISTINCT 
         COUNT(datepart(MM, InsertDateTime)) OVER (PARTITION BY datepart(MM, InsertDateTime)) AS TotalCount
     FROM 
         User
     WHERE 
         DATEDIFF(mm, UF.InsertDateTime, DATEADD(mm, T.i, GETDATE())) = 0 
         AND IsLogin = 1) uf
ORDER BY
    DATEPART(MM, CONVERT(DATETIME, FORMAT(dateadd(MM, T.i, GETDATE()), 'MMMM') + '01 ' + @year, 110))

我在这里有这样的查询,请让我如何改进这个 sp。

【问题讨论】:

如果不了解表结构、现有索引、解释计划以及一些示例数据,这很难回答。 使用查询分析器检查发生了什么。执行计划也有助于解决您的问题。请上传一份 @BerndOtt 但我在查看执行计划后创建了所有缺失的索引。但我仍然遇到同样的问题 寻求性能帮助的问题应包括 DDL、DML 所涉及的表以及测试数据。如果您的测试数据很大,请尝试为表编写模式和统计信息(right click database->generate scripts->select specific database objects->in next screen select advanced and choose Script statistics) 并粘贴它有问题..有了这些信息,任何人都可以重现您面临的相同问题。否则,回答您的问题变得非常困难。粘贴服务器版本也有帮助 【参考方案1】:

APPLY 运算符为查询的外部表表达式返回的每一行调用表值函数。

https://www.mssqltips.com/sqlservertip/1958/sql-server-cross-apply-and-outer-apply/

https://www.sqlshack.com/sql-server-query-execution-plans-understanding-reading-plans/

    您是否尝试从查询中删除 ORDER BY,然后检查查询性能。如果您只需要月份编号,为什么要在 ORDER BY 中格式化这么多。 DATEADD 之后的 DATEPART 不能给你吗?对大型集合使用 CONVERT 和 FORMAT 会降低性能。

    将 WHERE 子句中的 DATEDIFF 更改为 MONTH,而不是 DATEADD,以整数形式获取当前月份并添加到 T.i

    1234563 p>

    您能否将 VALUES 子句中的内容放入另一个表变量中,因为您要为多个查询重复它。

    再次在您的选择字符串中,您的格式设置过多。您创建了自己的值 T (i)。您可以只放置一个包含 2 列的表变量

2017 年 9 月 9 日

17 年 10 月 10 日

2017 年 11 月 11 日

那么,您就不需要进行这么多的格式化了。

    可以使用ISNULL函数代替SELECT中的CASE语句。

    显然,接下来是索引、实际查询执行计划、锁和等待统计信息。您的表架构未知。

    如果可能的话,您可能必须重写查询以使用其他内容而不是 OUTER APPLY,可能是 CROSS APPLY 或 LEFT JOIN。它们可以比 OUTER APPLY 更快。

https://dba.stackexchange.com/questions/75048/outer-apply-vs-left-join-performance

SQL View Outer Apply Speed

CROSS APPLY vs OUTER APPLY speed difference

    此外,请检查安装了 SQL Server 的 PC 上是否存在任何空间问题。检查日志文件清理。这些基本上是 DBA 可以在您所在位置进行的活动。

【讨论】:

你能给我一些提示吗? 我也可以删除 order by 并设置 isnull 来替换大小写,但我的查询仍然需要更多时间。看不到任何变化 试点号2 & 8. WHERE 子句中的日期比较可能需要很长时间。此外,除此之外,您还可以查找索引碎片、单个查询的等待统计信息以及所有查询的实际查询执行计划。查询执行计划中百分比较高的点可能需要重写。此外,检查安装了 SQL Server 的 PC 上是否存在任何空间问题。检查日志文件清理。这些基本上是 DBA 可以在您所在位置进行的活动。

以上是关于如何在 SQL Server 中使用存储过程提高和加快获取数据的速度?的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 存储过程

SQL Server 存储过程

SQL Server 存储过程

SQL Server 存储过程

SQL Server 存储过程

SQL Server 存储过程