发展历程 快速响应:对数据库进行调试和分析以营救

快速响应:对数据库进行调试和分析以营救

Anonim

通过Techopedia Staff,2017年3月15日

总结:主持人Eric Kavanagh与Robin Bloor博士,Dez Blanchfield和IDERA的Bert Scalzo讨论了数据库调试和配置文件。

您目前尚未登录。请登录或注册以观看视频。

埃里克·卡瓦那(Eric Kavanagh):好的,女士们,先生们,星期三是美国东部时间4:00,这当然意味着。

罗宾·布卢尔:听不到,埃里克。

埃里克·卡瓦纳(Eric Kavanagh):我几天前就在那儿,所以你并不孤单。 但是,今天的话题真的很有趣。 您要确保这种事情在公司的后台发生,除非您是这样做的人,在这种情况下,您要确保自己做得正确。 因为我们在谈论调试。 没有人喜欢错误,没有人喜欢软件何时停止运行,人们会不高兴,用户会变得不友好。 这不好。 因此,我们将讨论“快速响应:对救援进行数据库调试和性能分析”。

确实有一个关于您的地方,请在Twitter上打我,@ eric_kavanagh。

今年很热。 无论如何,调试都将变得很热。 实际上,这将是永远不会消失的问题之一,无论我们在这方面有多出色,总会有问题,所以关键是如何到达可以快速解决这些问题的地方? 理想情况下,您拥有出色的程序员,出色的环境,不会出错太多,但正如俗话所说,“事故发生在最优秀的家庭中。”组织也是如此。 那么,这些事情发生了,它将会发生,问题是什么将成为您处理和解决这些问题的解决方案?

我们会听到Robin Bloor博士的声音,然后是我们自己的Dez Blanchfield的声音,当然还有IDERA的好朋友Bert Scalzo。 实际上,我将交出Robin Bloor的钥匙,将其拿走。 地板是你的。

罗宾·布卢尔(Robin Bloor):好的。 这是一个有趣的话题。 我认为因为Dez可能会继续讨论有关调试的实际技术和战争故事,所以我认为我只会做一个背景讨论,以便我们对所发生的事情有一个全面的了解。 我做了很长时间,我曾经是一名编码人员,就像这样,我几乎被这个演示吸引住了,开始对开源概念进行抒情分析,但我想我会把它留给其他人。

这是一个著名的bug列表,基本上,大多数都进入了任何人的榜首,除了最后两个之外,所有bug至少花费了1亿美元。 第一个是火星气候轨道器,它在太空中迷路了,这是由于编码问题,人们将公制单位与(笑)英尺和英寸相混淆。 阿丽亚娜5航班501的安装引擎与应该在火箭发射时运行的计算机之间不匹配。 多台计算机故障,火箭爆炸,头条新闻。 据说1982年的苏联天然气管道是地球历史上最大的爆炸; 我不确定是否。 俄国人偷走了一些自动控制软件,中央情报局意识到他们要这样做并在其中添加了错误,苏联人则未经测试就实施了它。 因此,炸毁了一条管道,以为那很有趣。

莫里斯蠕虫是一个编码实验,突然变成了一个贪婪的蠕虫,遍及每个人,它显然造成了价值1亿美元的损失。 那是当然的估计。 英特尔在数学芯片上犯了一个著名的错误-1993年在奔腾芯片上进行了数学指令-应该花费超过1亿美元。 苹果的Maps计划可能是苹果做过的任何事情中最糟糕,最灾难性的发布。 我的意思是,尝试使用它的人正沿着101路行驶,并发现Apple Map称他们在旧金山湾中。 因此,人们开始将Apple Maps应用称为iLost。 从1990年以来,这是我们最长的一次停机,从这样的成本角度来看,这很有趣-AT&T停了大约9个小时,长途通话花费了大约6000万美元。

我当时在一家英国保险公司和数据库中,他们实施了新版本的数据库,并开始擦除数据。 而且我记得非常好,因为后来我被邀请参加某种数据库选择。 非常有趣的是,他们采用了新版本的数据库,并且对通过所有测试的数据库新版本进行了一系列测试。 它发现擦除数据的方法非常晦涩。

所以,就是这样。 我以为我会谈论阻抗不匹配和SQL发行。 有趣的是,关系数据库将数据存储在表中,而编码人员则倾向于操纵对象结构中的数据,而对象结构实际上并不能很好地映射到表。 因此,您会得到所谓的阻抗不匹配,并且有人必须以某种方式进行处理。 但是实际上发生了什么,因为一个模型,编码器的模型和数据库的另一个模型并没有特别对齐。 如果该行业构建了可以协同工作的东西,那么您将收到根本无法发生的错误,我认为这很有趣。 因此,基本上,在编码人员方面,当您获得层次结构时,它可能是类型,可能是结果集,可能是较差的API功能,可能是很多事情,这些事情只是与数据库交互而已。 但是对我来说最重要的事情真的很有趣。 总是让我感到惊讶的是,您遇到了这种SQL障碍,这也是一种阻抗,编码人员和数据库之间会相互配合。 因此,SQL具有数据识别功能,这很好,并且它具有用于选择,项目和联接的DML,这很好。 您可以利用它从数据库中获取数据方面提供很多功能。 但是它几乎没有用于做事的数学语言。 它具有这种特性,并且几乎没有基于时间的东西。 因此,如果您愿意,SQL是一种不完善的获取数据的方法。 因此,数据库专家构建了存储过程以驻留在数据库中,而存储过程驻留在该数据库中的原因是,您实际上并不想将数据来回传递给程序。

因为某些功能是非常特定于数据的,所以不仅仅是参照完整性和级联删除之类的事情,数据库正在处理您突然将功能放入数据库的所有工作,这当然意味着应用程序的功能可以在编码器和数据库本身之间分配。 这使得实现某些功能的工作确实非常困难,因此更容易出错。 所以,这是数据库游戏的一方面,因为这意味着您已经获得了很多实现,例如,我参与了关系数据库,实际上有很多代码存储在处理的存储过程中与位于应用程序中的代码分开。 这似乎是一件很奇怪的事情,在做各种事情上应该很聪明。

我以为我也会谈论数据库性能,因为性能错误通常被认为是错误,但基本上,您可能在CPU,内存,磁盘,网络上遇到瓶颈,并且由于锁定而可能遇到性能问题。 这样的想法是,编码人员实际上并不需要担心性能,而数据库实际上将表现得相当不错。 它的设计应使编码人员无需知道。 但是,您的数据库设计不佳,程序设计不佳,工作负载混合并发,这也可能导致性能问题。 您将获得负载平衡,获得容量规划和数据增长,这可能会导致数据库停止运行或减慢运行速度。 有趣的是,当数据库快满时,它们会变慢。 而且,在复制,复制需求以及进行备份和恢复方面,您可能会遇到数据层问题。 无论如何,这是一个总体概述。

我唯一要说的是数据库调试只能是繁重而又琐碎的-我之所以这样说是因为我做了很多事情-您经常会发现它就像调试中的所有情况一样曾经经历过的是,您见过的第一件事就是一团糟。 而且,您必须尝试从混乱中解脱出来,弄清混乱是如何产生的。 通常,当您查看数据库问题时,您所看到的只是损坏的数据,而您却在想:“这是怎么发生的?”

无论如何,我将转给Dez,他可能会说出比我想出的更多的智慧之词。 Dez,我不知道该如何传球。

埃里克·卡瓦纳(Eric Kavanagh):我会通过它,待命,稍等。

自动语音:与会者线路静音。

埃里克·卡瓦纳(Eric Kavanagh):好吧,请稍等,让我把球传给Dez。

Dez Blanchfield:谢谢Eric。 是的,Robin Bloor博士,您的确确实是最正确的:这是一个话题,如果您对双关语宽恕的话,那是一生的烦恼,对不起,我对此无能为力。 希望您能在此看到我的第一个屏幕,在顶部我对字体大小问题表示歉意。 根据我的经验,在许多情况下,漏洞的主题是为期一天的讲座。 这是一个广泛的话题,因此,我将重点放在两个关键领域,特别是我们认为与错误有关的概念,但与编程有关的问题。 我认为这些天来引入缺陷本身通常会被集成开发环境所接受,尽管它们可能是长期运行的缺陷。 但是,通常情况下,要对代码进行概要分析,并且有可能编写具有功能的代码,这应该是一个错误。 因此,我在这里的标题幻灯片实际上是在高分辨率A3上获得的副本,但不幸的是,在搬家后它被摧毁了。 但这是1945年左右的编程表上的手写笔记,据推测是美国哈佛大学的一些人,他们的第二代机器Mark 2。 他们正在用通用语言调试一些问题,但是他们试图找到故障,结果发现出现了与硬件和所谓软件问题稍有不同的事物。

因此,都市神话是1945年9月9 日左右 ,哈佛大学的一个团队拆开了一台机器,他们遇到了一个叫做“继电器70”的东西–那时,编程是在物理意义上完成的,这会伤到代码这是您有效地对机器进行编程的方式-他们发现继电器编号70出了点问题,事实证明出现了“错误”一词,因为它实际上是飞蛾。是一只飞蛾夹在一块从一处到另一处的铜线之间。 传说中,传说中的格蕾丝·霍珀(Grace Hopper)是这个标题,在我的标题幻灯片中,“发现错误的第一个实际案例”引用了无引号。

但是正如罗宾(Robin)在其第一张幻灯片的前面所强调的那样,错误的概念可以追溯到我们可以想象的人在进行计算时,这些概念就像补丁一样。 术语“补丁”来自将一条实际的胶带粘贴在打孔卡上的孔上。 但这的全部要点是,“调试”一词源自在物理机中发现错误的概念。 从那时起,我们就一直使用该术语来尝试处理问题,或者不只是在未编译的程序中编码问题,而是在运行不正常的程序中进行编码。 尤其是尚未进行概要分析,只是找到诸如永无止境的循环之类的东西。

但是我们也有一个场景,我想我应该先放几张有趣的幻灯片,然后再详细介绍。 这是经典漫画,在网络上称为XKCD,漫画家对世界有一些非常有趣的看法。 这是关于一个叫“小鲍比桌子”的孩子,据说他的父母叫这个小男孩罗伯特(Robert'); 放下桌子的学生;然后,它被称为“嗨,这是您儿子的学校遇到计算机故障”,而家长回答说:“哦,亲爱的,他有事吗?”然后老师说,“嗯,在某种程度上,”老师问,“您真的给儿子罗伯特起名字了吗? 放桌子的学生;-?”父母说:“哦,是的,小鲍比桌子,我们叫他。”无论如何,他们继续说,他们现在已经失去了当年的学生记录,我希望你幸福。 答案是:“嗯,您应该清理和清理数据库输入。”而且,我多次使用这种方式来讨论我们在代码中查找内容时遇到的一些问题,这些问题通常是代码不查看数据也一样

另一个有趣的是,我不知道这是不是真的–我怀疑这是一个恶作剧–但同样,它也触动了我的有趣的骨头。 有人将其汽车前部的车牌更改为类似的陈述,该陈述导致数据库中的速度相机下降,以此类推,从而捕获了汽车的车牌。 我一直指的是,我怀疑任何程序员都不会预料到实际汽车会撞上他们的代码,但永远不要低估这一点–愤怒的怪胎的力量。

(笑声)

我想,这将我引到了关键点,那就是从前,我们可以像调试凡人一样调试和分析代码。 但是我非常认为那段时间已经过去,而且我的经历是我第一次经历的轶事-我敢肯定,这将使我很老。 罗宾,欢迎您为我取笑–但是从历史上看,我来自14岁的背景,在城镇尽头徘徊,在新市镇打了一个名为“ Data Com”的数据中心新西兰,问我是否可以在学校里赚点零花钱,方法是坐晚班车回家,每天上下班约25公里,将纸张放进打印机,将磁带放进磁带机中,然后成为一名普通管理员。 奇怪的是,他们确实给了我一份工作。 但是随着时间的流逝,我设法找到了工作人员并找到了程序员,并意识到我喜欢编码,并经历了运行脚本和批处理作业的过程,但最终还是要编写代码。 您必须编写类似于小型程序的脚本和批处理作业,然后完成坐在3270终端上手动编写代码的整个过程。

实际上,我的第一个经验是在电传打字机终端上,它实际上是132列的物理打印机。 本质上,可以想像是一台非常古老的打字机,上面有纸可以滚动,因为他们没有CRT管。 并且在那方面调试代码是一个非常重要的问题,因此您倾向于手动编写所有代码,然后像打字员一样努力,尽最大努力不让错误潜入,因为不得不告诉别人非常沮丧一个行编辑器转到某一行,然后打印该行,然后将其键入。但是从前,这就是我们编写代码的方式以及调试的方式,我们对此非常非常好。 实际上,这迫使我们拥有非常好的编程技术,因为修复它确实很麻烦。 但是经历了整个旅程-我们都非常熟悉-从我在世界上的3270终端体验,到可以在屏幕上看到事物的Digital Equipment VT220,但是同样,您在做同样的事情您仅在CRT上使用纸带打印格式进行打印,但是您能够更轻松地删除,并且没有那种“滴滴涕滴滴涕”的声音。

然后您就会知道,Wyse终端机(例如Wyse 150,可能是我最喜欢的计算机接口),然后是PC,然后是Mac,然后是当今基于Web的现代GUI和ID。 并通过一系列程序,用一个汇编程序和PILOT和Logo和Lisp和Fortran和Pascal进行编程,以及可能使人们畏缩的语言。 但是这些语言迫使您编写好的代码。 他们并没有让您摆脱不良做法。 C,C ++,Java,Ruby,Python –到了编程阶段,我们变得更像脚本,我们越来越接近结构化查询语言和实际上用于调用SQL的PHP​​之类的语言。 告诉你的是,我来自我的背景,在许多方面都是自学成才的,那些确实帮助我学习的东西,教会了我很好的编程实践以及关于设计和过程的很好的实践,以确保我没有引入错误代码。

如今,编程方法之类的东西,例如结构化查询语言,SQL,它是一种非常强大,简单的查询语言。 但是我们已经将它变成了一种编程语言,我真的不相信SQL曾经被设计成一种现代的编程语言,但是我们已经把它变成这样。 这就引入了很多问题,因为这是从两个角度考虑的:从编码角度和从DBA角度考虑。 这很容易出现,并且会针对诸如不良的编程技术,懒惰的代码编写工作,缺乏经验,经典的讽刺之类的问题引入错误,例如,SQL人员跳上Google并搜索某些内容并找到一个得到一个示例,并复制和粘贴现有代码。 然后复制错误的编码,不当行为并将其投入生产,因为它恰好会给他们带来他们想要的结果。 您还面临其他挑战,例如,这些天,我们都在朝着这个目标迈进,我们称之为零竞争:试图以如此便宜和如此快速的速度做所有事情,以至于我们不采用低薪的方案。薪水的工作人员。 我并不是说这是一种卑鄙的态度,但我们并不是为每一项可能的工作都聘请专家。 曾几何时,与计算机有关的是火箭科学。 它涉及到爆炸性的声音,非常响亮的声音,进入太空的空间,或者工程师是具有高素质的男人和女人,他们都拥有学位并接受过严格的教育,以防止他们从事疯狂的事情。

这些天来,有很多人没有多年的经验,没有必要接受相同的培训或支持,就开始从事开发,设计和数据库工作。 这样一来,您只能遇到传统业余爱好者与专家的情况。 有一条著名的话,我实际上不记得是谁创造了这个报价,这行说:“如果您认为聘请专家来工作很昂贵,请等到您雇用了一些造成问题的业余人员之后,因此,SQL就有了这个问题,它非常非常容易学习,非常容易使用。 但是,在我看来,这不是一种完美的编程语言。 做到这一点非常容易,例如从任何地方选择一颗星星,然后将其全部放入您更熟悉的编程语言(例如PHP和Ruby或Python)中,然后使用您本来熟悉的编程语言来完成数据操作,而不是在SQL中执行更复杂的查询。 我们经常看到这种情况,然后人们想知道为什么数据库运行缓慢? 这是因为有一百万人正试图通过在线售票系统购买机票,该系统从任何地方都可以选明星。

现在,这是一个非常极端的示例,但是您从所有这些中了解了点。 因此,为了真正说明这一点,这里有一个我经常提到的例子。 我是数学的忠实粉丝,我喜欢混沌理论,也喜欢Mandelbrot集。 在右侧,有Mandelbrot集的演示文稿,我敢肯定我们都很熟悉。 在左侧,有一段SQL实际将其呈现出来。 现在,每次我将它放在屏幕上的某个地方时,我都会听到“哦,我的天哪,有人用SQL渲染了Mandelbrot系列,您是认真的吗? 好吧,其全部目的是说明我刚才在此处概述的内容,是的,事实上,您现在可以使用SQL编写几乎所有内容;这是对的。 这是一种非常发达的,功能强大的现代编程语言。 最初它是一种查询语言时,它只是为了获取数据而设计的。 因此,现在我们有了非常复杂的结构,有了存储过程,已经将编程方法应用于一种语言,因此对于不良的编程实践,缺乏经验,剪切和粘贴代码,低薪员工试图成为高薪员工,他们假装自己认识,但他们必须在工作中学习。

代码概要分析和我们称为调试的整个过程,并不是在发现使程序无法正常工作的错误,而是会损害系统和结构不良的代码的错误。 现在,当您查看此屏幕时,您会觉得这很可爱,并且您会想到:“哇,多么棒的图形,我很乐意运行它。”但是,想象一下在某种业务逻辑上运行。 它看起来很整洁,但是它讲的是一种数学图形表示的混沌理论,但是当您考虑将其潜在地用于某些业务逻辑中时,您会很快得到了解。 为了真正说明这一点–对不起,颜色相反,应该是黑色背景,绿色是绿色屏幕,但您仍然可以阅读。

我走了个例子,快速浏览一下一个例子,如果您真的很疯狂,没有任何经验,并且来自不同的编程背景,并且将C ++之类的东西应用于SQL,以真正说明我的观点,我从IDERA移交给了我们经验丰富的客人。 这是一个结构化查询,编写方式类似于C ++,但使用SQL编码。 它实际上执行,但是执行大约需要三到五分钟。 从表面上看,它从多个数据库,多个联接中拉回一行数据。

再说一遍,这就是说,如果您没有正确的工具,如果您没有正确的平台和环境来捕捉这些东西,那么它们就会投入生产,那么您将有100, 000人每天,每小时,每分钟或每分钟敲击一个系统,很快您就会遇到切尔诺贝利的经历,大型铁开始融化并埋葬在地球的核心,因为那段代码永远都不会投入生产。 对不起,您的系统和工具应该在接近测试之前就接受它-即使通过测试过程,甚至通过UAT和系统集成,也应该选择并突出显示那段代码,并且应该将某人放在一边,说,“看,这确实是很漂亮的代码,但是让我们得到一个DBA来帮助您正确构建该结构化查询,因为坦率地说,这太讨厌了。” URL在那里,您可以去看看-它被称为您编写的最复杂的SQL查询。 因为相信我,实际上确实可以编译,但是可以运行。 而且,如果您剪切并粘贴它并仅模拟数据库,那么它就值得一看。 如果您拥有监视数据库的工具,只需尝试在三到五分钟的时间内融化,然后回叫一行文本即可。

因此,总而言之,考虑到这一点,我的整个编码背景告诉我,您可以给人们开枪,如果他们不注意,他们会把自己开枪。 诀窍是向他们展示安全机制的位置。 有了合适的工具和合适的软件,在完成编码之后,您便可以查看代码,通过对代码进行性能分析可以发现问题,可以有效地发现与性能无关的错误,正如我所说的那样。以前,很久以前,您可以在绿色屏幕上查看。 你不能了 有成千上万的代码行,部署了成千上万的应用程序,在某些情况下有数百万个数据库,甚至超级人类实际上也无法手动完成此操作。 实际上,您确实需要唾手可得的正确的软件和正确的工具,并且团队需要使用这些工具,以便您可以找到这些问题并非常,非常快地解决它们,然后再进行讨论。罗宾·布洛尔(Robin Bloor)强调说,事情要么变得灾难性的,事情就爆炸了,或者更常见的是,当他们无法弄清事情为什么会发生时,它们就开始花费您很多美元,大量时间和精力并破坏了士气和东西。运行很长时间。

考虑到这一点,我将移交给客​​人,并期待听到他们如何解决此问题。 特别是我认为我们即将收到的演示。 埃里克,我会过去的。

埃里克·卡瓦纳(Eric Kavanagh):好的,伯特,把它拿走。

Bert Scalzo:好的,谢谢。 我是IDERA的Bert Scalzo,我是我们数据库工具的产品经理。 我将谈论调试。 我认为Robin之前说过的最重要的事情之一-的确,调试是繁琐且不琐碎的,而当您进行数据库调试时,它的数量级甚至更加繁琐又不平凡-因此,是一个重要的报价。

好。 我想从编程历史入手,因为很多时候我看到没有调试的人,他们没有使用调试器,他们只是使用所使用的语言进行编程,而且很多时候他们会跟我说,“嗯,那些调试器是新事物,我们还没有开始使用它们。”所以我要做的是向他们显示此时间线图,某种史前历史,老年,中世纪等。说我们在编程语言方面在哪里。 从1951年开始,我们就拥有非常古老的语言,包括汇编代码,Lisp,FACT和COBOL。 然后我们进入下一组,Pascals和Cs,然后进入下一组,C ++,看看那个问号在哪里–这个问号大约在1978年到1980年左右。在那个范围内,调试器可供我们使用,然后说:“嘿,我没有使用调试器,因为这是其中的新事物之一。”那么,您一定要在1950年代就开始编程,因为只有这样,您才能摆脱这种要求。

现在,关于该图表的另一个有趣之处是Dez对Grace Hopper进行了评论,我实际上知道Grace,所以这很有趣。 然后我笑的另一件事是他谈论电传打字,而我坐在那儿说:“伙计,这是我们有史以来生产力上的最大飞跃,当我们从卡片到电传打字时,这是有史以来最大的飞跃。 “因此,我已经在这里使用所有语言进行编程,包括SNOBOL,这是CDC,Control Data Corporation,这是以前从未有人听说过的,所以我想对于这个行业来说我已经有点老了。

Dez Blanchfield:我要说的是,您在我们这里年纪大了。

伯特·斯卡佐(Bert Scalzo):是的,我告诉你,我感觉就像辛普森爷爷一样。 因此,我着眼于调试,并且有不同的调试方法。 您可能正在谈论我们都认为进入调试器并逐步执行代码的传统想法。 但是,人们也会使用他们的代码。 在那儿,您可以将语句粘贴到代码中,也许您可​​以生成输出文件,跟踪文件或其他内容,从而对代码进行检测。 我认为这是调试,这有点麻烦,但确实很重要。 而且,我们还有著名的打印语句:您看着人们实际上将打印语句放入其中,而我实际上已经看到了一个工具-它是数据库工具-如果您不知道如何使用调试器,按下一个按钮,它将为您在代码中粘贴打印语句,然后在您完成操作后,按下另一个按钮,将其删除。 因为这就是很多人调试的方式。

而且我们进行调试的原因有两个:首先,我们必须找到使我们的代码无效的东西。 换句话说,通常这意味着存在逻辑错误或我们错过了业务需求,但实际上是代码无效。 它没有达到我们的预期。 还有一次我们去调试,这是为了提高效率,这可能是一个逻辑错误,但这是我做对的事情,只是返回得还不够快。 现在,我指出这一点是因为分析器可能适合第二种情况,我们将同时讨论调试器和分析器。 另外,还有远程调试的概念。 这很重要,因为很多时候,如果您坐在个人计算机上,并且正在使用调试器,该调试器会访问数据库中实际在其上执行代码的数据库,那么您实际上正在执行所谓的远程调试。 您可能没有意识到,但这就是正在发生的事情。 然后,对于这些调试器来说,具有断点,观察点,介入和逐步过渡以及其他一些常见的事情是很常见的,我将在稍后的屏幕快照中显示这些内容。

现在,进行概要分析:您可以通过两种不同的方式进行概要分析。 有人会说工作负载捕获并在捕获所有内容的地方重播,这被视为概要分析。 我的经验是,采样完成后会更好。 没有理由去捕捉每一个语句,因为有些语句可能运行得如此之快以至于您根本不在乎,所以您真正想要看到的是那些不断出现的语句,因为他们跑得太久。 因此,有时分析可能​​意味着采样而不是运行整个过程。 通常,您将获得某种可以使用的输出,现在在IDE开发环境中它是可视的,在该输出中,您可以像直方图所示地了解各行代码的性能,但仍然可以是因为它会生成跟踪文件。

Profilers于1979年首次出现。因此,它们也存在了很长时间。 非常适合发现资源消耗或性能问题,换句话说,就是效率。 一般而言,它与调试器是分开的,并且与调试器不同,尽管我与同时进行调试的调试器一起工作。 虽然我认为概要分析器是这两个工具中比较有趣的一个,但是如果我觉得调试的人员不足,则肯定没有足够的人员进行概要分析,因为似乎十分之十的调试器会进行概要分析。 真可惜,因为剖析确实可以带来巨大的改变。 现在,正如我们之前所讨论的,数据库语言已经有了SQL,并且我们已经在这种情况下将圆头钉强制插入方孔并将其变成一种编程语言,并使用了Oracle。 那是PL / SQL –是过程语言SQL –是SQL Server,是Transact-SQL,是SQL-99,是SQL / PSM –我认为,这是过程存储模块。 Postgres给它起了另一个名字,DB2又给了它一个名字,即Informix,但是重点是每个人都使用了3GL类型的构造。 换句话说,FOR循环,变量声明以及SQL以外的所有其他内容现在已成为这些语言中SQL的一部分。 因此,您需要像Visual Basic程序一样能够调试PL / SQL或Transact-SQL。

现在,对于数据库对象来说,这很重要,因为人们会说:“好吧,我必须在数据库中调试什么?”答案是,好吧,无论您将什么作为代码存储在数据库中,如果我正在做的话。 T-SQL或PL / SQL –我将对象存储在数据库中,它可能是存储过程或存储函数。 但是也有触发器:触发器有点像存储过程,但是会在某种事件上触发。 现在,某些人会在触发器中放入一行代码并调用存储过程,以便保留所有存储的代码和过程,但这是相同的概念:触发器仍然可以引发整个事情。 然后,作为Oracle,他们有一个称为包的东西,如果您愿意的话,它有点像一个库。 您将50或100个存储过程放在一个分组(称为包)中,因此有点像库。 因此,这是旧的调试器; 这实际上是一个工具,可以实际使用并将所有这些调试语句粘贴在您的代码中。 因此,在所有看到调试块的地方,不要删除,自动调试器的启动和跟踪,这些都被某种工具卡住了。 除此之外,这是少数代码,这就是非手动调试方法。

我提出这个问题的原因是,如果您尝试手动执行此操作,则实际上您将要键入比这些代码更多的调试代码以放入所有这些打印语句中。 因此,虽然这可能行得通,而且总比没有好,但是这是调试的一种非常困难的方法,尤其是因为如果这件事花了10个小时才能运行,而问题出在第三行,该怎么办? 如果我正在进行一个交互式调试会话,那么我会在第三行-五分钟之内就知道了-嘿,这里有问题,我可以退出。 但是,有了这个,我必须等待它运行,一直到完成为止,然后我要查看一些可能包含所有这些打印语句的跟踪文件,并尝试在草垛。 再有,这总比没有好,但是它并不是最佳的工作方式。 现在,这就是上一张幻灯片中的文件。 换句话说,我运行了程序,并且在此跟踪文件中只有一堆打印语句,并且我可能无法虹吸通过它并找到我需要查找的内容。 因此,我不确定这是否是您想要的工作方式。

现在,使用交互式调试器,如果您使用过Visual Studio之类的程序来编写程序或Eclipse,那么您已经有了调试器,并且将它们与其他语言一起使用了,只是不想在这里与数据库一起使用它们。 那里有一些工具,例如我们的DB Artisan和我们的Rapid SQL,这是这里的Rapid SQL,其中有一个调试器,您可以在左侧看到一个名为“检查重复项”的存储过程。基本上,它只是去查看一下表中是否有多行具有相同的电影标题。 因此,该数据库用于电影。 您会在右侧的顶部三分之一中看到源代码,在中间有我的监视变量和调用堆栈托盘,然后在底部找到我得到了一些输出信息。 而且这里重要的是,如果您查看第一个红色箭头,如果我将鼠标悬停在变量上,那么我逐步浏览代码时,实际上可以及时看到该变量中的值。 这真的很有用,然后我可以一次遍历代码,而不必说执行,可以说一步,让我看看发生了什么,一步到另一行,让我看看发生了什么,而我正在数据库中执行此操作。 即使我坐在PC上的Rapid SQL上并且数据库在云中,我仍然可以进行远程调试,并从此处查看和控制它,并像使用其他任何语言一样进行调试。

现在,那里的下一个箭头–您会看到指向右侧的小箭头,指向该DBMS输出,这就是我的光标所在的位置–换句话说,我已经踩到了,那就是我的位置此时此刻。 因此,如果我说“再次执行”,我将转到下一行。 现在,在其下方,您将看到红点。 好吧,这是一个断点,上面写着:“嘿,我不想越过这些行。”如果我只想跳过所有内容并到达那个红点,则可以单击运行按钮,它将运行如果设置了任何断点,则从此处到终点或断点,然后它将停止并让我再次执行步进。 之所以如此重要和强大,是因为当我执行所有这些操作时,中间甚至底部(但最重要的是中间)发生的事情都会改变,并且我可以从变量中看到值,我可以看到我的调用堆栈跟踪,所以当我逐步执行代码时,所有这些信息都显示在这里,因此我实际上可以看到并感觉到并了解正在发生的事情以及代码的实际运行方式在执行时工作。 通常,我可以找到一个问题,如果有问题,或者我足够好解决这个问题。

好的,现在我要讨论一个探查器,在这种情况下,这是一个我可以通过调试器看到的探查器。 还记得我说过,有时他们是分开的,有时他们可以在一起吗? 在这种情况下,我再次使用Rapid SQL,可以看到左侧行号旁有一个空白。 那就是执行每一行代码所需的秒数或微秒数,我可以清楚地看到,我所有的时间都花在了这个FOR循环中,我从表中选择了所有内容。 因此,在FOR循环中发生的一切可能都是我需要研究的,如果我可以做得更好,它将分红。 通过处理那些0.90或0.86的行,我不会得到任何改善。 那里没有太多时间。 现在,在这种情况下,又是在Rapid SQL中,您将看到如何在调试时混合进行性能分析。 现在,Rapid SQL还可以让您以另一种方式来实现。 Rapid SQL允许您说:“您知道吗? 我不想进入调试器,我只想运行它,然后以图形或视觉方式查看相同类型的信息。”

您会看到我不再在调试器中,并且它运行程序,执行完成后,它给了我一些图表来告诉我一些事情,因此我可以看到我有一条看起来像正在占用的语句大部分饼图,如果我看的话,我会看到该网格朝着底部的第23行,再次出现FOR循环:他占用的时间最多,实际上,他是深红色咀嚼了所有饼图。 因此,这是进行概要分析的另一种方法。 我们碰巧在我们的工具中称该代码为“代码分析师”。 但这基本上只是与调试器分开的分析器。 有些人喜欢第一种方式,有些人喜欢第二种方式。

为什么我们要进行调试和分析? 这不是因为我们要编写世界上最出色的代码并获得加薪–这可能是我们的原因,但这并不是您这样做的真正原因–您向企业保证您会做正确的事,使您的程序有效。 那就是您将使用调试器的目的。 此外,业务最终用户; 他们不是很耐心:他们甚至在按下键之前就想要结果。 我们应该阅读他们的想法,并立即做所有事情。 换句话说,它必须高效。 因此,这就是我们将使用探查器的目的。 现在,如果没有这些工具,我确实相信您是这个穿着弓箭的西装的人,并且您正在向目标射击,并且蒙住了双眼。 因为您将如何仅通过查看静态代码来查找程序的执行方式,以及如何仅通过查看静态代码来找出哪一行真正花费了最多的执行时间呢? 代码审查可能会或可能不会解决其中一些问题,但是不能保证代码审查会找到所有这些问题。 使用调试器和探查器,您应该能够找到所有这些错误。

好的,我将在这里做一个真正的快速演示。 我并不是要推出产品,我只是想向您展示调试器的外观,因为很多时候人们会说:“我以前从未见过这些调试器。”而且在屏幕快照中看起来很漂亮,但是运动时会是什么样子? 因此,在我的屏幕上,我正在运行我们的DB Artisan产品。 我们也有一个调试器。 DB Artisan对于DBA而言意味着更多,Rapid SQL对开发人员而言意味着更多,但是我已经看到使用DB Artisan的开发人员,以及我看到使用Rapid的DBA。 因此,不要被产品赶上。 在这里,我可以选择进行调试,但是在启动调试之前,我将提取此代码,以便您可以在开始运行之前查看代码的样子。 因此,这里的代码与屏幕快照中的代码完全相同,这是我检查是否重复的代码。 我想调试它,所以按调试。 而现在,这需要花一点时间,您会说:“嗯,为什么要花一点时间?”请记住远程调试:调试实际上是在数据库服务器上进行的,而不是在PC上进行的。 因此,它必须经过并在该处创建一个会话,创建一个远程调试对象,将我的会话挂接到该远程调试会话并建立一个通信通道。

所以,现在,这是我的箭头,它位于第一行的顶部,这就是我在代码中的位置。 然后,如果我按了其中的第三个图标,您会看到箭头刚刚移动,如果我一直按它,您将看到它一直在移动。 现在,如果我想一直进行到此FOR循环,因为我知道问题出在哪里,那么我可以设置一个断点。 我以为我定了。 哦,拍摄,我将一个屏幕捕获键映射到了与调试器相同的键,这就是造成混乱的原因。 好的,所以我只是在此处手动设置一个断点,所以现在不用一步一步,一步一步地走,直到到达那儿为止,实际上我只能说“继续并运行该程序”,它将停止。 注意,它一直将我移动到断点的位置,所以现在进入运行此循环的上下文,我可以看到所有变量都设置为什么,这不足为奇,因为我已将它们全部初始化归零。 现在,我可以进入此循环并开始查看该循环内部的情况。

因此,现在要从我的租金中进行选择计数,然后我可以将鼠标悬停在那个家伙上,看一下,他是两个,两个大于一个,因此很可能将执行此代码的下一部分。 换句话说,它发现了一些东西。 我将继续进行下去。 我不想浏览这里的所有内容; 我想向您展示的是调试器完成后,它像普通程序一样完成了。 我已经设置了断点,所以当我说运行时,它就回到了下一个断点。 我让它运行到最后,因为我希望您看到的是调试器不会改变程序的行为:完成运行后,如果我没有运行它,我应该得到完全相同的结果在调试器中。

然后,我将暂停演示并返回,因为我们想确保我们有时间提问和回答。 因此,我将打开它以提出问题和答案。

埃里克·卡瓦纳(Eric Kavanagh):好吧,罗宾(Robin),也许您问一个问题,然后是德兹(Dez)的几个问题?

罗宾·布卢尔(Robin Bloor):是的,当然,我觉得这很有趣。 我已经使用过类似的东西,但是我从未在数据库中使用过类似的东西。 您能给我一些人们使用探查器做什么的想法吗? 因为这就像他们在查看-因为我想是的-他们在查看性能问题,这是否可以帮助您区分数据库何时花费时间和代码何时花费时间?

Bert Scalzo:您知道,这是一个很棒的问题。 假设我在Visual Basic中工作,而在Visual Basic中,我将称为Transact-SQL或PL / SQL。 让我来做PL / SQL,因为Oracle在Microsoft工具中并不总是很好地发挥作用。 我可能正在分析我的Visual Basic代码,那里的配置文件可能会说:“嘿,我调用了此存储过程,它花了太长时间。”但是随后我可以进入存储过程,并可以对存储的数据库进行配置文件步骤,然后说:“好的,在这里的100条语句中,这是引起问题的5条语句。”因此,您可能必须组队,在其中必须使用多个分析器。

这个想法是,如果您被告知性能问题出在数据库中,那么数据库概要文件可能会帮助您在大海捞针中找到实际上有问题的语句所在的地方。 我告诉您另一个与性能分析有关的事情:如果您有一段代码被调用一百万次,但是每百万次仅花费一微秒的时间,但是被调用一百万次,则分析器将显示,那么事情就运行了这么长时间。 因此,尽管代码可能非常高效,但是您可能会说:“哦,我们对这种代码的调用太频繁了。 也许我们应该只每隔一段时间调用一次,而不是每次处理记录时都调用它。” 因此,您实际上可以找到在哪里经常调用高效代码,而这实际上是性能问题。

罗宾·布洛尔:是的,太好了。 我没做过 您当然可以看到,当我遇到数据库问题时,就像以某种方式处理数据库或处理代码一样。 我永远无法同时处理这两个问题。 但是,我再次没有做过-我从未真正参与过构建存储过程的应用程序,所以我想我从未真正遇到过使我发狂的问题,即您将代码在数据库和程序之间拆分。 但是,做所有吧-我想答案是肯定的,但这是开发团队活动的一部分,当您以某种方式尝试修复已损坏的问题,或者尝试引入新的解决方案时,一起申请。 但这是否与我在环境中期望的所有其他组件相匹配? 我是否可以期望将其与我的所有测试包以及我将要进行的所有其他工作以及项目管理工作一起剪辑,这是如何将这些剪辑在一起的?

Bert Scalzo:是的,它可以成为任何结构化过程的一部分,以进行您的编程或开发工作。 有趣的是,上周我有一个正在构建Web应用程序的客户,并且从历史上看,他们的数据库很小,因此,他们不是很好的程序员这一事实从未伤害过他们。 嗯,他们的数据库已经发展了很多年,现在,在您说“登录并给我一些数据以供查看”到实际出现屏幕之间,Web页面花费了20秒。性能问题。 他们知道问题不在他们的Java或其他任何地方。 但是他们有成千上万个存储过程,因此他们必须开始对存储过程进行概要分析,以找出为什么此网页需要20秒才能显示出来? 实际上,我们发现他们在其选择语句之一中加入了笛卡尔坐标,但并不知道。

罗宾·布卢尔(Robin Bloor):哇。

伯特·斯卡尔佐(Bert Scalzo):但是有人曾经对我说 “那么他们怎么能进行笛卡尔加入而又不知道呢?”这听起来真的很可怕; 有时候,对SQL不太熟悉的程序员会做一些事情,例如给我笛卡尔联接,但随后只给我第一条记录,所以我知道我得到了一些东西,而我只需要第一条。 因此,他们没有意识到他们只是带回了十亿条记录,或者浏览十亿条记录,因为他们得到了他们感兴趣的记录。

罗宾·布卢尔(Robin Bloor):哇,我知道,这就是所谓的-恩,这就是Dez所从事的工作,就人们所知,他们的技能可能不尽如人意。 如果您是一名程序员,则应该知道发出任何命令的含义。 我的意思是,真的没有任何愚蠢的借口。 我还假设您在某种程度上与语言无关,因为这一切都集中在数据库方面。 我说的对吗? 无论您在编码方面使用什么,都一样吗?

Bert Scalzo:绝对可以在Fortran或C或C ++中执行此操作。 实际上,在某些Unix上,您甚至可以为它们的脚本语言执行此操作。 他们实际上提供了相同的工具。 然后,我想再说一遍,您无可辩驳。 我要给程序员一个休息时间,因为我不喜欢把程序员扔在公车上。 但是问题实际上是学术环境,因为当您学习如何成为一名程序员时,就会被教导一次记录思维。 不会教您集合思维,这就是结构化查询语言或SQL处理集合的方式。 这就是为什么我们需要并集,相交和减号运算符。 有时候,对于一个从来没有想到集的人来说,戒烟,放弃一次记录处理并使用集会非常困难。

罗宾·布卢尔(Robin Bloor):是的,我支持你。 我的意思是,我现在明白了,这是一个教育问题; 我认为这完全是一个教育问题,我认为程序员进行程序思考是很自然的。 SQL不是程序性的,而是声明性的。 您实际上只是在说:“这就是我想要的,我不在乎您如何去做,”您知道吗? 鉴于使用编程语言,您经常会袖手旁观,而在循环时却陷入甚至无法管理计数的细节中。 我将继续-

伯特·斯卡尔佐:不,好的,继续。

是的,我要说的是您提出了另一个示例,即分析器很好地捕获了这种一次记录处理的功能。 有时,擅长一次记录逻辑的程序员无法弄清楚如何执行SQL程序。 好吧,假设他进行了两个FOR循环并基本上进行了联接,但他在客户端进行了联接。 因此,他的作用与联接相同,但他自己进行,配置文件可以捕获该联接,因为与让数据库服务器为您完成连接相比,您可能最终会花费更多的时间手动进行联接。

Robin Bloor:是的,那将是一场灾难。 我的意思是,您只会四处走动。 脱粒总是不好的。

无论如何,我会转交给Dez; 我确定他有一些有趣的问题。

Dez Blanchfield:谢谢,是的。 我将与您一起参加不把总线扔掉的程序员。 我的意思是,我一生从事编码工作的时间已经很多年了,在每个级别上,您都知道,是否像您所说的那样,坐在Unix计算机的命令行上,在某些情况下,我甚至参与其中在从一个硬件平台到另一个硬件平台的Unix的两个不同端口中。 您可以想象我们在那里遇到的挑战。 但实际情况是,这是世界上每个编码人员和脚本编写人员的牢狱之灾。 确切地说,这是一门火箭科学,每时每刻都要写得很紧。 还有诸如Dennis Ritchie和Brian Kernahan之类的人的著名故事,他们独立地编写某些代码,然后在喝咖啡时进行代码审查聊天,发现他们在完全相同的程序中编写了完全相同的代码,以完全相同的方式。 他们是用C语言编写的。但是,纯粹的编程水平很少存在。

事实是,每天只有24小时,一周只有7天,我们只需要完成工作即可。 因此,不仅是传统的程序员,DBA,编码人员,脚本编写者,系统管理员,网络管理员和安全人员,而且这些日子一直贯穿到公民数据方面。 我们听说,每个人都只是想尽自己的职责。 因此,我认为整个事情的最大收获就是我喜欢您的演示,我喜欢您刚才离开我们这里的收获,与Robin讨论了这一事实,它确实具有特殊之处-也许没有那么多一个利基市场-但它适用的广阔空间,包括固定代码,SQL和数据库。 但是,听到您说可以在shell脚本中戳它并发现一些问题,我感到非常兴奋,因为您知道,在当今的时代,我们一直在以最低的成本来努力。

之所以可以在某处购买6美元的衬衫,是因为有人构建了一个足够便宜的系统,可以实际制造,运输和物流配送,销售和零售,并通过在线付款来获得这6美元的衬衫。 如果您让人们每年以完美的方式编写代码,年薪40万美元,那将不会发生。 这只是整个开发。 因此,在这一点上,我想我真的很希望您能给我们提供更多的见解的一个问题是,您目前所看到的正在部署此类工具进行剖析的人员的广度和影响范围是什么代码并查找性能问题? 最初,从历史上看,它们来自哪里? 他们曾经是大型工程公司吗? 然后,向前发展,是这样吗,我是否认为越来越多的公司正在实施此工具或这些工具以尝试帮助编码人员,他们知道他们只是在做事情才能完成工作,这是正确的吗?然后把它拿出来 有时我们需要一张监狱卡吗? 我是否认为历史上我们更注重工程和发展? 现在,正如罗宾所说,我们的学习方法有所减少,现在它是自学的或剪切粘贴的代码,还是只是构建了东西? 这与现在正在使用该产品的人匹配吗?

Bert Scalzo:好的 ,是的。 我会举一个非常具体的例子,我们只是想完成工作,因为商务人士不希望完美。 这有点像是计算机化的国际象棋游戏:国际象棋游戏并不是在寻找完美的答案。 它会在合理的时间内找到足够好的答案,这就是我们编程的方式。 但是我现在发现的是,大多数人没有说要在他们的单元测试中使用探查器-这就是我会做的,因为我不认为这是浪费时间-发生的是现在,如果幸运的话,有时需要在集成测试或压力测试期间完成。 但是在大多数情况下,它是升级的一部分,有些东西已经投入生产,它运行了一段时间,甚至可能运行了多年,现在运行不佳,现在我们将对其进行概要分析。 这似乎是现在更常见的情况。

Dez Blanchfield:是的,我认为“技术债务”一词可能是您所不熟悉的。 我知道罗宾,我当然知道。 我认为这些天,特别是在开发和系统构建的敏捷方法中,对我而言,技术债务的概念现在是非常现实的事情,而我们实际上在项目中对此予以考虑。 我知道,我的意思是,我们拥有自己的项目,例如Media Lens等,我们每天都在进行编码,并且Bloor Group开展了各种各样的工作。 每当我们要构建某些东西时,我们都会对其进行观察,观察,并且始终从这样的角度进行研究:现在修复此问题将花费我多少钱,而我只能从中获得它吗?可以从那里拿出来,然后观察一下这东西是否会破裂。 并继承这些技术债务,我知道以后必须回头再解决。

我的意思是,我在过去的七天内做到了:我编写了一些工具和脚本,我编写了几段Python语言,并将其部署到Mongo后端,确保它很好,干净且安全,但是它知道我需要该功能才能正常工作,只是得到了我需要完成的查询; 那才是我真正的痛苦所在。 因此,您承担了这笔技术债务,我认为现在这不仅仅是偶然的事情,我认为这是现在发展的DNA的一部分。 人们只是(而不是毫不客气地)只接受技术债务,这是正常的操作方式,并且他们必须承担责任。 这是您承担技术债务的地方。 而且我认为您在演示中向我们展示的很棒的事情是,您可以从字面上描述和观察运行某项操作需要多长时间。 那可能是我最喜欢的事情之一。 我的意思是,我实际上已经构建了性能分析工具-我们曾经在Sed和Lex和Orc中构建工具来运行我们的代码,并在可用此类工具之前查看循环的位置-以及何时构建了代码并查看您自己的代码,您将非常擅长查看自己的代码。 但这不是现在。 考虑到这一点,是否有特定的细分市场比其他任何细分市场占有更多的份额? 像群众一样

伯特·斯卡尔佐(Bert Scalzo):哦,是的,我有-我将为您做一个类比,并向您展示非程序员一直都在这样做。 “因为如果我要教调试器和性能分析类或会话,我会问人们,“好吧,这里有多少人使用Microsoft Word,并且故意从未使用过拼写检查程序?”而且没人举手,因为众所周知,编写文档时会犯英文错误,因此每个人都使用拼写检查器。 我说:“好吧,当您在像Visual Basic这样的IDE中编写文本时,为什么不使用调试器呢? 是同一回事,就像拼写检查器一样。”

Dez Blanchfield:是的,实际上,这是一个很好的类比。 我并没有真正考虑过,我不得不承认我实际上使用了一些工具来做类似的事情。 实际上,我最喜欢Eclipse的ODF就是在其中剪切并粘贴代码,然后去寻找可以立即突出显示的内容,并意识到我在某些类调用中输入了错误。 而且,但现在有趣的是,使用这样的工具,您可以实时进行操作,而不必稍后再查看它,这样可以很好地提前了解它。 但是,是的,这就像将文本放入文字处理器中,这是一个很好的类比,因为这是一个有趣的唤醒呼叫,只是意识到您已经犯了一些错字甚至语法错误,对吗?

伯特·斯卡尔佐:没错。

Dez Blanchfield:那么,我想您现在是否看到更多的提速建议,我的意思是,在我为参加者进行问答之前,我的最后一个问题是。 如果您打算就此方法提出一些建议(我认为这是夸夸其谈的话),是不是您在开发之前就开始了并在开发过程中实施了这种情况? 或者是您主要是要建造,搬家,建造一些东西然后再进行剖析? 我怀疑是早起的情况,并确保您的代码预先干净。 还是在这种情况下,他们应该考虑部署后的这一部分?

伯特·斯卡尔佐(Bert Scalzo):理想情况下,他们会提前做,但是由于每个人都在忙碌而忙碌的世界中,他们只能完成工作,因此他们倾向于不这样做,直到遇到无法解决的性能问题为止向虚拟机添加更多的CPU和内存。

Dez Blanchfield:是的。 因此,实际上您提到了一些有趣的事情,如果可以的话,我可以吗? 您之前提到过,它可以在任何地方运行,并且可以在后端与数据库对话。 因此,这对于我们现在谈论的那种双峰概念(内部部署/非内部部署云)还是很满意的,无论从外观上还是最终,如果它可以与后端对话并看到代码,它不是很在乎,是吗?

Bert Scalzo:好的 ,是的,您可以在云中运行它。

Dez Blanchfield:太好了 ,因为我认为这就是我们新的勇敢世界前进的方向。 所以,埃里克。 我现在回头再问您,我们在这里有几个问题,即使我们已经过去了一个小时,我希望我们的与会者仍然与我们在一起。

埃里克·卡瓦纳(Eric Kavanagh):是的,那里有几个人,我只想简单说一句:伯特,我认为隐喻,您对使用拼写检查的类比坦率地讲得很出色。 坦率地说,这值得一两个博客,因为这是一种框架,可以很好地说明您正在做的事情的上下文,它的价值以及使用调试器的最佳实践。定期吧? 我敢打赌,当你扔掉那个头时,你会点头,对吗?

伯特·斯卡尔佐(Bert Scalzo):绝对是,因为我告诉他们,“为什么我要对文档进行拼写检查? 我不想被愚蠢的拼写错误所困扰。”好吧,他们不想被愚蠢的编码错误所困扰!

埃里克·卡瓦纳(Eric Kavanagh):对。 确实是的。 好的,伙计们,我们在这里已经花了一个小时零五分钟,非常感谢你们所有人的时间和关注。 我们会存档所有这些网络聊天记录,随时可以随时回来查看它们。 找到这些链接的最佳地点可能是techopedia.com,因此我们将在此处将其添加到此列表中。

亲爱的,我们将向您告别。 再次感谢Bert,感谢IDERA的朋友。 实际上,下一次我们会与您交谈,下周我们会与您交谈。 照顾自己! 再见。

快速响应:对数据库进行调试和分析以营救