SQL优化技巧–远程连接对象引起的CTE性能问题

SQL优化技巧–远程连接对象引起的CTE性能问题

背景 

  最近SSIS的开发过程中遇到几个问题。其中使用CTE时,遇到一个远程连接对象,结果导致严重的性能问题,为了应急我就修改了代码。

  之前我写了一篇介绍CTE的随笔包含了CTE的用法等:

     http://wudataoge.blog.163.com/blog/static/80073886200961652022389/

问题

  在一个数据查询中遇到一个远程连接对象,然后使用了CTE,然后本地查询与远程对象的CTE进行了left join 。下面就是执行计划:

<span>SQL优化技巧--远程连接对象引起的CTE性能问题</span>

首先我们发现,最后一个操作符显示远程查询占了99%。

注意:

首先,远程查询使用的是CTE的表达式,我对CTE的理解有以下几点:

1.一次性视图(ADHoc View)。即必须后面跟着相应的select、insert、update等,只能用一次。

2.CTE表达式也是在内存中创建了一个表并对其操作。

3.with as 部分仅仅是一个封装定义的对象,并没有真的查询。

3.除非本身具有索引否则CTE中是没有索引和约束的。

4.没有专门的统计信息,这点与表变量很像。有可能会有错误的统计信息。

 

其次,连接操作符使用的是循环嵌套的操作符。这样就几何翻倍了查询的时间。

这里需要说一下NestedLoops:

本质上讲,“Nested Loops”操作符就是:为每一个记录的外部输入找到内部输入的匹配行。

技术上讲,这意味着外表聚集索引被扫描获取外部输入相关的记录,然后内表聚集索引查找每一个匹配外表索引的记录。

以上两个说法都表明了这种方式导致的性能问题。因为每一次循环都要访问一次链接服务器。当数据很大的时候极大地增加了查询时间。我这边70000+的数据执行了半小时。

解决:

既然了解了问题的情况,那我就着手解决问题。主要是两分解成两个步骤:

1.将远程链接服务器的查询结果插入临时表。

2.本地数据与临时表做left join。

对应的执行计划如下:

<span>SQL优化技巧--远程连接对象引起的CTE性能问题</span>

可以看到整个性能得到了极大的提高。修改完成后执行时间缩减到20秒以内。效率还是惊人的。

可以对比一下表变量与cte表倒是不同的特点:

  • tempdb中实际存在的表
  • 能索引
  • 有约束
  • 在当前连接中存在,退出后自动删除。
  • 有由引擎生成的数据统计。

通过两个方式的不同点可知几种情况不应当使用CTE:

1.结果集较大时不应使用。

2.查询时间较长的不要使用,比如跨服务器查询。

3.需要大的表连接的,比如行很多的各种join。尤其没有索引。

4.多次查询数据。

5.需要优化相关子查询。

这些时候使用临时表甚至表变量将会带来性能的提升。具体我就不在这里细说了有兴趣可以一起讨论下。

一些网上的错误:

1.materialize 提示 可以强制将WITH AS短语里的数据放入一个全局临时表里。sql server中根本没有这个提示。据说2014以后可能会有?

2.CTE 性能要差,根据实际情况出发,据我所知在绝大多数情况下,CTE的性能要好。尤其是对比游标(迭代)和内置函数的情况下,都会大大提高性能。

3.CTE使用了tempdb,没有仅仅使用了内存。

总结:

  通过解决实际问题,让我了解了CTE的运行机制。可以理解为一种一次性的视图。当然我们这里需要着重说明,CTE本身在性能优化上还是有很大作用的,尤其对于递归查询和内置函数的使用时都极大的较少了IO。

我猜想CTE内部原理应该与游标相似,但是极大的简化了性能,也许是优化器的功劳。最后由于仅仅使用了内存中这样也大大减少了连接瓶颈。

  这部分很多是我的个人观点,希望各位大神帮忙指摘一下。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/119721.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • netty 权威指南勘误[通俗易懂]

    netty 权威指南勘误[通俗易懂]近日就netty库的使用,试读了netty权威指南一书,就书中的编码问题进行以下校正1、我使用的是4.1.2版本的netty库2、IDE为netbeans8.1E1. handler适配器应使用ChannelInboundHandlerAdapter。 E2. 在私有协议开发一章:     编码器中函数encode中设置帧长度应为以下代码

    2022年9月1日
    5
  • B 站上有哪些很好的学习资源?[通俗易懂]

    B 站上有哪些很好的学习资源?[通俗易懂]哇说起B站,在小九眼里就是宝藏般的存在,放年假宅在家时一天刷6、7个小时不在话下,更别提今年的跨年晚会,我简直是跪着看完的!!最早大家聚在在B站是为了追番,再后来我在上面刷欧美新歌和漂亮小姐姐的舞蹈视频,最近两年我和周围的朋友们已经把B站当作学习教室了,而且学习成本还免费,真是个励志的好平台ヽ(.◕ฺˇдˇ◕ฺ;)ノ下面我们就来盘点一下B站上优质的学习资源:综合类Oeasy:综合…

    2022年7月17日
    13
  • python手机编程软件-盘点几个在手机上可以用来学习编程的软件[通俗易懂]

    python手机编程软件-盘点几个在手机上可以用来学习编程的软件[通俗易懂]前天在悟空问答的时候,很荣幸被邀请参加回答“在手机上可以用来学习编程的软件有哪些?”这个问题,当时在回答的首页看到一个头条大微(小小猿爱嘻嘻)的回答,觉得十分受用,在此将其整理好,发布头条给大家学习,希望对大家学习编程有帮助。感谢大佬提供的解答,原文可以点击拓展链接进行查看。学习编程的软件其实挺多的,下面我简单几个可以在手机上编程的软件,主要分为C/C++,Java,Python,前端网页,Lin…

    2025年10月18日
    3
  • MySQL基础篇(DDL,DML,DQL,DCL详细讲解)

    一、常用开发工具1.NavicateNavicat是一套快速、可靠并价格相宜的数据库管理工具,专为简化数据库的管理及降低系统管理成本而设。它的设计符合数据库管理员、开发人员及中小企业的需要。Navicat是以直觉化的图形用户界面而建的,让你可以以安全并且简单的方式创建、组织、访问并共用信息。http://www.navicat.com.cn/破解方式:https://www.jb51.net/database/710931.html再手动激活[外链图片转存失败,源站可能有防盗链.

    2022年4月7日
    134
  • 转行学习3D游戏建模,你需要了解的职业分类及发展

    转行学习3D游戏建模,你需要了解的职业分类及发展王者荣耀、LOL、梦幻西游,近几年在线人数破千万,带动了越来越多的企业在游戏上的开发,3D游戏建模将游戏的画面感、真实感高度还原,给游戏者更强烈的体验感,更加身临其境。游戏模型师是目前非常热的职业岗位,目前国内动漫游戏产业已经非常成熟,需要大量优质青年加入游戏美术行业,在游戏企业里可以成为优秀的次世代场景模型师,次世代角色模型师,底模手绘贴图模型师。成功进入游戏企业之后经过项目的锻炼,薪资也会逐年有所提升。游戏建模职业分类及发展:进入游戏模型行业你可以选择不同的发展方向,比如:(1)手绘3D美术设

    2022年5月19日
    63
  • SPI接口介绍

    SPI接口介绍SPI接口的全称是”SerialPeripheralInterface”,即串行外围接口。SPI接口主要应用在EEPROM、FLASH、实时时钟、AD转换器,还有数字信号处理器和数字信号解码器之间。SPI接口是在CPU和外围低速器件之间进行同步串行数据传输,在主器件的移位脉冲下,数据按位传输,高位在前,低位在后,为全双工通信,数据传输速度总体来说比I2C总线要快,速度可达到几十Mbps。S

    2022年6月18日
    44

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号