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

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

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

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

  1. ALTER FUNCTION [dbo].[GetFrame_CustomerSerch]  
  2. (      
  3.     -- Add the parameters for the function here 
  4.     @WorkNo varchar(38)  
  5.     ,@SerchChar varchar(500)  
  6. )  
  7. RETURNS TABLE   
  8. AS 
  9. RETURN   
  10. (  
  11.     -- Add the SELECT statement with parameter references here 
  12.     select a.GUID,a.CustomerName,a.CustomerIDcard,a.CustomerPhone,a.CustomerMobile from 
  13.     (  
  14.    --具体子查询略 
  15.     )  
  16.     ) a union all 
  17.     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  
  18.     --where a.WorkNo=@WorkNo 
  19.     WHERE a.WorkNo IN 
  20.     (  
  21. --具体子查询略 
  22.     )  
  23.     )

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

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

  1. declare @WorkNo varchar(38)  
  2. declare @SerchChar varchar(500)  
  3. set @WorkNo='admin' 
  4. set @SerchChar='1' 
  5. select top 20 a.GUID,a.CustomerName,a.CustomerIDcard,a.CustomerPhone,a.CustomerMobile from 
  6.  (  
  7.   --具体子查询略 
  8.  )  
  9.  ) a union all 
  10.  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  
  11.    
  12.  WHERE a.WorkNo IN 
  13.  (  
  14.  --具体子查询略 
  15.  )

  为什么会有这么大的差异?

  我分析可能有如下原因:

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

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

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

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

本文出自seven的测试人生公众号最新内容请见作者的GitHub页:http://qaseven.github.io/

时间: 2024-09-12 03:11:59

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

和表值函数连接引发的性能问题分析

 表值函数     SQL Server中提供了类似其他编程语言的函数,而函数的本质通常是一段代码的封装,并返回值.在SQL Server中,函数除了可以返回简单的数据类型之外(Int.Varchar等),还可以返回一个集合,也就是返回一个表.     而根据是否直接返回集合或是定义后再返回集合,表值函数又分为内联用户定义表值函数和用户定义表值函数(下文统称为表值函数,省去"用户定义"四个字). 内联表值函数     内联表值函数和普通函数并无不同,唯一的区别是返回结果为集合(表),而

android开发-在android程序中在acitvity继承的重载函数外定义的语句

问题描述 在android程序中在acitvity继承的重载函数外定义的语句 请问如果在非重载函数外定义的函数,在哪个函数之后被执行? 比如在一个activity里有onCreate, onstart函数,如果在这些函数外面声明了函数或者语句,会在什么时候执行? 我会上机试一试.来验证你们的答案~~谢谢哈 解决方案 你不调用它怎么执行啊.... 还有好像语句必须在方法里面...

SQL SERVER函数之深入表值函数的处理分析_MsSql

有些情况可能用下表值函数,表值函数主要用于数据计算出来返回结果集,可以带参数(和视图的一个大的区别),如果函数中没有过多的逻辑处理,如变量的定义,判断等,表值函数返回结果集可以简单向下面这么写: 复制代码 代码如下: CREATE FUNCTION Fun_GetReportNews(@type varchar(10))RETURNS TABLEAS RETURN(  SELECT TPR_ID,TPR_Title,TPR_Date FROM TP_ReportNews WHERE TPR_Ty

SQL SERVER函数之深入表值函数的处理分析

有些情况可能用下表值函数,表值函数主要用于数据计算出来返回结果集,可以带参数(和视图的一个大的区别),如果函数中没有过多的逻辑处理,如变量的定义,判断等, 表值函数返回结果集可以简单向下面这么写: 复制代码 代码如下: CREATE FUNCTION Fun_GetReportNews(@type varchar(10)) RETURNS TABLE AS RETURN (   SELECT TPR_ID,TPR_Title,TPR_Date FROM TP_ReportNews WHERE T

通过分析SQL语句的执行计划优化SQL(二)

优化|语句|执行 第5章 ORACLE的执行计划 背景知识:        为了更好的进行下面的内容我们必须了解一些概念性的术语: 共享sql语句    为了不重复解析相同的SQL语句(因为解析操作比较费资源,会导致性能下降),在第一次解析之后,ORACLE将SQL语句及解析后得到的执行计划存放在内存中.这块位于系统全局区域SGA(system global area)的共享池(shared buffer pool)中的内存可以被所有的数据库用户共享.因此,当你执行一个SQL语句(有时被称为一个

在 SQL Server 2005 中使用表值函数来实现空间数据库

server|函数|数据|数据库 Gyorgy Fekete 和 Alex Szalay约翰霍普金丝大学 Jim GrayMicrosoft(联系作者) 适用于Microsoft SQL Server 2005 摘要:本文说明了如何使用 C# 和表值函数将空间搜索函数("邻近点的点"和"多边形内的点")添加到 Microsoft SQL Server 2005.使用此库可以在不编写任何特殊代码的情况下向应用程序中添加空间搜索.此库实现了来自约翰霍普金丝大学的公共域

表值函数与JS中split()的联系

在公司用云平台做开发就是麻烦 ,做了很多功能或者有些收获,都没办法写博客,结果回家了自己要把大脑里面记住的写出来. split()这个函数我们并不陌生,但是当前台有许多字段然后随意勾选后的这些参数传递到后台做处理的时候却麻烦了,我们这个时候需要把这些当字符串传递到存储过程,在存储过程里面将这些字符串分割成一个个单独的个体,我这里不说数组,是因为存储过程没有数组这一说. 这时候我们就会想到表值函数.表值函数返回的是一个Table类型的表.说到这里我想很多人都想到了,这不就是一个数组形式么?一个表就

和表值函数连接引发的性能问题

原文:和表值函数连接引发的性能问题     最近调优过程中遇到一个问题,就是表值函数作为连接中的一部分时,可能会引起麻烦,本文会简单阐述表值函数是什么,以及为什么使用表值函数进行连接时会引发性能问题. 表值函数     SQL Server中提供了类似其他编程语言的函数,而函数的本质通常是一段代码的封装,并返回值.在SQL Server中,函数除了可以返回简单的数据类型之外(Int.Varchar等),还可以返回一个集合,也就是返回一个表.     而根据是否直接返回集合或是定义后再返回集合,表

如何使用SQL CLR表值函数进行扩展

Microsoft SQL Server 2005 的一项新增功能是其与 Microsoft .NET Framework 公共语言运行库 (CLR) 的集成.这使得人们能够将 .NET Framework 类和函数纳入 Transact-SQL 语句和查询. CLR 集成的机制有多种: • CLR 用户定义函数(包括表值函数). • CLR 用户定义类型. • CLR 存储过程. • CLR 触发器. 本白皮书说明如何使用 CLR 表值函数根据包括数据库在内的各种源创建报表数据,从而创建可靠的