TOP语句放到表值函数外,效率异常低下的原因分析

本文涉及的产品
云数据库 RDS SQL Server,独享型 2核4GB
简介:

SQLSERVER的表值函数是SQLSERVER 2005以来的新特性,由于它使用比较方便,就像一个单独的表一样,在我们的系统中大量使用。有一个获取客户数据的SQLSERVER 表值函数,如果使用管理员登录,这个函数会返回150W行记录,大概需要30秒左右,但如果将TOP语句放到表值函数外,效率异常低下,需要约3分钟:

select   top   20    *   from  GetFrame_CustomerSerch( ' admin ' , ' 1 ' )

下面是该存储过程的定义:

 

复制代码
ALTER   FUNCTION   [ dbo ] . [ GetFrame_CustomerSerch ]
(    
    
--  Add the parameters for the function here
     @WorkNo   varchar ( 38 )
    ,
@SerchChar   varchar ( 500 )
)
RETURNS   TABLE  
AS
RETURN  
(
    
--  Add the SELECT statement with parameter references here
     select  a.GUID,a.CustomerName,a.CustomerIDcard,a.CustomerPhone,a.CustomerMobile  from
    (
   --具体子查询略
    )
    ) a 
union   all
    
select  b.GUID,b.CustomerName,b.CustomerIDcard,b.CustomerPhone,b.CustomerMobile  from  WFT_ManagerCollectUsers a  left   join  WFT_Customer b  on  a.FundAccount = b.FundAccount
    
-- where a.WorkNo=@WorkNo
     WHERE  a.WorkNo  IN
    (
--具体子查询略
    )
    )
复制代码

 

 

这个语句放在PDF.NET数据开发框架的SQL-MAP文件中,开始还以为是框架引起的,将这个语句直接在查询分析器中查询,仍然很慢。


将GetFrame_CustomerSerch 中的SQL语句提取出来,直接加上Top查询,只需要6秒,快了N倍:

复制代码
declare   @WorkNo   varchar ( 38 )
declare   @SerchChar   varchar ( 500 )
set   @WorkNo = ' admin '
set   @SerchChar = ' 1 '
select   top   20  a.GUID,a.CustomerName,a.CustomerIDcard,a.CustomerPhone,a.CustomerMobile  from
 (
  
-- 具体子查询略
 )
 ) a 
union   all
 
select  b.GUID,b.CustomerName,b.CustomerIDcard,b.CustomerPhone,b.CustomerMobile  from  WFT_ManagerCollectUsers a  left   join  WFT_Customer b  on  a.FundAccount = b.FundAccount
 
 
WHERE  a.WorkNo  IN
 (
 
-- 具体子查询略
 )
 
复制代码


 

为什么会有这么大的差异?
我分析可能有如下原因:


1,在表值函数外使用Top或者其它条件,SQLSERVER 的查询优化器无法针对此查询进行优化,比如先返回所有记录,然后再在临时表中选取前面的20条记录;

2,虽说该表值函数使用了“表变量”,它是内存中的,但如果这个“表”结果很大,很有可能内存放不下(并非还有物理内存就会将结果放到物理内存中,数据库自己还会有保留的,会给其它查询预留一定的内存空间),使用虚拟内存,而虚拟内存实际上就是磁盘页面文件,当记录太多就会发生频繁的页面交换,从而导致这个查询效率非常低。

看来,“表值函数”也不是传说中的那么好,不知道大家是怎么认为的。

最近还遇到一个怪异的问题,有一个存储过程,老是在系统运行1-2天后变得极其缓慢,但重新修改一下又很快了(只是加一个空格之类),不知道大家遇到过没有,什么原因?


    本文转自深蓝医生博客园博客,原文链接:http://www.cnblogs.com/bluedoctor/archive/2011/04/27/2030305.html,如需转载请自行联系原作者



相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情: https://www.aliyun.com/product/rds/sqlserver
相关文章
|
3月前
|
SQL 存储 关系型数据库
原本可以执行得很快的 SQL 语句,执行速度却比预期的慢很多,原因是什么?如何解决?
原本可以执行得很快的 SQL 语句,执行速度却比预期的慢很多,原因是什么?如何解决?
|
4月前
|
存储 安全 C++
【C++14保姆级教程】lambda 初始化捕获 new/delete 消除
【C++14保姆级教程】lambda 初始化捕获 new/delete 消除
106 0
|
9月前
|
消息中间件 数据采集 Kafka
每次join之后没有正确处理数据的重复或缺失情况
每次join之后没有正确处理数据的重复或缺失情况
86 1
|
设计模式 JavaScript 前端开发
如何优雅的消除系统重复代码
在程序猿的日常工作中,不仅要跟随业务侧的发展不断开发新的需求,同时也需要维护老的已有平台。无论是开发新需求还是维护老系统,我们都会遇到同样一个问题,系统中总是充斥着很多重复的代码。
29472 11
如何优雅的消除系统重复代码
|
SQL 存储 Oracle
关于SQL优化,你不能只是说自己只会语句的优化了(一)
文章有点长,请各位看官按下耐心,一定看下去,虽然数据库这块的内容很枯燥,但是一定得保证自己全部都掌握,才能拿到一个很好的Offer,不是么?
关于SQL优化,你不能只是说自己只会语句的优化了(一)
|
存储 SQL 关系型数据库
关于SQL优化,你不能只是说自己只会语句的优化了(二)
文章有点长,请各位看官按下耐心,一定看下去,虽然数据库这块的内容很枯燥,但是一定得保证自己全部都掌握,才能拿到一个很好的Offer,不是么?
关于SQL优化,你不能只是说自己只会语句的优化了(二)
Kam
枚举优化if-else if -else过程记录
枚举优化if-else if -else过程记录
Kam
174 0
|
自然语言处理
在以阶段划分的编译过程中,判断程序语句的形式是否正确属于()阶段的工作。
在以阶段划分的编译过程中,判断程序语句的形式是否正确属于()阶段的工作。
130 0
|
SQL BI 关系型数据库
参数为空取全部数据的几种做法
当通过多个参数对数据进行过滤并且不选择某个参数时,希望依然能够查询出其他带条件的数据,也就是参数为空时忽略掉该条件,点击 <a href="http://c.raqsoft.com.cn/article/1543386793666?r=IBelieve" target="_blank" rel="n...
980 0