C#获取程序运行目录
第一种方法: string AppPath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase; if (AppPath.EndsWith("\\") || AppPath.EndsWith("/")) AppPath= AppPath.Substring(0, AppPath.Length – 1); 第二种方法:string AppPath = Environment.CurrentDirectory; // 结尾不带"/" 第三种方法:string AppPath = Directory.GetCurrentDirectory();//获取应用程序的当前工作目录 Directory.SetCurrentDirectory(localFolder);
View Detailsc# 不规则窗口实现
相信每个编程爱好者都希望自己的程序不仅性能优越而且有一个美观的界面,一个区别于别人的程序的个性化的界面。然而以前烦琐的API调用和大量的代码使大家望而却步。现在好了,在C#中通过少量的代码就可以实现不规则窗体的制作。如果您有兴趣就接着往下看吧。 一、在说我用的方法前,我不得不说一下另一种方法,这种方法在实现不规则窗体自身显示效果(即除开窗体的移动、最大最小话、关闭等)时是不用编代码 的。非常简便,但它的致命缺点就是要要求程序运行环境在24位色以下,否则不规则窗体的透明部分就会显示出来,窗体会非常难看。 方法1:步骤1:先用图象处理软件制作您的不规则窗体的位图BMP(最好是位图,其它的我没有试过:))。制作时请注意将背景色(即需要设置成透明的颜色部分)设置成与非背景图片颜色反差较大的颜色,并且使用一种容易记忆的颜色。如下图: 图中黄颜色背景将要设置成透明部分 步骤2:新建windows应用程序。创建windows窗体并设置窗体基本属性。(1)将 FormBorderStyle 属性设置为 None。(2)将窗体的 BackgroundImage 属性设置为先前创建的位图文件。不必将文件添加到项目系统中;这将在指定该文件作为背景图像时自动完成。(3)将 TransparencyKey 属性设置为位图文件的背景色,本例中为黄色。(此属性告诉应用程序窗体中的哪些部分需要设置为透明。 )上面两个步骤已经完成了不规则窗体自身显示效果的制作,此刻您要做的就是为窗体添加移动、关闭、最大最小化的事件。这个将在方法2中详细介绍。方法1在24位色以下的环境中可以显示正常,但在24位色以上时黄色背景不能消失,所以方法1不能胜任24位色以上环境。为了解决这个问题,我们可以用到方法2。方法2步骤1:同方法1,先用图象处理软件制作您的不规则窗体的位图BMP步骤2:创建windows应用程序。创建windows窗体。由于方法2是调用类来实现制作不规则窗体,所以您只需要在窗体的LOAD事件中加入以下代码:private void login_Load(object sender, System.EventArgs e){//初始化调用不规则窗体生成代码BitmapRegion BitmapRegion =new BitmapRegion();//此为生成不规则窗体和控件的类BitmapRegion.CreateControlRegion(this,new Bitmap("HMlogin.bmp")); }其中"HMlogin.bmp"为您制作的位图。 下面就是文件BitmapRegion.cs 我在网上找到的是英文的,自己翻译了一下,英语水平有限,有错的地方还请大家指出。 /***************************************************************************************///// 功能描述:不规则窗体和控件的生成类// 撰 写 人:不祥(网上搜集)// //// 修改说明:2005.8.31 杨丹翻译和修改///***************************************************************************************/using System; using System.Drawing; using System.Drawing.Drawing2D; using System.Windows.Forms; { /// <summary> /// Summary description for BitmapRegion. /// </summary> public class BitmapRegion { public BitmapRegion() {} /// <summary> /// Create and apply the region on the supplied control/// 创建支持位图区域的控件(目前有button和form)/// </summary> /// <param name="control">The Control object to apply the region to控件</param> /// <param […]
View Details如何编写单元测试用例(白盒测试)
前段时间公司进行有关测试的培训,集成测试,性能测试,压力测试说了很多。由于本人还处于Coder阶段,只是对单元测试有了些了解。写下来怕以后自己忘记了。都是些自己的看法,不一定准确,欢迎高手指教。 一、 单元测试的概念 单元通俗的说就是指一个实现简单功能的函数。单元测试就是只用一组特定的输入(测试用例)测试函数是否功能正常,并且返回了正确的输出。 测试的覆盖种类 1.语句覆盖:语句覆盖就是设计若干个测试用例,运行被测试程序,使得每一条可执行语句至少执行一次。 2.判定覆盖(也叫分支覆盖):设计若干个测试用例,运行所测程序,使程序中每个判断的取真分支和取假分支至少执行一次。 3.条件覆盖:设计足够的测试用例,运行所测程序,使程序中每个判断的每个条件的每个可能取值至少执行一次。 4.判定——条件覆盖:设计足够的测试用例,运行所测程序,使程序中每个判断的每个条件的每个可能取值至少执行一次,并且每个可能的判断结果也至少执行一次。 5.条件组合测试:设计足够的测试用例,运行所测程序,使程序中每个判断的所有条件取值组合至少执行一次。 6.路径测试:设计足够的测试用例,运行所测程序,要覆盖程序中所有可能的路径。 用例的设计方案主要的有下面几种:条件测试,基本路径测试,循环测试。通过上面的方法可以实现测试用例对程序的逻辑覆盖,和路径覆盖。 二、开始测试前的准备 在开始测试时,要先声明一下,无论你设计多少测试用例,无论你的测试方案多么完美,都不可能完全100%的发现所有BUG,我们所需要做的是用最少的资源,做最多测试检查,寻找一个平衡点保证程序的正确性。穷举测试是不可能的。 所以现在进行单元测试我选用的是现在一般用的比较多的基本路径测试法。 三、开始测试 基本路径测试法:设计出的测试用例要保证每一个基本独立路径至少要执行一次。 函数说明 :当i_flag=0;返回 i_count+100 当i_flag=1;返回 i_count *10 否则 返回 i_count *20 输入参数:int i_count , int i_flag 输出参数: int i_return; 代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
int Test(int i_count, int i_flag) { int i_temp = 1; while (i_count>0) { if (0 == i_flag) { i_temp = i_count + 100; break; } else { if (1 == i_flag) { i_temp = i_temp * 10; } else { i_temp = i_temp * 20; } } i_count--; } return i_temp; } |
1.画出程序控制流程图 图例: 事例程序流程图: 圈中的数字代表的是语句的行号,也许有人问为什么选4,6,13,8……作为结点,第2行,第3行为什么不是结点,因为选择结点是有规律的。让我们看程序中;第2行,第3行是按顺序执行下来的。直到第4行才出现了循环操作。而2,3行没有什么判断,选择等分支操作,所以我们把2,3,4全部合并成一个结点。其他的也是照这个规则合并,然后就有了上面的流程图。 2.计算圈复杂度 有了图以后我们要知道到底我们有写多少个测试用例,才能满足基本路径测试。 这里有有了一个新概念——圈复杂度 圈复杂度是一种为程序逻辑复杂性提供定量测试的软件度量。将该度量用于计算程序的基本独立路径数目。为确保所有语句至少执行一次的测试数量的上界。 公式圈复杂度V(G)=E-N+2,E是流图中边的数量,N是流图中结点的数量。 公式圈复杂度V(G)=P+1 ,P是流图G中判定结点的数量。 通俗的说圈负责度就是判断单元是不是复杂,是不是好测试的标准。一般来说如果圈复杂度如果大于20就表示这个单元的可测试性不好,太复杂(也许有人觉得无所谓,但是如果你们公司实行了CMMI5的话,对这个是有规定的)。 从图中我们可以看到, V(G)=10条边-8结点+2=4 V(G)=3个判定结点+1=4 上图的圈复杂图是4。这个结果对我们来说有什么意义呢?它表示我们只要最多4个测试用例就可以达到基本路径覆盖。 3.导出程序基本路径。 现在我们知道了起码要写4个测试用例,但是怎么设计这4个测试用例? 导出程序基本路径,根据程序基本路径设计测试用例子。 程序基本路径:基本独立路径就是从程序的开始结点到结束可以选择任何的路径遍历,但是每条路径至少应该包含一条已定义路径不曾用到的边。(看起来不好理解,让我们看例子)。 让我们看上面的流程图:从结点4到24有几条路径呢? 1 B(4,24) 2 C,E,J(4,6,8,24) 3 C,D,F,H,A,B(4,6,13,15,22,4,24) 4 C,D,G,I,A,B(4,6,13,19,22,4,24) 还有吗?? 5 C,D,C,I,A,C,E,J(4,6,13,19,22,4,6,8,24)算吗? 不算,为什么?因为上面的4条路径已经包括了所有的边。第5条路径已经不包含没有用过的边了。所有的路径都遍历过了。 好了,现在我们有了4条基本独立路径根据独立路径我们可以设计测试用例。 1 B(4,24) 输入数据:i_count=0,或者是i_count<0的某一个值。 预期结果:i_temp=0. 2 C,E,J(4,6,8,24) 输入数据: i_count =1;i_flag=0 预期结果:i_temp=101. 3 C,D,F,H,A,B(4,6,13,15,22,4,24) 输入数据: i_count =1;i_flag=1 预期结果:i_temp=10. 4 C,D,G,I,A,B(4,6,13,19,22,4,24) 输入数据: i_count =1;i_flag=2 预期结果:i_temp=20. 这里的输入数据是由路径和程序推论出来的。而要注意的是预期结果是从函数说明中导出,不能根据程序结构中导出。 为什么这么说? 让我们看程序中的第3行。 int i_temp=1;假如开发人员一不小心写错了,变成了int i_temp=0;根据程序导出的预期结果就会是一个错误的值,但是单元测试不出来问题。 那单元测试就失去了意义。 […]
View Detailsflash在C#中的应用
很多光盘上的程序,比如电脑迷光盘,开头总有一段动画,用来展现企业品牌和LOGO之用。这个动画是Flash做的,而且嵌入到程序中简直做到无缝融合,因为右键点击它也不会有那特有而烦人的Flash右键菜单。 因此将Flash融合到WinForm中能够增强程序的多媒体效果和炫丽的外观。现在我们就来看看在C#桌面程序中如何插入Flash视频,而且去掉烦人的右键菜单。 首先要插入Flash就必须使用Flash控件,在工具栏右键选择“选择项…”,然后在“COM组件”面板下点击“浏览”按钮,在本机电脑C:\WINDOWS\system32\Macromed\Flash\目录里选择Flash8.ocx(也有可能是Flash9F.ocx,版本不同所致),然后点击确定就可以了。但到这里还没有完,因为要使用Flash控件必须注册它。 在CMD里面输入如下: regsvr32 C:\WINDOWS\system32\Macromed\Flash\Flash8.ocx 系统会提示注册成功,这个时侯就可以在VS2008里面使用该控件了! 打开VS2008,新建一个Windows程序,然后把刚才我们选择的Flash控件Shockwave Flash Object拖到窗体中,这时窗体中会出现一个白色的矩形框,Name属性我们设置为Myflash,在里面可以播放我们需要的swf文件。 注意到该控件主要有几个属性: Name属性,这个是所有对象都会有的。 Menu属性,这个是Flash菜单项,默认值为true,也就是右键的时候会出现完整的Flash菜单,如果设置为False,则只出现最简的菜单(设置与关于)。 Move属性,这个属性是用来指定要播放的Flash文件的。 Playing属性,指定是否装在影片之后马上播放。 Quality属性,设置影片的质量。 Scalemode属性,设置影片的缩放模式。 Visible属性,设置影片控件的可视与否。 接下来我们在窗体中放置一个按钮,Text属性设置为LoadSwf。双击添加事件代码如下: OpenFileDialog ofd = new OpenFileDialog(); ofd.Filter = "Flash文件|*.swf"; DialogResult dr = ofd.ShowDialog(); if (dr == DialogResult.OK) { Myflash.Movie = ofd.FileName; Myflash.Play(); } 这样当程序运行的时候点击按钮会要我们选择一个SWF文件,选择好后确定就自动播放了! 当然,我们还可以添加一些按钮,分别为Play,Pause Play按钮的播放功能如下: This.Myflash.Play(); Pause按钮的暂停功能如下: This.Myflash.StopPlay();
View DetailsOracle卸载后彻底清理痕迹
Oracle数据库在开始菜单中使用自带的程序卸载后,我们经常为了避免下次再次安装过程中这样那样的错误发生,我们要对Oracle进行下完全的卸载,下面是手工处理删除不掉的一些文件夹和目录。 常用Oracle数据库的同仁都知道,Oracle经常会莫名的出现一些错误,导致数据库无法正常启动或使用。 经过对出现这些问题的解决,后来找到了问题的根源,也就是再次安装Oracle数据库时,未对之前安装的Oracle进行彻底的卸载所导致。下面我就详细谈谈如何才能彻底卸载Oracle数据库 一、Linux 平台 Linux 平台下卸载Oracle 非常简单,即:删除Oracle安装目录下的所有文件和文件夹即可。 二、Windows 平台 其实这篇文章我主要想就在Windows平台上如何彻底的卸载Oracle进行说明。 因为Oracle在Windows下的卸载颇有一些麻烦,如果不能完全卸载有可能影响将来的再次安装!常规卸载方法是运行Oracle的自带的 卸载程序,可遗憾的是我在卸载时总不能完全卸载,当我再次安装Oracle时,就会出现莫名其妙的问题,并且这种卸载方式比较麻烦,比较慢,下面我介绍一 种比较快并且能够彻底卸载Oracle的方法。 1.关闭oracle所有的服务。可以在windows的服务管理器中关闭; 2.打开注册表:regedit 打开路径: 这一步中,可以用到我们在注册表清理软件一文中介绍的一款及其方便查找路径的小软件。Registry Manager HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ 删除该路径下的所有以oracle开始的服务名称,这个键是标识Oracle在windows下注册的各种服务! 3.打开注册表,找到路径: HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE 删除该oracle目录,该目录下注册着Oracle数据库的软件安装信息。 4.删除注册的oracle事件日志,打开注册表 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Application 删除注册表的以oracle开头的所有项目。 5.删除环境变量path中关于oracle的内容。 鼠标右键右单击“我的电脑-->属性-->高级-->环境变量-->PATH 变量。 删除Oracle在该值中的内容。注意:path中记录着一堆操作系统的目录,在windows中各个目录之间使用分号(;)隔开的,删除时注意。 建议:删除PATH环境变量中关于Oracle的值时,将该值全部拷贝到文本编辑器中,找到对应的Oracle的值,删除后,再拷贝修改的串,粘贴到PATH环境变量中,这样相对而言比较安全。 6.重新启动操作系统。 以上1~5个步骤操作完毕后,重新启动操作系统。 7.重启操作系统后各种Oracle相关的进程都不会加载了。这时删除Oracle_Home下的所有数据。(Oracle_Home指Oracle程序的安装目录) 8.删除C:\Program Files下oracle目录。 (该目录视Oracle安装所在路径而定) 9.删除开始菜单下oracle项,如: C:\Documents and Settings\All Users\「开始」菜单\程序\Oracle – ora10g 不同的安装这个目录稍有不同。 如果不删除开始菜单下的Oracle相关菜单目录,没关系,这个不影响再次安装Oracle.当再次安装Oracle时,该菜单会被替换。 至此,Windows平台下Oracle就彻底卸载了。 到这里,我们的任务就完成了, 如果哪位人才有感兴趣的同仁可以自己编写一个小工具,用来彻底删除Oracle.提供上来大家一起用用,我想很多人会感激涕零的。 FROM:http://www.tree360.cn/blog/article.asp?id=123
View Details数据库点滴之精妙SQL语句
SQL语句先前写的时候,很容易把一些特殊的用法忘记,我特此整理了一下SQL语句操作,方便自己写SQL时方便一点,想贴上来,一起看看,同时希望大家能共同多多提意见,也给我留一些更好的佳句,整理一份《精妙SQL速查手册》,不吝赐教! 一、基础 1、说明:创建数据库
1 |
<ol class="dp-sql"><li class="alt"><span><span class="keyword">CREATE</span><span> </span><span class="keyword">DATABASE</span><span> </span><span class="keyword">database</span><span>-</span><span class="keyword">name</span><span> </span></span></li></ol> |
2、说明:删除数据库
1 |
<ol class="dp-sql"><li class="alt"><span><span class="keyword">drop</span><span> </span><span class="keyword">database</span><span> dbname </span></span></li></ol> |
3、说明:备份sql server
1 |
<ol class="dp-sql"><li class="alt"><span><span class="comment">--- 创建 备份数据的 device</span><span> </span></span></li><li><span>USE master </span></li><li class="alt"><span><span class="keyword">EXEC</span><span> sp_addumpdevice </span><span class="string">'disk'</span><span>, </span><span class="string">'testBack'</span><span>, </span><span class="string">'c:\mssql7backup\MyNwind_1.dat'</span><span> </span></span></li><li><span><span class="comment">--- 开始 备份</span><span> </span></span></li><li class="alt"><span>BACKUP <span class="keyword">DATABASE</span><span> pubs </span><span class="keyword">TO</span><span> testBack </span></span></li></ol> |
4、说明:创建新表
1 |
<ol class="dp-sql"><li class="alt"><span><span class="keyword">create</span><span> </span><span class="keyword">table</span><span> tabname(col1 type1 [</span><span class="op">not</span><span> </span><span class="op">null</span><span>] [</span><span class="keyword">primary</span><span> </span><span class="keyword">key</span><span>],col2 type2 [</span><span class="op">not</span><span> </span><span class="op">null</span><span>],..) </span></span></li><li><span><span class="comment">-------根据已有的表创建新表:</span><span> </span></span></li><li class="alt"><span>A:<span class="keyword">create</span><span> </span><span class="keyword">table</span><span> tab_new </span><span class="op">like</span><span> tab_old (使用旧表创建新表) </span></span></li><li><span>B:<span class="keyword">create</span><span> </span><span class="keyword">table</span><span> tab_new </span><span class="keyword">as</span><span> </span><span class="keyword">select</span><span> col1,col2… </span><span class="keyword">from</span><span> tab_old definition </span><span class="keyword">only</span><span> </span></span></li></ol> |
5、说明:删除新表
1 |
<ol class="dp-sql"><li class="alt"><span><span class="keyword">drop</span><span> </span><span class="keyword">table</span><span> tabname </span></span></li></ol> |
6、说明:增加一个列
1 |
<ol class="dp-sql"><li class="alt"><span><span class="keyword">Alter</span><span> </span><span class="keyword">table</span><span> tabname </span><span class="keyword">add</span><span> </span><span class="keyword">column</span><span> col type </span></span></li></ol> |
注:列增加后将不能删除。DB2中列加上后数据类型也不能改变,唯一能改变的是增加varchar类型的长度。 7、说明:添加主键
1 |
<ol class="dp-sql"><li class="alt"><span><span class="keyword">Alter</span><span> </span><span class="keyword">table</span><span> tabname </span><span class="keyword">add</span><span> </span><span class="keyword">primary</span><span> </span><span class="keyword">key</span><span>(col) </span></span></li></ol> |
说明:删除主键
1 |
<ol class="dp-sql"><li class="alt"><span><span class="keyword">Alter</span><span> </span><span class="keyword">table</span><span> tabname </span><span class="keyword">drop</span><span> </span><span class="keyword">primary</span><span> </span><span class="keyword">key</span><span>(col) </span></span></li></ol> |
8、说明:创建索引
1 |
<ol class="dp-sql"><li class="alt"><span><span class="keyword">create</span><span> [</span><span class="keyword">unique</span><span>] </span><span class="keyword">index</span><span> idxname </span><span class="keyword">on</span><span> tabname(col….) </span></span></li></ol> |
说明:删除索引
1 |
<ol class="dp-sql"><li class="alt"><span><span class="keyword">drop</span><span> </span><span class="keyword">index</span><span> idxname </span></span></li></ol> |
注:索引是不可更改的,想更改必须删除重新建。 9、说明:创建视图
1 |
<ol class="dp-sql"><li class="alt"><span><span class="keyword">create</span><span> </span><span class="keyword">view</span><span> viewname </span><span class="keyword">as</span><span> </span><span class="keyword">select</span><span> statement </span></span></li></ol> |
说明:删除视图
1 |
<ol class="dp-sql"><li class="alt"><span><span class="keyword">drop</span><span> </span><span class="keyword">view</span><span> viewname </span></span></li></ol> |
10、说明:几个简单的基本的sql语句
1 |
<ol class="dp-sql"><li class="alt"><span><span>选择:</span><span class="keyword">select</span><span> * </span><span class="keyword">from</span><span> table1 </span><span class="keyword">where</span><span> 范围 </span></span></li><li><span>插入:<span class="keyword">insert</span><span> </span><span class="keyword">into</span><span> table1(field1,field2) </span><span class="keyword">values</span><span>(value1,value2) </span></span></li><li class="alt"><span>删除:<span class="keyword">delete</span><span> </span><span class="keyword">from</span><span> table1 </span><span class="keyword">where</span><span> 范围 </span></span></li><li><span>更新:<span class="keyword">update</span><span> table1 </span><span class="keyword">set</span><span> field1=value1 </span><span class="keyword">where</span><span> 范围 </span></span></li><li class="alt"><span>查找:<span class="keyword">select</span><span> * </span><span class="keyword">from</span><span> table1 </span><span class="keyword">where</span><span> field1 </span><span class="op">like</span><span> ’%value1%’ </span><span class="comment">---like的语法很精妙,查资料!</span><span> </span></span></li><li><span>排序:<span class="keyword">select</span><span> * </span><span class="keyword">from</span><span> table1 </span><span class="keyword">order</span><span> </span><span class="keyword">by</span><span> field1,field2 [</span><span class="keyword">desc</span><span>] </span></span></li><li class="alt"><span>总数:<span class="keyword">select</span><span> </span><span class="func">count</span><span> </span><span class="keyword">as</span><span> totalcount </span><span class="keyword">from</span><span> table1 </span></span></li><li><span>求和:<span class="keyword">select</span><span> </span><span class="func">sum</span><span>(field1) </span><span class="keyword">as</span><span> sumvalue </span><span class="keyword">from</span><span> table1 </span></span></li><li class="alt"><span>平均:<span class="keyword">select</span><span> </span><span class="func">avg</span><span>(field1) </span><span class="keyword">as</span><span> avgvalue </span><span class="keyword">from</span><span> table1 </span></span></li><li><span>最大:<span class="keyword">select</span><span> </span><span class="keyword">max</span><span>(field1) </span><span class="keyword">as</span><span> maxvalue </span><span class="keyword">from</span><span> table1 </span></span></li><li class="alt"><span>最小:<span class="keyword">select</span><span> </span><span class="keyword">min</span><span>(field1) </span><span class="keyword">as</span><span> minvalue </span><span class="keyword">from</span><span> table1 </span></span></li></ol> |
11、说明:几个高级查询运算词 A: UNION 运算符 UNION 运算符通过组合其他两个结果表(例如 TABLE1 和 TABLE2)并消去表中任何重复行而派生出一个结果表。当 ALL 随 UNION 一起使用时(即 UNION ALL),不消除重复行。两种情况下,派生表的每一行不是来自 TABLE1 就是来自 TABLE2。 B: EXCEPT 运算符 EXCEPT 运算符通过包括所有在 TABLE1 中但不在 TABLE2 中的行并消除所有重复行而派生出一个结果表。当 ALL 随 EXCEPT 一起使用时 (EXCEPT ALL),不消除重复行。 C: INTERSECT […]
View Details45个非常奇妙的 CSS3 特性应用示例
这篇文字收集了45个让人觉得不可思议的 CSS3 应用示例,它们验证了 CSS3 Transform 和 Transition 等属性的强大能力。随着越来越多的浏览器对 CSS3 支持的不断完善,设计师和开发者们有了更多的选择,以前需要使用 JavaScript 才能实现的各种很酷的界面效果和动画,如今使用纯 CSS 代码就可以很容易实现。 CSS3 Clock With jQuery Another Image Gallery Sliding Vinyl 3D Cube That Rotates Using Arrow Keys Multiple 3D Cubes (Slide In/Out) CSS3 Accordion Auto-Scrolling Parallax Isocube Image Gallery Matrix 7 Javascript-effect Alternatives Using CSS3 Image Hover Effects Turning Coke Can (Control With Scrollbar) 3D Meninas Polaroid Gallery Space Note: this one is graphic intense and takes a while to load, but the result is crazy! Mac Dock Drop-In Modals Zooming Polaroids Animated Rocket Poster […]
View DetailsSQL Server性能调优之执行计划第一次实践
自从上一篇文章发出之后,收到了很朋友的关注。很多朋友要求多多实践,而不是纯粹的理论。确实,从打算出这个系列开始,我就本着实践的思想来进行的!同时,为了使得大家更好的理解、消化这些知识,我会定期的就所写内容进行在线的视频讲座,朋友们可以去参与这个小组:http://www.agilesharp.com/c/sqlprofiler.aspx,报名活动开始啦:http://www.agilesharp.com/Event.aspx/T-2 议程如下: 实践概述 图形化执行计划实战 执行计划信息解读 实践概述 执行计划可以辅助我们写出高效率的T-SQL代码,同时也可以找出现有T-SQL代码的问题,还可以监控数据库!当然,最后如何使用执行计划还是取决于我们自己了,但是不管怎么样,我们首先学会解析执行计划中所包含的信息,最快的学习方法就是实践。下面,我们就从一个实践开始。 为了使得大家易于理解,这里的例子不会太复杂,随着课程的不断深入,后续的示例也会越来越复杂。同时,如果大家也想跟着一起动手实践,那么希望朋友们安装SQL2005或更高版本,同时记得安装AdventureWorks数据库。下载地址为:http://msftdbprodsamples.codeplex.com 另外,有一个需要注意的是,由于数据库中数据,操作和时间的关系,可能大家在运行脚本产生的执行计划和我这里不完全一样,这是没有任何问题的! 图形化执行计划实战 下面我们正式进入要讨论的话题。 首先,为了使得我们可以查看执行计划,最起码要确保我们在登录数据库的时候,要被授予权限,如下语句所示:
1 |
<ol class="dp-sql"><li class="alt"><span><span class="keyword">GRANT</span><span> SHOWPLAN </span><span class="keyword">TO</span><span> [username] </span></span></li></ol> |
为了将讨论集中在执行计划(估计执行计划和实际执行计划)上,我们这里这是运行一个比较简单的查询,如下代码所示:
1 |
<ol class="dp-sql"><li class="alt"><span><span class="keyword">SELECT</span><span> * </span><span class="keyword">FROM</span><span> [dbo].[DatabaseLog]; </span></span></li></ol> |
下面,我们就来看看这个语句的估计执行计划,正如之前文章讲述的:估计执行计划是优化器使用了的元数据,成本分析算法等而产生的计划,这个计划是查询语句执前的一个分析! 显示估计执行计划 我们可以采用以下几种方式显示估计执行计划: 点击Sql Server Studio工具栏上的按钮: 在查询窗口右击鼠标,如下所示: 使用快捷键“CTRL + L”. 对以上面的查询语句,显示的图形化的估计查询计划如下: 显示执行查询计划 与估计执行计划不同,实际的执行计划不是优化器产生的,实际的执行计划是底层的存储引擎在执行时候产生的,这个计划中包含了大量的实际的底层数据和相关的信息。 我们可以采用以下方式获得实际的执行计划,如下所示: 点击工具栏上面的按钮: 在查询窗口右击鼠标,如下: 快捷键“CTRL + M” 上述查询的实际执行计划如下所示: 大家初一看,以为两者没有区别,但是它们包含的数据信息很多是不一样的。 下面,我们就开始对图形化的执行计划进行解读。 执行计划信息解读 刚刚大家已经看了图形化的执行计划了,相关大家比较关心的问题有两个:如何解读执行计划中提供的各种信息;如何采用执行计划来进行性能调优。 我们首先来看看第一个问题。 一般而言,我们在阅读图形化的执行计划的时候顺序是这样的:从右向左,从下往上。也就说:sql执行的第一步就显示在执行计划的右下角。 在图形化执行计划中的每一个图标,都表示一个操作,在之前的执行计划中就有两个操作。并且每个操作之前采用箭头连接起来,表明了数据流动的方向,其中箭头的粗细就反应了数据量的大小。 另外,在每个操作下面都显示了一个百分比。 对于估计执行计划而言,这个数字就是优化器对执行计划中每一个操作步骤进行成本分析后的结果。例外,在我们的例子中,整个查询最后会有两个操作会进行,Select和Table Scan,其中整个查询的成本将会落在Table Scan(整表扫描)上。 操作提示信息 当我们把鼠标放在每个操作或箭头上面的时候,就会弹出更多的相关信息,我们下面就来具体的看一看。 例如,当我们把鼠标放在执行计划的Select操作上面,显示如图: 上面图中给出的信息非常清楚了,我这里只是解释一下“估计子树大小”。因为执行计划可以看出是sql语句的逻辑执行步骤,这个选项就告诉我们:在我们现在所看的这个操作步骤以及后面的所有步骤的开销是多少,是一个总计数字。 如何朋友们还有有什么不清楚的,我们在后续将要展开的在线讲座中讲述! […]
View Details养成一个SQL好习惯带来一笔大财富
我们做软件开发的,大部分人都离不开跟数据库打交道,特别是erp开发的,跟数据库打交道更是频繁,存储过程动不动就是上千行,如果数据量大,人员流动大,那么我么还能保证下一段时间系统还能流畅的运行吗?那么还能保证下一个人能看懂我么的存储过程吗?那么我结合公司平时的培训和平时个人工作经验和大家分享一下,希望对大家有帮助。 要知道sql语句,我想我们有必要知道sqlserver查询分析器怎么执行我么sql语句的,我么很多人会看执行计划,或者用profile来监视和调优查询语句或者存储过程慢的原因,但是如果我们知道查询分析器的执行逻辑顺序,下手的时候就胸有成竹,那么下手是不是有把握点呢? 一:查询的逻辑执行顺序 (1) FROM < left_table> (2) ON < join_condition> (3) < join_type> JOIN < right_table> (4) WHERE < where_condition> (5) GROUP BY < group_by_list> (6) WITH {cube | rollup} (7) HAVING < having_condition> (8) SELECT (9) DISTINCT (11) < top_specification> < select_list> (10) ORDER BY < order_by_list> 标准的SQL 的解析顺序为: (1).FROM 子句 组装来自不同数据源的数据 (2).WHERE 子句 基于指定的条件对记录进行筛选 (3).GROUP BY 子句 将数据划分为多个分组 (4).使用聚合函数进行计算 (5).使用HAVING子句筛选分组 (6).计算所有的表达式 (7).使用ORDER BY对结果集进行排序 二 执行顺序: […]
View Details