SQL SERVER中SQL优化

本文涉及的产品
云数据库 RDS SQL Server,独享型 2核4GB
简介: Sqlserver中尝试了一个开发的写法 实现功能是扫描当前每条记录时,把下一条记录合并到当前行。 用自关联CURR.RN = NEXT.RN +1(能找下一条)的方式查找时30万的数据就很慢,甚至30分钟后就内存溢出,最后调试后发现导致慢的根本原因是用表变量存储了中间结果,然后从表变量里查询数据时就非常慢。

Sqlserver中尝试了一个开发的写法

实现功能是扫描当前每条记录时,把下一条记录合并到当前行。

用自关联CURR.RN = NEXT.RN +1(能找下一条)的方式查找时30万的数据就很慢,甚至30分钟后就内存溢出,最后调试后发现导致慢的根本原因是用表变量存储了中间结果,然后从表变量里查询数据时就非常慢。数据量如果很大都缓存到内存里,可能已经占用很多内存,后面再查询时表自关联时也要用到很多内存,所以就慢且最后内存溢出了。

解决方法就是把表变量换成临时表,这样查询时有足够内存可以使用,速度从30分钟到10秒钟。

 

DECLARE @DI_V2_BFGATE TABLE (                     

                      RN              NUMERIC(19,0)

                    , WORKDT           VARCHAR(20)

                    , IDNO             VARCHAR(20)

                    , INOUTTIME          VARCHAR(20)

                    , INOUTGBNCD            VARCHAR(20)

                    , IF_SQ              BIGINT

                    --, WKT_TOT_TM       NUMERIC(19,0)

                    );

                   

      --  INSERT INTO @DI_V2_BFGATE

        SELECT

               ROW_NUMBER()OVER(PARTITION BY T.WORKDT,IDNO ORDER BY INOUTTIME) RN

               --ROW_NUMBER()OVER(ORDER BY IDNO,INOUTTIME) RN OLD WAY

              ,T.WORKDT

              --,T2.OVTM_DT

              --,T3.TMOFF_DT

              --,T3.TMOFF_NM

              --,T3.TMOFF_TYPE

              ,IDNO

              ,INOUTTIME

              ,INOUTGBNCD

              ,T.IF_SQ INTO #DI_V2_BFGATE

        

         FROM T_DI_V2_BFGATE T

         LEFT JOIN T_SI_GHR_OVTM  T2 ON (

                                         T.IDNO = T2.EMP_ID

                                         AND T.WORKDT = REPLACE(CONVERT(VARCHAR(10),T2.OVTM_DT,120),'-','')

                                         AND  T2.TIME_WEEK_CD = '1'

                                         AND  T2.SHIFT_TYPE = 'OFMW'

                                        )

         LEFT JOIN T_SI_GHR_TIME_OFF T3 ON (

                                         T.IDNO = T3.EMP_ID

                                         AND T.WORKDT =  REPLACE(CONVERT(VARCHAR(10),T3.TMOFF_DT,120),'-','')

                                         AND  T3.TMOFF_TYPE IN ('YC')

                                         )

         WHERE 1=1

      -- AND IDNO = '12587526' --test case

         AND   WORKDT >= '20170101' AND WORKDT < '20170201'

         AND  IsNumeric(IDNO) = 1

        

         --(1) 插入上午集中工作时间违反记录

        DECLARE @WKT_TEMP TABLE (

                      WORKDT           VARCHAR(20)

                    , IDNO             VARCHAR(20)

                    , OUT_DT           DATETIME

                    , IN_DT            DATETIME

                    );

        INSERT INTO @WKT_TEMP

        SELECT WORKDT

              ,IDNO

              ,OUT_DT

              ,IN_DT

        FROM(

            SELECT  T1.WORKDT

                   ,T1.IDNO

                   ,CAST(SUBSTRING(T1.INOUTTIME,0,9) AS DATE) WKT_DATE

                   ,CONVERT(DATETIME,SUBSTRING(LEFT(T1.INOUTTIME,8)+' ' + SUBSTRING(T1.INOUTTIME,9,2)+':' + SUBSTRING(T1.INOUTTIME,11,2)+':' + SUBSTRING(T1.INOUTTIME,13,2),1,20))  OUT_DT

                   ,CONVERT(DATETIME,SUBSTRING(LEFT(T2.INOUTTIME,8)+' ' + SUBSTRING(T2.INOUTTIME,9,2)+':' + SUBSTRING(T2.INOUTTIME,11,2)+':' + SUBSTRING(T2.INOUTTIME,13,2),1,20))  IN_DT

                   ,T1.INOUTGBNCD

                   ,T2.INOUTGBNCD INOUTGBNCD1

                 

            FROM #DI_V2_BFGATE T1

            LEFT JOIN #DI_V2_BFGATE T2 ON (T2.IDNO = T1.IDNO

                                       AND T2.WORKDT = T1.WORKDT

                                       AND T2.RN = T1.RN + 1

                                       AND IsNumeric(T2.IDNO) = 1

                                       AND T2.INOUTGBNCD != T1.INOUTGBNCD)

            WHERE T1.INOUTGBNCD = 'OUT'   

            AND   T1.WORKDT >= '20170101' AND T1.WORKDT < '20170201'               

            AND   RIGHT(T1.INOUTTIME,6) >= '090000' AND RIGHT(T1.INOUTTIME,6) <= '110000'

            --OR    RIGHT(T1.INOUTTIME,6) >= '140000' AND RIGHT(T1.INOUTTIME,6) <= '150000')

        )T

        SELECT * FROM @WKT_TEMP

        DROP TABLE #DI_V2_BFGATE

小结

 

选择对应的方式:

  1)使用表变量主要需要考虑的就是应用程序对内存的压力,如果代码的运行实例很多,就要特别注意内存变量对内存的消耗。我们对于较小的数据或者是通过计算出来的推荐使用表变量。如果数据的结果比较大,在代码中用于临时计算,在选取的时候没有什么分组的聚合,就可以考虑使用表变量。

  2)一般对于大的数据结果,或者因为统计出来的数据为了便于更好的优化,我们就推荐使用临时表,同时还可以创建索引,由于临时表是存放在Tempdb中,一般默认分配的空间很少,需要对tempdb进行调优,增大其存储的空间。

相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS&nbsp;SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/sqlserver
目录
相关文章
|
8天前
|
SQL 人工智能 算法
【SQL server】玩转SQL server数据库:第二章 关系数据库
【SQL server】玩转SQL server数据库:第二章 关系数据库
47 10
|
20天前
|
SQL 存储 关系型数据库
一文搞懂SQL优化——如何高效添加数据
**SQL优化关键点:** 1. **批量插入**提高效率,一次性建议不超过500条。 2. **手动事务**减少开销,多条插入语句用一个事务。 3. **主键顺序插入**避免页分裂,提升性能。 4. **使用`LOAD DATA INFILE`**大批量导入快速。 5. **避免主键乱序**,减少不必要的磁盘操作。 6. **选择合适主键类型**,避免UUID或长主键导致的性能问题。 7. **避免主键修改**,保持索引稳定。 这些技巧能优化数据库操作,提升系统性能。
215 4
一文搞懂SQL优化——如何高效添加数据
|
1月前
|
SQL 数据库 数据安全/隐私保护
Sql Server数据库Sa密码如何修改
Sql Server数据库Sa密码如何修改
|
18天前
|
SQL
启动mysq异常The server quit without updating PID file [FAILED]sql/data/***.pi根本解决方案
启动mysq异常The server quit without updating PID file [FAILED]sql/data/***.pi根本解决方案
16 0
|
8天前
|
SQL 算法 数据库
【SQL server】玩转SQL server数据库:第三章 关系数据库标准语言SQL(二)数据查询
【SQL server】玩转SQL server数据库:第三章 关系数据库标准语言SQL(二)数据查询
66 6
|
8天前
|
SQL 存储 数据挖掘
数据库数据恢复—RAID5上层Sql Server数据库数据恢复案例
服务器数据恢复环境: 一台安装windows server操作系统的服务器。一组由8块硬盘组建的RAID5,划分LUN供这台服务器使用。 在windows服务器内装有SqlServer数据库。存储空间LUN划分了两个逻辑分区。 服务器故障&初检: 由于未知原因,Sql Server数据库文件丢失,丢失数据涉及到3个库,表的数量有3000左右。数据库文件丢失原因还没有查清楚,也不能确定数据存储位置。 数据库文件丢失后服务器仍处于开机状态,所幸没有大量数据写入。 将raid5中所有磁盘编号后取出,经过硬件工程师检测,没有发现明显的硬件故障。以只读方式将所有磁盘进行扇区级的全盘镜像,镜像完成后将所
数据库数据恢复—RAID5上层Sql Server数据库数据恢复案例
|
12天前
|
SQL 安全 Java
SQL server 2017安装教程
SQL server 2017安装教程
14 1
|
21天前
|
SQL 关系型数据库 MySQL
【MySQL技术之旅】(7)总结和盘点优化方案系列之常用SQL的优化
【MySQL技术之旅】(7)总结和盘点优化方案系列之常用SQL的优化
36 1
|
22天前
|
SQL 索引
SQL怎么优化
SQL怎么优化
27 2
|
25天前
|
SQL 存储 Python
Microsoft SQL Server 编写汉字转拼音函数
Microsoft SQL Server 编写汉字转拼音函数