使用SQL Server2005扩展函数进行性能优化
来源:asp之家 发布时间:2010-06-07 11:26:00
SQL Server2005扩展函数已经不是一件什么新鲜的事了,但是我看网上的大部分都是说聚合函数,例子也比较浅,那么这里就讲讲我运用扩展函数来优化数据库性能的例子,希望和大家一起分享这个经验。如果你还不知道什么是SQLCLR,那么你可以参考:SQL Server扩展函数的基本概念。
需求说明
大家在使用SQL Server开发的时候一定会遇到这样的需求,那就是通过Table_Name1表的两个字段Column1、Column2来查询在Table_Name2表中符合这两个条件的记录,并返回Table_Name2中的字段Column3,面对这样的需求,你也许会说使用表连接就可以了,对的,没错,我也是这样想的,但是有的时候往往要面对不同的突 * 况,那就是并不是一定会Column1与Column2是全匹配的查询,可能中间还需要一些逻辑的处理,比如字符串的截取后再匹配等等。
这个时候我们通常会在SQL Server中写一个函数,这个函数接收两个参数:Column1、Column2,函数体里面做一些逻辑处理,在通过处理好的参数去查询Table_Name2表,并返回相应的值。很好,那下面我们来计算下图中数据的查询情况。假设表1的数据有50W,表2的数据有4W,在表2没有索引的条件下,查询的复杂度就有50W*4W了,两个表都需要做全表扫描,表2的全表扫描就会达到50W次。
(图1:需求说明)
优化1:这一个优化,每个开发人员都知道,那就是对表2的两个查询字段分别建立索引。这样的优化和之前相比,性能将会提高N个等级。
优化2:这第二个优化方法是使用SQL Server的复合索引,在表2上创建一个复合索引,这个符合索引包括需要查询的两个字段,其实就是把两个字段的内容生成一个索引,其中索引包含了两个索引的排序。
优化3:这第三个优化方法是使用SQL Server2005之后版本才有的索引-包含性索引(Include),就是在优化2的基础上,把需要返回的字段也一起放入到索引中,这样的查询就只需要查询索引就够了,不需要再读取数据页了,减少磁盘的IO消耗。不过这个方法也不是万能,因为有时可能返回的字段会比较多,有时几个字段加起来的长度有可能超出了900个字符(索引大小范围),如果想了解可以进入:SQL Server 索引中include的魅力(具有包含性列的索引)
优化4:在不考虑一些分区、分表、分到不同的磁盘等优化方式的情况下,我们是否还能进一步优化我们的查询呢?这就是这篇文章想要告诉你的,因为我们的回答是:有的。那就是通过SQLCLR的UDT,把表2的数据一次性加载到内存,那么在进行表1查询的时候,我们不需要通过B+树来查询数据了,直接到内存中查询,这样之所以快是因为操作内存要比操作磁盘要快得多。这其中会有些局限性和缺点,具体见下面的缺点描述。
设计思路
1、去数据库中把表2读取出来,并放到private static readonly IDictionary<string, string> resultCollectionDic的静态变量中。在数据库服务启动的时候是会初始化2、SQLCLR函数的,所以在启数据库服务的时候,也一起把表2的数据保存到了内存当中了。
3、上面的查询中包括了两个字段Column1、Column2和一个返回字段Column3,那么我们如何把这些数据保存到IDictionary字典当中呢?我的做法就是把Column1、Column2的中间加一个字符“+”,把这个字符串作为Key值,把Column3这个返回值做为Value,这样就解决了多个And的查询的问题。这个会有些局限性,具体可以见下面的缺点描述。
在函数FunctionImsi2HLR2中传进的两个字符后,就要进行上面的拼凑方式来拼凑Key值,再到IDictionary中查询。
测试结果
测试数据:表2有4.6732万条记录,表1有54.2524万条记录。


猜你喜欢
- [pre]REPAIR [LOCAL | NO_WRITE_TO_BINLOG] TABLE[/pre][pre] tbl_name[,tb
- 广州4.18书友会主题的内容提纲自己参与撰写,同时还参与组织和主持。通过这次的深入参与,我发现胡晓同学能坚持下来多不容易,先赞下。由于天公不
- 用户输入1、使用input来等待用户输入。如 username = input('username:') password
- 喜欢用 Python 做项目的小伙伴不免会遇到这种情况:做图表时,用哪种好看又实用的可视化工具包呢?之前文章里出现过漂亮的图表时,也总有读者
- 项目地址是:https://www.chenshiyang.com/dytk接下来我们分析下源码简要看下实现原理。实现原理该项目不需要使用模
- Wake-On-LAN简称WOL,是一种电源管理功能;如果存在网络活动,则允许设备将操作系统从待机或休眠模式中唤醒。许多主板厂商支持IBM提
- Spark Streaming VS Structured StreamingSpark Streaming是Spark最初的流处理框架,使
- PyAutoGUI是一个纯Python的GUI自动化工具,其目的是可以用程序自动控制鼠标和键盘操作,多平台支持(Windows,OS X,L
- 有时,我们需要获得某张表所有的元数据,我们可能想到的是通过查询系统表获得,但是这比较繁琐,而在SQL Server2005(包含)以后,提供
- 京东商品详细的请求处理,是先显示html,然后再ajax请求处理显示价格。1.可以运行js,并解析之后得到的html2.模拟js请求,得到价
- 使用celery在django项目中实现异步发送短信在项目的目录下创建celery_tasks用于保存celery异步任务。在celery_
- 前言写过的这些脚本有一个共性,都是和web相关的,总要用到获取链接的一些方法,累积不少爬虫抓站的经验,在此总结一下,那么以后做东西也就不用重
- 实战场景 本篇博客学习字体反爬,涉及的站点是实习 x,目标站点地址直接百度搜索即可。可以看到右侧源码中出现了很多&ldqu
- 这些标记告诉预处理器,它们包含代码,并且应对它们作出处理。与 CGI 非常相似,这些代码在服务器上运行,并返回一些内容,这些内容表现为发回给
- 大家都知道系统存储过程是无法用工具导出的(大家可以试试 >任务>生成SQL脚本) 因为系统存储过程一般是不让开发人员修改的。 需
- vue后台返回base64图片无法显示关于后台接口返回的图片base64格式页面无法显示的问题,我遇到的原因是因为返回的一串内容里面存在空格
- 一、使用selenium前?1.安装seleniumpip install Selenium2.安装浏览器驱动Chrome驱动文件下载:点击
- 1.基数排序基数排序的基本思想是先将数字按照个位数上数字的大小进行排序,排序之后再将已经排过序的数字再按照十位数上数字的大小进行排序,依次推
- 使用python实现文件导入,具体方法如下:文件样例可以自己random这里的temp1根据每一行的分隔符来读入,‘\n'表述回车t
- 神奇创意相框! 是的,主要利用position的relative, absolute, z-index属性。结合Photo Frame(相框