燕之庐网站建设 - 优质网站设计公司

Archive for 10月 10th, 2009

产业新闻, 开源动态

2009/10/10

Apache HTTP Server 与 Tomcat 的三种连接方式介绍

Tags: ,

首先我们先介绍一下为什么要让 Apache 与 Tomcat 之间进行连接。事实上 Tomcat 本身已经提供了 HTTP 服务,该服务默认的端口是 8080,装好 tomcat 后通过 8080 端口可以直接使用 Tomcat 所运行的应用程序,你也可以将该端口改为 80。

既然 Tomcat 本身已经可以提供这样的服务,我们为什么还要引入 Apache 或者其他的一些专门的 HTTP 服务器呢?原因有下面几个:

1. 提升对静态文件的处理性能

2. 利用 Web 服务器来做负载均衡以及容错

3. 无缝的升级应用程序

这三点对一个 web 网站来说是非常之重要的,我们希望我们的网站不仅是速度快,而且要稳定,不能因为某个 Tomcat 宕机或者是升级程序导致用户访问不了,而能完成这几个功能的、最好的 HTTP 服务器也就只有 apache 的 http server 了,它跟 tomcat 的结合是最紧密和可靠的。

接下来我们介绍三种方法将 apache 和 tomcat 整合在一起。

JK

这是最常见的方式,你可以在网上找到很多关于配置JK的网页,当然最全的还是其官方所提供的文档。JK 本身有两个版本分别是 1 和 2,目前 1 最新的版本是 1.2.19,而版本 2 早已经废弃了,以后不再有新版本的推出了,所以建议你采用版本 1。

JK 是通过 AJP 协议与 Tomcat 服务器进行通讯的,Tomcat 默认的 AJP Connector 的端口是 8009。JK 本身提供了一个监控以及管理的页面 jkstatus,通过 jkstatus 可以监控 JK 目前的工作状态以及对到 tomcat 的连接进行设置,如下图所示:
图 1:监控以及管理的页面 jkstatus

在 这个图中我们可以看到当前JK配了两个连接分别到 8109 和 8209 端口上,目前 s2 这个连接是停止状态,而 s1 这个连接自上次重启后已经处理了 47 万多个请求,流量达到 6.2 个 G,最大的并发数有 13 等等。我们也可以利用 jkstatus 的管理功能来切换 JK 到不同的 Tomcat 上,例如将 s2 启用,并停用 s1,这个在更新应用程序的时候非常有用,而且整个切换过程对用户来说是透明的,也就达到了无缝升级的目的。关于 JK 的配置文章网上已经非常多了,这里我们不再详细的介绍整个配置过程,但我要讲一下配置的思路,只要明白了配置的思路,JK 就是一个非常灵活的组件。

JK 的配置最关键的有三个文件,分别是

httpd.conf
Apache 服务器的配置文件,用来加载 JK 模块以及指定 JK 配置文件信息

workers.properties
到 Tomcat 服务器的连接定义文件

uriworkermap.properties
URI 映射文件,用来指定哪些 URL 由 Tomcat 处理,你也可以直接在 httpd.conf 中配置这些 URI,但是独立这些配置的好处是 JK 模块会定期更新该文件的内容,使得我们修改配置的时候无需重新启动 Apache 服务器。

其中第二、三个配置文件名都可以自定义。下面是一个典型的 httpd.conf 对 JK 的配置

# (httpd.conf) # 加载 mod_jk 模块 LoadModule jk_module modules/mod_jk.so  # # Configure mod_jk #  JkWorkersFile conf/workers.properties JkMountFile conf/uriworkermap.properties JkLogFile logs/mod_jk.log JkLogLevel warn

接下来我们在 Apache 的 conf 目录下新建两个文件分别是 workers.properties、uriworkermap.properties。这两个文件的内容大概如下

# # workers.properties #   # list the workers by name  worker.list=DLOG4J, status  # localhost server 1 # ------------------------ worker.s1.port=8109 worker.s1.host=localhost worker.s1.type=ajp13  # localhost server 2 # ------------------------ worker.s2.port=8209 worker.s2.host=localhost worker.s2.type=ajp13 worker.s2.stopped=1  worker.DLOG4J.type=lb worker.retries=3 worker.DLOG4J.balanced_workers=s1, s2 worker.DLOG4J.sticky_session=1  worker.status.type=status

以 上的 workers.properties 配置就是我们前面那个屏幕抓图的页面所用的配置。首先我们配置了两个类型为 ajp13 的 worker 分别是 s1 和 s2,它们指向同一台服务器上运行在两个不同端口 8109 和 8209 的 Tomcat 上。接下来我们配置了一个类型为 lb(也就是负载均衡的意思)的 worker,它的名字是 DLOG4J,这是一个逻辑的 worker,它用来管理前面配置的两个物理连接 s1 和 s2。最后还配置了一个类型为 status 的 worker,这是用来监控 JK 本身的模块。有了这三个 worker 还不够,我们还需要告诉 JK,哪些 worker 是可用的,所以就有worker.list = DLOG4J, status这行配置。

接下来便是 URI 的映射配置了,我们需要指定哪些链接是由 Tomcat 处理的,哪些是由 Apache 直接处理的,看看下面这个文件你就能明白其中配置的意义

/*=DLOG4J /jkstatus=status  !/*.gif=DLOG4J !/*.jpg=DLOG4J !/*.png=DLOG4J !/*.css=DLOG4J !/*.js=DLOG4J !/*.htm=DLOG4J !/*.html=DLOG4J

相 信你已经明白了一大半了:所有的请求都由 DLOG4J 这个 worker 进行处理,但是有几个例外,/jkstatus 请求由 status 这个 worker 处理。另外这个配置中每一行数据前面的感叹号是什么意思呢?感叹号表示接下来的 URI 不要由 JK 进行处理,也就是 Apache 直接处理所有的图片、css 文件、js 文件以及静态 html 文本文件。

通过对 workers.properties 和 uriworkermap.properties 的配置,可以有各种各样的组合来满足我们前面提出对一个 web 网站的要求。您不妨动手试试!
http_proxy

这是利用 Apache 自带的 mod_proxy 模块使用代理技术来连接 Tomcat。在配置之前请确保是否使用的是 2.2.x 版本的 Apache 服务器。因为 2.2.x 版本对这个模块进行了重写,大大的增强了其功能和稳定性。

http_proxy 模式是基于 HTTP 协议的代理,因此它要求 Tomcat 必须提供 HTTP 服务,也就是说必须启用 Tomcat 的 HTTP Connector。一个最简单的配置如下

ProxyPass /images ! ProxyPass /css ! ProxyPass /js ! ProxyPass / http://localhost:8080/

在 这个配置中,我们把所有 http://localhost 的请求代理到 http://localhost:8080/ ,这也就是 Tomcat 的访问地址,除了 images、css、js 几个目录除外。我们同样可以利用 mod_proxy 来做负载均衡,再看看下面这个配置

ProxyPass /images ! ProxyPass /css !  ProxyPass /js !  ProxyPass / balancer://example/ <Proxy balancer://example/> BalancerMember http://server1:8080/ BalancerMember http://server2:8080/ BalancerMember http://server3:8080/ </Proxy>

配置比 JK 简单多了,而且它也可以通过一个页面来监控集群运行的状态,并做一些简单的维护设置。
图 2:监控集群运行状态

ajp_proxy

ajp_proxy 连接方式其实跟 http_proxy 方式一样,都是由 mod_proxy 所提供的功能。配置也是一样,只需要把 http:// 换成 ajp:// ,同时连接的是 Tomcat 的 AJP Connector 所在的端口。上面例子的配置可以改为:

ProxyPass /images ! ProxyPass /css !  ProxyPass /js !  ProxyPass / balancer://example/ <Proxy balancer://example/> BalancerMember ajp://server1:8080/ BalancerMember ajp://server2:8080/ BalancerMember ajp://server3:8080/ </Proxy>

采 用 proxy 的连接方式,需要在 Apache 上加载所需的模块,mod_proxy 相关的模块有 mod_proxy.so、mod_proxy_connect.so、mod_proxy_http.so、mod_proxy_ftp.so、 mod_proxy_ajp.so, 其中 mod_proxy_ajp.so 只在 Apache 2.2.x 中才有。如果是采用 http_proxy 方式则需要加载 mod_proxy.so 和 mod_proxy_http.so;如果是 ajp_proxy 则需要加载 mod_proxy.so 和 mod_proxy_ajp.so这两个模块。
三者比较

相 对于 JK 的连接方式,后两种在配置上是比较简单的,灵活性方面也一点都不逊色。但就稳定性而言就不像 JK 这样久经考验,毕竟 Apache 2.2.3 推出的时间并不长,采用这种连接方式的网站还不多,因此,如果是应用于关键的互联网网站,还是建议采用 JK 的连接方式。

燕之庐 网站建设

PHP业界, 开源动态

discuz!与ucenter之间的通信问题

Tags: ,

我有一朋友做了个论坛http://www.soso80.com,是用discuz做的后台。前段时间他跟我说论坛出现了一点小问题,上传不了头像,一选择好头像图片之后就会提示:access denied for agent changed。我当时有些事在忙,也没放在心上,就让他上百度搜搜看,有什么解决的方法没有。

到 了前几天,他跟我说论坛的注册用户全部丢失了,问我有没有办法找回来。我吃了一惊,忙问是怎么回事,怎么会全部用户都丢失了?他说,原先不是出现上传不了 头像的问题吗?他怎么弄也弄不了,就想着干脆重装UChome算了,结果重装了之后,用户数据全部丢失了,不但以前的问题没解决,还出现了新问题,从论坛 转去个人中心的时候老是要重新再登录一遍,囧死了!

我上他的论坛看了一下,其他的都还好,基本上都是用户中心那边出的问题,从论坛转到用户中心无法记住用户会话,要用户重新再登陆一次,无法上传头像,还有就是用户资料全部丢失。

一个一个问题来解决吧。首先,我觉得从论坛到用户中心无法记住用户会话,可能是discuz论坛和uchome之间的通信问题,上后台看了一下,果然,ucenter的应用中没有添加discuz论坛。

先去discuz的后台查通信密钥,再到ucenter中添加应用,OK,显示通信成功了,再去论坛试了一下,问题还是没有解决,我就纳闷了,后台都显示通信成功了,证明它们之间的数据确实已经联通了,为什么还是无法记住用户会话呢。

又 仔细的分析了一下论坛的config.inc.php文件,通信密钥也一致,并没有什么问题。又进后台重新比对了一下数据,终于让我发现在了问题所在,在 discuz的后台中,ucenter应用ID是1,也就是在config.inc.php文件中define(’UC_APPID’, ‘1′),但在ucenter中,论坛的应用程序ID却是2,哎,这点小错误,真是找死人了,赶紧改好,进论坛再试一下,果然好了,而且连上传头像的问题 也一并解决了,不再出现那句access denied for agent changed提示了,看来这个问题也是这原因造成了。

我又 试着修改了一下头像,结果,虽然不再有错误提示,但却怎么也无法保存上传的图片,操作过程中没有任何错误提示,但就是无法保存头像。没办法,去百度了一 下,原来是保存头像的文件夹未设置写入权限,在ucenter目录下,找到这两个文件夹data/avatar/ ,data/tmp/,把权限设置成可写入,OK,一切都没问题了。

接下来就是要找回之前的用户资料了,我问朋友要了论坛没出问题之前的数据库备 份,然后找到cdb_members,uc_members和uchome_member这三张表,打算导入之前的数据就可以了,但等我进入论坛现在的数 据库一看,晕死了,已经有不少新用户注册了,要知道新用户注册的时候都是自动生成的UID,这些新注册的用户已经占用了老用户的UID了,而且还有不少用 户是发现在老ID丢了,直接又注册了一个同样的新ID,一样的用户名,恢复的时候肯定会冲突的,现在只能面临两个选择了,要么保留现在的用户,要么恢复以 前的用户。但我的朋友说,现在论坛才刚起步,丢失用户数据对论坛的信誉影响挺大的,最好能全部都找回来,而且新用户也保留着。

Orz,这也太高难度了吧。没办法,那就只能手动把以前的用户数据一条一条的加到表里去了,UID冲突的就改UID,用户名重复的就改用户名。。。。。。上百条数据啊,而且还是三张表都要改啊,可怜~~!!!!

最 后,虽然论坛的用户数据全部都找回来了,但还是有一点小小的遗憾,就是,很多新用户会发现,在查看自己发的帖子时,会多了很多自己根本没发过的帖子出来。 但这是没办法的事,因为这个调用是根据UID来调用的,这些新用户占用了老用户的UID,老用户发的帖子也就自然转到了他们的名下。。。呵呵

好了,别再指望我去一个个的改这些帖子的用户UID,这不可能,这么多帖子,杀了我都改不过来。

燕之庐 网站建设

产业新闻, 开源动态

开源媒体播放器Amarok 2.2 发布

Tags: ,

得益于 KDE 4 的跨平台特性

,Amarok 除了可在 Linux 系统上运行之外,也能够在其他系统上使用,包括 Windows 和 Mac OS X。相比 Amarok 1.x 而言,它是一个革新的版本。Amarok 2.0 对用户界面(UI)进行了完全的重新设计,集成了 Magnatune、Jamendo、MP3tunes、Last.fm、Shoutcast 等在线服务,对脚本 API 和插件支持进行了修订,从 KDE 3 迁移到了 KDE 4 框架,以及使用了 Solid、Phonon、Plasma 等核心技术

下载:Amarok 2.2

燕之庐 网站建设

产业新闻

开源语言Python 2.6.3正式发布

Tags:

Python是一门跨平台的脚本语言,Python规定了一个Python语法规则,实现了Python语法的解释程序就成为了Python的解释器,我们用的比较多的是C版本的Python,也就是使用C语言实现的Python解释器,除此之外还有使用Java实现的Jython和使用.NET实现的 IronPython,这些实现可以使Python用户充分利用己有的Java及.NET资源.

Python 2.6.3

We are pleased to announce the release of Python 2.6.3, a bugfix release of Python 2.6.2, on October 2, 2009.

Python 2.6 is now in bugfix-only mode; no new features are being added. Somewhere near 100 bugs have been fixed since the release of Python 2.6.2. The NEWS file lists every change in each alpha, beta, and release candidate of Python 2.6.

* What’s New in Python 2.6.
* Report bugs at http://bugs.python.org.
* Read the Python license.
* PEP 361 set out the development schedule for 2.6.

Help fund Python and its community by donating to the Python Software Foundation.
Download
This is a final release; we currently support these formats:

  • Gzipped source tar ball (2.6.3)(sig)
  • Bzipped source tar ball (2.6.3)(sig)
  • Windows x86 MSI Installer (2.6.3)(sig)
  • Windows AMD64 MSI Installer (2.6.3)(sig)
  • Mac Installer disk image (2.6.3)(sig)

MD5 checksums and sizes of the released files:
c4842532170fc0a6f9e878497efc0ddf 13319447 Python-2.6.3.tgz 8755fc03075b1701ca3f13932e6ade9f 11249543 Python-2.6.3.tar.bz2 f7382afe57e21ced274eeec614dbda37 15214592 python-2.6.3.amd64.msi 9ff76b6101fdb1c935970476ed428569 14871552 python-2.6.3.msi 114d26c741d4c0b8ee91191a7a06aa2a 20329350 python-2.6.3-macosx.dmg
The signatures for the source tarballs above were generated with GnuPG using release manager Barry Warsaw’s public key which has a key id of A74B06BF. The Windows installers were signed by Martin von Löwis’ public key which has a key id of 7D9DC8D2. The Mac disk image was signed by Ronald Oussoren’s public key which has a key id of E6DF025C.
Documentation
The documentation has also been updated. You can browse the HTML on-line or download the HTML

同时我们期待已久的Dive into Python 3已经发布了,希望大家能够积极的参与翻译工作

燕之庐 网站建设

产业新闻

Linux桌面用户占有率为何逐月下降?

Tags:

当今,Windows 7即将正式发布对全球操作系统的格局产生重大影响,这是客观事实。我们必须清醒地面对。

根据W3counter发布的全球统计数据,今年7、8、9三个月Linux 桌面用户占有率分别为2.02%、1.97%、1.84%,呈逐月下降趋势。在这同一时期,除了XP以外,Vista、Mac OS和Windows 7用户占有率均出现明显增长。这是什么原因造成的?首先,我们要搞清楚W3counter的统计原理(或机制)。该网站在 全球范围内不断监视着27.891个固定网站,在每月的最后一天,在每个被监视的网站提取最新(last)的15,000个page views,进行自动分析,得出相关统计结论。被监视用户群体多半分布在北美、欧洲地区,比如,美国占28.74%、德国占4.72%、英国占4.48% 等。由此可见,该统计结果并不全面,但是,有相当的代表性。

大家知道,全球PC计算机的用户数是在每月不断逐渐增加的。各类操作系统的用户占有率的些微变化当然与这种增加有关。我们不难想象,Linux用户占有率 的不断下降反映了全球新增PC计算机预装Linux操作系统相当稀少的事实。事实上,全球新增PC计算机预装Linux的比例肯定不足原有的整体占有率。 简单地说,Linux用户被“稀释”了,其浓度正在不断下降。这一事实说明了什么呢?这说明PC计算机预装什么样的操作系统至今仍然是一个有关大局的根本 问题,是一个决定着全球IT产业未来走势的大问题。

事实上,微软是很强大的。它的Windows 7的OEM版本早已推出,全球PC计算机厂商几乎都愿意预装Windows 7。这是为什么呢?我们把话说明白了就是:企业追求利润。Windows 7可以给PC厂家带来丰厚的利润空间,而Linux则不能(或是很困难)。这就是问题关键之所在。

国庆期间,我在Kanas(喀纳斯) 湖边思考着这一问题。我确信,当今摆在Linux面前的主要问题不是技术因 素,而是经济模式。微软为Windows所构建的生态(经济)保护圈是异常坚固的,远非我们的一般想象。客户为何愿意花钱购买Windows?对用户而 言,免费并不一定是最好的选择。这其中的道理不易说清楚。……据此,我不想再和微软玩(直接对抗)了。但是,我心里面并不服气。U盘的生意经就是一个明 证。把U盘视作计算机的一种配件,再把Linux预装到U盘里面去,让它紧紧贴上XP,就像寄生虫一样。当然,这种发展Linux的思路不是Linux国 家队所考虑的,而只能是Linux草根队的发展策略。草根孕育着荒漠上的生命,不惧天寒地冻,仍能生生不息。草根不需要特别的呵护,死了也无非是一根小 草。

说明:昨晚回京。今年10月29日,Ubuntu 9.10大家族就要发布了。当前,《Ubuntu实验室》有许多工作要做,比如,要增加一些硬设备(应对企业云计算)。有人也许会说,你就是一个乌托邦理想主义者。我说,不是。乌邦托(Wubuntu)不是乌托邦,就是这个意思。

燕之庐 网站建设

产业新闻

支持HTML 5的Chrome Frame:为Google Wave作准备

Tags:

众所周知Google可以说是HTML 5最强有力的支持者,而身为Google主打浏览器的Chrome自然是事事身先士卒。这不,Google刚发布了一款名为Google Chrome Frame的插件,可让Chrome在IE中执行呈现工作。这表示所有针对Chrome Frame的页面即将使用谷歌的呈现引擎进行显示,当中包括Google支持的一些HTML 5元素,而该页面依然可以使用微软IE来浏览。

Google Chrome Frame是一项给Wave做准备的开源项目。Wave即将使用HTML 5特性,若IE不支持HTML 5的话则不会大量的采用。谷歌这项工作就是曾针对IE开发一个插件,完全绕过IE的呈现引擎。不仅IE中的页面加载更加快速,而且谷歌支持的HTML 5元素在IE中也运行良好。

谷歌Wave项目经理Lars Rasmussen提到创建Chrome Frame的初衷:

谷歌Wave依赖强大的JS和DOM呈现性能在浏览器中提供桌面风格的用户体验。HTML 5的离线存储和Web Workers可让我们添加强大的功能而无需牺牲性能。不幸的是,有着众多Web用户的IE浏览器并没有跟进这些最新的Web技术。相对于其它浏览 器,JavaScript性能落后许多倍,而且对于HTML 5的支持也远远不足。类似的是,IE的各个版本仍在使用,每个版本都有自己不同的CSS集和布局限制,这使得富Web应用程序的开发更加复杂。

在以往,谷歌Wave项目小组花了大量时间来改进IE中Google Wave的运行性能。我们要在这方面不断前进,但Google Chrome Frame的使用让我们把原来在引擎上花费的时间投入到给所有客户提供更多功能之上,而不会失去IE的用户。

要 开始测试它,先要安装这个IE插件。然后,所有的页面都可以在IE中加载,如果URL前缀是“cf:”则由Chrome引擎进行呈现。例如,以下页面包含 HTML 5视频:cf:http://camendesign.com/code/video_for_everybody/test.html。

使用“cf:”前缀是应用该项功能的最快捷方式,但实际使用的方法则是在HTML页面中定义meta标签:

  1. < meta http-equiv="X-UA-Compatible" content="chrome=1"> 

带Chrome Frame插件的IE遇到这个标签时,它就会开始使用Chrome引擎。谷歌准备了一份脚本来进行测试,需要先安装Chrome Frame:

  1. < script type="text/javascript"   
  2. src="http://ajax.googleapis.com/ajax/libs/chrome-frame/1/CFInstall.min.js"> < /script> 
  3.    
  4. < div id="placeholder">< /div> 
  5.  
  6. < script> 
  7. CFInstall.check({  
  8.     node: "placeholder",  
  9.     destination: "http://www.waikiki.com"  
  10.   });  
  11. < /script> 
  12.  

还可以设置注册表项来强制IE总是使用Chrome Frame:

  1. HKCU  
  2.   Software  
  3.     Google  
  4.       ChromeFrame  
  5.         OptInUrls  
  6.           *google.com*         [字符串值的名称是要匹配的模式,不使用赋值]  
  7.           *yahoo.com/mail*     [使用简单模式,而非正则表达式匹配]  
  8.           *                    ['*'表示加载所有元素]  

Chrome Frame中还有Chrome调试工具和日志工具。Chrome Frame仅适用于Windows XP和Vista的IE 6、7和8版本。不针对其它浏览器或版本。该插件还处在预发布阶段,仍未公布Beta版,且只针对开发人员。

该 项目的意图不是让所有的主流浏览器都运行HTML 5应用程序。虽然用户现在可以在IE中使用这个插件来运行HTML 5应用程序,但谷歌的做法势必会促使微软加快采纳HTML 5并完善IE。毋庸置疑,当前使用IE的用户通个这个插件马上就会受益于Webkit带来的速度提升和享受到类似Wave那样的HTML 5应用程序。

燕之庐 网站建设

产业新闻

软件测试的十二个误区

Tags:

PHPChina资讯:软件测试是软件开发中非常重要的部分,甚至可以说,软件开发,一半是开发,一半是测试。软件测试过程中会遇到一些误区,希望能给大家指点迷津。  软件测试的十二个误区大体总结如下:

1) 测试人员不需要了解软件开发的知识:

这个很要命的,我们谈到软件测试人员未来的发展方向大致有:自动化测试,性能测试,测试管理,项目经理。这其中自动化测试和性能测试包括项目管理,都会要求对软件开发有深入的理解,如何能设计一个好的自动化框架,好的性能测试用例,如何管理一个开发团队,这都需要我们在软件开发方面有所掌握。不单要掌握,而且要精通。此其一。

其二:如果不了解开发知识,测试人员很容易被开发人员牵着鼻子走,因为开发人员随便一忽悠,你如果不了解个中奥妙,你一个字也说不上来。(以前我们讨论 Cookie和Session,由于GoAhead不支持Session,只能用Cookie来控制,差点别开发人员忽悠了)

2) 软件测试很简单:

如果你这么想,那么请别去做测试,如果你做了,你也做不长久。以前面试一位小伙子,做了3年测试,问他测试都怎么做的?答不上来,原来他测的都是很简单的小软件,根本就没有系统地去学习过测试,无语。

3) 测试就是为了找到BUG:

很多人最初都是这样的看法,千万要小心。如果你只是为了找到BUG,那么BUG会成天缠着你。

4) 测试人员和开发人员从来都是死对头:

我以前发起过一个倡议:我们讨论的时候不要用他们(开发人员)和我们(测试人员),而是统一用咱们(开发人员和测试人员本来就是一起的)。如果测试人员能与开发人员成为朋友,你会发现,生活是多么美好。

5) 自动化测试太难:

有的人一进公司就想做自动化,觉得它有难度,有挑战。我说你如果做不好手工测试,你同样做不好自动化,手工测试才是基础。而另外还有一部分人一说到自动化便望而生畏,认为这个东西太难了,不想碰(特别是很多女生,就有这个心理)。其实大可不必这样想,自动化测试工具它只是一个工具而已,它跟WORD这样的工具没有任何区别。

6) 手工测试太没挑战:

什么都不说了,能把它做好的人没几个。

7) 大量的重复性的工作很乏味:

于是大家学得测试这份工作不好玩儿,特别一些男生,特别一些开发人员,从来都瞧不起做测试的,觉得这玩意儿太没劲。我想说的是,要掌握方法,要学会创新,任何东西都有它的特点,你如果总觉得成天在做重复性的工作,那么请静下心来想想,怎么能让它不重复(事情本身是死的,人是活的)。

8) 白盒测试是开发人员干的事:

一个合格的测试人员必须掌握白盒测试,理解其中的原理。不管什么样的测试,都必须要有测试人员的思维才能做好。

9) 女生适合做测试:

不管适合不适合吧,反正我以前所在的公司有5个Team Leader,3个Test Manager,其中只有两个是男生(加上我),这是现实。但是做自动化测试的,全是4个男生,这也是现实。不太想加以评论。只想说,女生未必适合做测 试,男生同样能把测试做好,且做得更加专业。

10) 测试就是给开发擦屁股的:

如果这样想,那么请每天多准备些手纸。测试人员永远要站在客户的角度来想问题,很显然,客户是从来不会给谁擦屁股的,相反,是客户在驱动着软件的进展与成型。测试人员就应该扮演这样的角色,在大部分时候,要驱动开发人员完成软件的功能,驱动他们做改变。

11) 我做开发可能不行,做测试吧:

这个观点特别适应于应届毕业生,在以前面试的过程中,有一部分人就是觉得我代码写不好,所以入行做测试,还有一部分人稍微明白一点的,是觉得自己在开发方面没什么优势,主动给自己定位做测试工作。其实测试要掌握的技能远比开发多得多,至少面要广得多,要做一个好的测试人员,远比做一个开发人员难得多。

12) 功能性测试掩盖了可用性测试的必要

测试人员甚至我们的设计人员,开发人员都不太注重可用性(usability)方面的设计和测试。

我们往往只在意功能性或者性能方面的测试,而忽略了用户体验,即使谈不上用户体验,哪怕是方便使用也行,这些方面往往从软件需求,设计一开始就没怎么考虑。到后来,用户使用的时候便是边用边骂娘。(我常举的例子是:咱们买手机的时候,手机功能一切正常,但偏偏盖子上有条划痕,我相信大家都会要求重新换一台,就这意思)

有则改之,无则加勉,希望大家在进入软件测试这一行以前,能对测试有一个更深入的认识。时间仓促,随便写写,大家多提观点。

燕之庐 网站建设

产业新闻

五十种巧妙优化SQL Server数据库的方法

Tags:

查询速度慢的原因很多,常见如下几种:

没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷)。

I/O吞吐量小,形成了瓶颈效应。

没有创建计算列导致查询不优化。

内存不足。

网络速度慢。

查询出的数据量过大(可以采用多次查询,其他的方法降低数据量)。

锁或者死锁(这也是查询慢最常见的问题,是程序设计的缺陷)。

sp_lock,sp_who,活动的用户查看,原因是读写竞争资源。

返回了不必要的行和列。

查询语句不好,没有优化。

可以通过如下方法来优化查询 :

1、把数据、日志、索引放到不同的I/O设备上,增加读取速度,以前可以将Tempdb应放在RAID0上,SQL2000不在支持。数据量(尺寸)越大,提高I/O越重要。

2、纵向、横向分割表,减少表的尺寸(sp_spaceuse)。

3、升级硬件。

4、根据查询条件,建立索引,优化索引、优化访问方式,限制结果集的数据量。注意填充因子要适当(最好是使用默认值0)。索引应该尽量小,使用字节数小的列建索引好(参照索引的创建),不要对有限的几个值的字段建单一索引如性别字段。

5、提高网速。

6、扩大服务器的内存,Windows 2000和SQL server2000 能支持4-8G的内存。配置虚拟内存:虚拟内存大小应基于计算机上并发运行的服务进行配置。运行 Microsoft SQL Server? 2000 时,可考虑将虚拟内存大小设置为计算机中安装的物理内存的 1.5 倍。如果另外安装了全文检索功能,并打算运行 Microsoft 搜索服务以便执行全文索引和查询,可考虑:将虚拟内存大小配置为至少是计算机中安装的物理内存的 3 倍。将 SQL Server max server memory 服务器配置选项配置为物理内存的 1.5 倍(虚拟内存大小设置的一半)。

7、增加服务器 CPU个数;但是必须明白并行处理串行处理更需要资源例如内存。使用并行还是串行程是MsSQL自动评估选择的。单个任务分解成多个任务,就可以在处理器 上运行。例如耽搁查询的排序、连接、扫描和GROUP BY字句同时执行,SQL SERVER根据系统的负载情况决定最优的并行等级,复杂的需要消耗大量的CPU的查询最适合并行处理。但是更新操作Update,Insert, Delete还不能并行处理。

8、如果是使用like进行查询的话,简单的使用index是不行的,但是全文索引,耗空间。 like ‘a%’ 使用索引 like ‘%a’ 不使用索引用 like ‘%a%’ 查询时,查询耗时和字段值总长度成正比,所以不能用CHAR类型,而是VARCHAR。对于字段的值很长的建全文索引。

9、DBServerAPPLicationServer 分离;OLTP和OLAP分离。

10、分布式分区视图可用于实现数据库服务器联合体。联合体是一组分开管理的服务器,但它们相互协作分担系统的处理负荷。这种通过分区数据形成数据库服务器联合体的机制能够扩大一组服务器,以支持大型的多层 Web 站点的处理需要。有关更多信息,参见设计联合数据库服务器。(参照SQL帮助文件’分区视图’)

在实现分区视图之前,必须先水平分区表。

在创建成员表后,在每个成员服务器上定义一个分布式分区视图,并且每个视图具有相同的名称。这样,引用分布式分区视图名的查询可以在任何一个成员服务器 上运行。系统操作如同每个成员服务器上都有一个原始表的复本一样,但其实每个服务器上只有一个成员表和一个分布式分区视图。数据的位置对应用程序是透明的。

11、重建索引 DBCC REINDEX ,DBCC INDEXDEFRAG,收缩数据和日志 DBCC SHRINKDB,DBCC SHRINKFILE. 设置自动收缩日志.对于大的数据库不要设置数据库自动增长,它会降低服务器的性能。在T-sql的写法上有很大的讲究,下面列出常见的要点:首 先,DBMS处理查询计划的过程是这样的:

查询语句的词法、语法检查。

将语句提交给DBMS的查询优化器。

优化器做代数优化和存取路径的优化。

由预编译模块生成查询规划。

然后在合适的时间提交给系统处理执行。

最后将执行结果返回给用户其次,看一下SQL SERVER的数据存放的结构:一个页面的大小为8K(8060)字节,8个页面为一个盘区,按照B树存放。

12、Commit和rollback的区别Rollback:回滚所有的事物。 Commit:提交当前的事物. 没有必要在动态SQL里写事物,如果要写请写在外面如: begin tran exec(@s) commit trans 或者将动态SQL 写成函数或者存储过程。[SPAN]

13、在查询Select语句中用Where字句限制返回的行数,避免表扫描,如果返回不必要的数据,浪费了服务器的I/O资源,加重了网络的负担降低性能。如果表很大,在表扫描的期间将表锁住,禁止其他的联接访问表,后果严重。

14、SQL的注释申明对执行没有任何影响。

15、尽可能不使用光标,它占用大量的资源。如果需要row-by-row地执行,尽量采用非光标技术,如:在客户端循环,用临时表,Table变量,用子查询,用Case语句等等。游标可以按照它所支持的提取选项进行分类: 只进 必须按照从第一行到最后一行的顺序提取行。FETCHNEXT 是唯一允许的提取操作,也是默认方式。可滚动性可以在游标中任何地方随机提取任意行。游标的技术在SQL2000下变得功能很强大,他的目的是支持循环。 有四个并发选项 READ_ONLY:不允许通过游标定位更新(Update),且在组成结果集的行中没有锁。 OPTIMISTIC WITH valueS:乐观并发控制是事务控制理论的一个标准部分。乐观并发控制用于这样的情形,即在打开游标及更新行的间隔中,只有很小的机会让第二个用户更新 某一行。当某个游标以此选项打开时,没有锁控制其中的行,这将有助于最大化其处理能力。如果用户试图修改某一行,则此行的当前值会与最后一次提取此行时获 取的值进行比较。如果任何值发生改变,则服务器就会知道其他人已更新了此行,并会返回一个错误。如果值是一样的,服务器就执行修改。选择这个并发选项 OPTIMISTIC WITH ROW VERSIONING:此乐观并发控制选项基于行版本控制。使用行版本控制,其中的表必须具有某种版本标识符,服务器可用它来确定该行在读入游标后是否有 所更改。在 SQL Server 中,这个性能由timestamp数 据类型提供,它是一个二进制数字,表示数据库中更改的相对顺序。每个数据库都有一个全局当前时间戳值:@@DBTS。每次以任何方式更改带有 timestamp 列的行时,SQL Server 先在时间戳列中存储当前的 @@DBTS 值,然后增加 @@DBTS 的值。如果某 个表具有 timestamp 列,则时间戳会被记到行级。服务器就可以比较某行的当前时间戳值和上次提取时所存储的时间戳值,从而确定该行是否已更新。服务器不必比较所有列的值,只需 比较 timestamp 列即可。如果应用程序对没有 timestamp 列的表要求基于行版本控制的乐观并发,则游标默认为基于数值的乐观并发控制。

SCROLL LOCKS 这个选项实现悲观并发控制。在悲观并发控制中,在把数据库的行读入游标结果集时,应用程序将试图锁定数据库行。在使用服务器游标时,将行读入游标时会在其 上放置一个更新锁。如果在事务内打开游标,则该事务更新锁将一直保持到事务被提交或回滚;当提取下一行时,将除去游标锁。如果在事务外打开游标,则提取下 一行时,锁就被丢弃。因此,每当用户需要完全的悲观并发控制时,游标都应在事务内打开。更新锁将阻止任何其它任务获取更新锁或排它锁,从而阻止其它任务更 新该行。然而,更新锁并不阻止共享锁,所以它不会阻止其它任务读取行,除非第二个任务也在要求带更新锁的读取。滚动锁根据在游标定义的 Select 语句中指定的锁提示,这些游标并发选项可以生成滚动锁。滚动锁在提取时在每行上获取,并保持到下次提取或者游标关闭,以先发生者为准。下次提取时,服务器 为新提取中的行获取滚动锁,并释放上次提取中行的滚动锁。滚动锁独立于事务锁,并可以保持到一个提交或回滚操作之后。如果提交时关闭游标的选项为关,则COMMIT语 句并不关闭任何打开的游标,而且滚动锁被保留到提交之后,以维护对所提取数据的隔离。所获取滚动锁的类型取决于游标并发选项和游标 Select 语句中的锁提示。锁提示 只读 乐观数值 乐观行版本控制 锁定无提示 未锁定 未锁定 未锁定 更新 NOLOCK 未锁定 未锁定未锁定 未锁定 HOLDLOCK 共享 共享 共享 更新 UPDLOCK 错误 更新 更新 更新 TABLOCKX 错误 未锁定 未锁定更新其它 未锁定 未锁定 未锁定 更新 *指定 NOLOCK 提示将使指定了该提示的表在游标内是只读的。

16、用Profiler来跟踪查询,得到查询所需的时间,找出SQL的问题所在;用索引优化器优化索引。

17、注意UNion和UNion all 的区别。UNION all好。

18、注意使用DISTINCT,在没有必要时不要用,它同UNION一样会使查询变慢。重复的记录在查询里是没有问题的。

19、查询时不要返回不需要的行、列。

20、用sp_configure ‘query governor cost limit’或者SETQUERY_GOVERNOR_COST_LIMIT来限制查询消耗的资源。当评估查询消耗的资源超出限制时,服务器自动取消查询,在查询之前就扼杀掉。 SET LOCKTIME设置锁的时间。

21、用select top 100 / 10 Percent 来限制用户返回的行数或者SET ROWCOUNT来限制操作的行。

22、在SQL2000以前,一般不要用如下的字句: “IS NULL”, “<>”, “!=”, “!>”, “!<”, “NOT”, “NOT EXISTS”, “NOT IN”, “NOT LIKE”, and “LIKE ‘%500′”,因为他们不走索引全是表扫描。也不要在Where字句中的列名加函数,如Convert,substring等,如果必须用函数的时候, 创建计算列再创建索引来替代.还可以变通写法:Where SUBSTRING(firstname,1,1) = ‘m’改为Where firstname like ‘m%’(索引扫描),一定要将函数和列名分开。并且索引不能建得太多和太大。NOT IN会多次扫描表,使用EXISTS、NOT EXISTS ,IN , LEFT OUTER JOIN 来替代,特别是左连接,而Exists比IN更快,最慢的是NOT操作.如果列的值含有空,以前它的索引不起作用,现在2000的优化器能够处理了。相同 的是IS NULL,”NOT”, “NOT EXISTS”, “NOT IN”能优化她,而”<>”等还是不能优化,用不到索引。[SPAN]

23、使用Query Analyzer,查看SQL语句的查询计划和评估分析是否是优化的SQL。一般的20%的代码占据了80%的资源,我们优化的重点是这些慢的地方。

24、如果使用了IN或者OR等时发现查询没有走索引,使用显示申明指定索引: Select * FROM PersonMember (INDEX = IX_Title) Where processid IN (’男’,’女’)。

25、将需要查询的结果预先计算好放在表中,查询的时候再Select。这在SQL7.0以前是最重要的手段。例如医院的住院费计算。

26、MIN() 和 MAX()能使用到合适的索引。

27、数据库有一个原则是代码离数据越近越好,所以优先选择Default,依次为Rules,Triggers, Constraint(约束如外健主健CheckUNIQUE……,数据类型的最大长度等等都是约束),Procedure.这样不仅维护工作小,编写程序质量高,并且执行的速度快。

28、如果要插入大的二进制值到Image列, 使用存储过程,千万不要用内嵌Insert来插入(不知JAVA是否)。因为这样应用程序首先将二进制值转换成字符串(尺寸是它的两倍),服务器受到字符 后又将他转换成二进制值.存储过程就没有这些动作: 方法:Create procedure p_insert as insert intotable(Fimage) values (@image), 在前台调用这个存储过程传入二进制参数,这样处理速度明显改善。

29、Between在某些时候比IN 速度更快,Between能够更快地根据索引找到范围。用查询优化器可见到差别。 select * from chineseresume where title in (’男’,'女’) Select * from chineseresume where between ‘男’ and ‘女’ 是一样的。由于in会在比较多次,所以有时会慢些。

30、在必要是对全局或者局部临时表创建索引,有时能够提高速度,但不是一定会这样,因为索引也耗费大量的资源。他的创建同是实际表一样。

31、不要建没有作用的事物例如产生报表时,浪费资源。只有在必要使用事物时使用它。

32、用OR的字句可以分解成多个查询,并且通过UNION 连接多个查询。他们的速度只同是否使用索引有关,如果查询需要用到联合索引,用UNION all执行的效率更高.多个OR的字句没有用到索引,改写成UNION的形式再试图与索引匹配。一个关键的问题是否用到索引。

33、尽 量少用视图,它的效率低。对视图操作比直接对表操作慢,可以用stored procedure来代替她。特别的是不要用视图嵌套,嵌套视图增加了寻找原始资料的难度。我们看视图的本质:它是存放在服务器上的被优化好了的已经产生 了查询规划的SQL。对单个表检索数据时,不要使用指向多个表的视图,直接从表检索或者仅仅包含这个表的视图上读,否则增加了不必要的开销,查询受到干 扰.为了加快视图的查询,MsSQL增加了视图索引的功能。

34、没有必要时不要用DISTINCT和ORDER BY,这些动作可以改在客户端执行。它们增加了额外的开销。这同UNION 和UNION ALL一样的道理。

select top 20 ad.companyname,comid,position,ad.referenceid,worklocation, convert(varchar(10),ad.postDate,120) as postDate1,workyear,degreedescription FROM jobcn_query.dbo.COMPANYAD_query ad where referenceID in(’JCNAD00329667′,’JCNAD132168′,’JCNAD00337748′,’JCNAD00338345′,
‘JCNAD00333138′,’JCNAD00303570′,’JCNAD00303569′,
‘JCNAD00303568′,’JCNAD00306698′,’JCNAD00231935′,’JCNAD00231933′,
‘JCNAD00254567′,’JCNAD00254585′,’JCNAD00254608′,
‘JCNAD00254607′,’JCNAD00258524′,’JCNAD00332133′,’JCNAD00268618′,
‘JCNAD00279196′,’JCNAD00268613′) order by postdate desc

35、在IN后面值的列表中,将出现最频繁的值放在最前面,出现得最少的放在最后面,减少判断的次数。

36、当用Select INTO时,它会锁住系统表(sysobjects,sysindexes等等),阻塞其他的连接的存取。创建临时表时用显示申明语句,而不是 select INTO. drop table t_lxh begin tran select * into t_lxh from chineseresume where name = ‘XYZ’ –commit在 另一个连接中Select * from sysobjects可以看到 Select INTO 会锁住系统表,Create table 也会锁系统表(不管是临时表还是系统表)。所以千万不要在事物内使用它!!!这样的话如果是经常要用的临时表请使用实表,或者临时表变量。

37、一般在GROUP BY 个HAVING字句之前就能剔除多余的行,所以尽量不要用它们来做剔除行的工作。他们的执行顺序应该如下最优:select 的Where字句选择所有合适的行,Group By用来分组个统计行,Having字句用来剔除多余的分组。这样Group By 个Having的开销小,查询快.对于大的数据行进行分组和Having十分消耗资源。如果Group BY的目的不包括计算,只是分组,那么用Distinct更快。

38、一次更新多条记录比分多次更新每次一条快,就是说批处理好。[SPAN]

39、少用临时表,尽量用结果集和Table类性的变量来代替它,Table 类型的变量比临时表好。

40、在SQL2000下,计算字段是可以索引的,需要满足的条件如下:

计算字段的表达是确定的。

不能用在TEXT,Ntext,Image数据类型。

必须配制如下选项 ANSI_NULLS = ON, ANSI_PADDINGS = ON, ……。

41、尽量将数据的处理工作放在服务器上,减少网络的开销,如使用存储过程。存储过程是编译好、优化过、并且被组织到一个执行规划里、且存储在数据库中 的SQL语句,是控制流语言的集合,速度当然快。反复执行的动态SQL,可以使用临时存储过程,该过程(临时表)被放在Tempdb中。以前由于SQLSERVER对复杂的数学计算不支持,所以不得不将这个工作放在其他的层上而增加网络的开销。SQL2000支持UDFs,现在支持复杂的数学计算,函数的返回值不要太大,这样的开销很大。用户自定义函数象光标一样执行的消耗大量的资源,如果返回大的结果采用存储过程。

42、不要在一句话里再三的使用相同的函数,浪费资源,将结果放在变量里再调用更快。

43、Select COUNT(*)的效率教低,尽量变通他的写法,而EXISTS快.同时请注意区别: select count(Fieldof null) fromTable和 select count(Field of NOT null) from Table 的返回值是不同的!!!

44、当服务器的内存够多时,配制线程数量 = 最大连接数+5,这样能发挥最大的效率;否则使用 配制线程数量<最大连接数启用SQL SERVER的线程池来解决,如果还是数量 = 最大连接数+5,严重的损害服务器的性能。

45、按照一定的次序来访问你的表。如果你先锁住表A,再锁住表B,那么在所有的存储过程中都要按照这个顺序来锁定它们。如果你(不经意的)某个存储过程中先锁定表B,再锁定表A,这可能就会导致一个死锁。如果锁定顺序没有被预先详细的设计好,死锁很难被发现。

46、通过SQL ServerPerformanceMonitor监视相应硬件的负载 Memory:PageFaults / sec计数器如果该值偶尔走高,表明当时有线程竞争内存。如果持续很高,则内存可能是瓶颈

Process:

% DPCTime指 在范例间隔期间处理器用在缓延程序调用(DPC)接收和提供服务的百分比。(DPC 正在运行的为比标准间隔优先权低的间隔)。 由于 DPC 是以特权模式执行的,DPC 时间的百分比为特权时间百分比的一部分。这些时间单独计算并且不属于间隔计算总数的一部 分。这个总数显示了作为实例时间百分比的平均忙时。

%ProcessorTime计数器 如果该参数值持续超过95%,表明瓶颈是CPU。可以考虑增加一个处理器或换一个更快的处理器。

% Privileged Time 指非闲置处理器时间用于特权模式的百分比。(特权模式是为操作系统组 件和操纵硬件驱动程序而设计的一种处理模式。它允许直接访问硬件和所有内存。另一种模式为用户模式,它是一种为应用程序、环境分系统和整数分系统设计的一 种有限处理模式。操作系统将应用程序线程转换成特权模式以访问操作系统服务)。特权时间的 % 包括为间断和 DPC 提供服务的时间。特权时间比率高可能是由于失败设备产生的大数量的间隔而引起的。这个计数器将平均忙时作为样本时间的一部分显示。

% User Time表示耗费CPU的数据库操作,如排序,执行aggregatefunctions 等。如果该值很高,可考虑增加索引,尽量使用简单的表联接,水平分割大表格等方法来降低该值。 Physical Disk: Curretn Disk Queue Length计数器该值应不超过磁盘数的1.5~2倍。要提高性能,可增加磁盘。 SQLServer:CacheHit Ratio计数器该值越高越好。如果持续低于80%,应考虑增加内存。 注意该参数值是从SQL Server启动后,就一直累加记数,所以运行经过一段时间后,该值将不能反映系统当前值。

47、分析select emp_name form. employee where salary >3000在此语句中若salary是Float类型的,则优化器对其进行优化为Convert(float,3000),因为3000是个整数,我们应在编程时使用3000.0而不要等运行时让DBMS进行转化。同样字符和整型数据的转换。

48、查询的关联同写的顺序

select a.personMemberID, * from chineseresume a,personmember b where personMemberID = b.referenceid and a.personMemberID = ’JCNPRH39681′ (A = B ,B = ’ 号码’)
select a.personMemberID, * from chineseresume a,personmember b where a.personMemberID = b.referenceid and a.personMemberID = ’JCNPRH39681′ and b.referenceid = ’JCNPRH39681′ (A = B ,B = ’ 号码’, A = ’号码’)
select a.personMemberID, * from chineseresume a,personmember b where b.referenceid = ’JCNPRH39681′ and a.personMemberID = ’JCNPRH39681′ (B = ’ 号码’, A = ’号码’)

49、

(1)IF 没有输入负责人代码 THEN code1=0 code2=9999 ELSE code1=code2=负责人代码 END IF 执行SQL语句为: Select 负责人名 FROM P2000 Where 负责人代码>=:code1 AND负责人代码 <=:code2

(2)IF 没有输入负责人代码 THEN  Select 负责人名 FROM P2000 ELSEcode= 负责人代码 Select 负责人代码 FROM P2000 Where 负责人代码=:code END IF 第一种方法只用了一条SQL语句,第二种方法用了两条SQL语句。在没有输入负责人代码时,第二种方法显然比第一种方法执行效率高,因为它没有限制条件; 在输入了负责人代码时,第二种方法仍然比第一种方法效率高,不仅是少了一个限制条件,还因相等运算是最快的查询运算。我们写程序不要怕麻烦

50、关于JOBCN现在查询分页的新方法(如下),用性能优化器分析性能的瓶颈,如果在I/O或者网络的速度上,如下的方法优化切实有效,如果在CPU或者内存上,用现在的方法更好。请区分如下的方法,说明索引越小越好。

begin
DECLARE @local_variable table (FID int identity(1,1),ReferenceID varchar(20))
insert into @local_variable (ReferenceID)
select top 100000 ReferenceID from chineseresume order by ReferenceID
select * from @local_variable where Fid > 40 and fid <= 60
end 和
begin
DECLARE @local_variable table (FID int identity(1,1),ReferenceID varchar(20))
insert into @local_variable (ReferenceID)
select top 100000 ReferenceID from chineseresume order by updatedate
select * from @local_variable where Fid > 40 and fid <= 60
end 的不同
begin
create table #temp (FID int identity(1,1),ReferenceID varchar(20))
insert into #temp (ReferenceID)
select top 100000 ReferenceID from chineseresume order by updatedate
select * from #temp where Fid > 40 and fid <= 60 drop table #temp
end[SPAN]

另附:存储过程编写经验和优化措施 From:网页教学网

一、适合读者对象:数据库开发程序员,数据库的数据量很多,涉及到对SP(存储过程)的优化的项目开发人员,对数据库有浓厚兴趣的人。

二、介绍:在数据库的开发过程中,经常会遇到复杂的业务逻辑和对数据库的操作,这个时候就会用SP来封装数据库操作。如果项目的SP较多,书写又没有一 定的规范,将会影响以后的系统维护困难和大SP逻辑的难以理解,另外如果数据库的数据量大或者项目对SP的性能要求很,就会遇到优化的问题,否则速度有可 能很慢,经过亲身经验,一个经过优化过的SP要比一个性能差的SP的效率甚至高几百倍。

三、内容:

1、开发人员如果用到其他库的Table或View,务必在当前库中建立View来实现跨库操作,最好不要直接使用“databse.dbo.table_name”,因为sp_depends不能显示出该SP所使用的跨库table或view,不方便校验。

2、开发人员在提交SP前,必须已经使用setshowplan on分析过查询计划,做过自身的查询优化检查。

3、高程序运行效率,优化应用程序,在SP编写过程中应该注意以下几点:

a)SQL的使用规范:

尽量避免大事务操作,慎用holdlock子句,提高系统并发能力。

尽量避免反复访问同一张或几张表,尤其是数据量较大的表,可以考虑先根据条件提取数据到临时表中,然后再做连接。

尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该改写;如果使用了游标,就要尽量避免在游标循环中再进行表连接的操作。

注意where字句写法,必须考虑语句顺序,应该根据索引顺序、范围大小来确定条件子句的前后顺序,尽可能的让字段顺序与索引顺序相一致,范围从大到小。

不要在where子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。

尽量使用exists代替select count(1)来判断是否存在记录,count函数只有在统计表中所有行数时使用,而且count(1)比count(*)更有效率。

尽量使用“>=”,不要使用“>”。

注意一些or子句和union子句之间的替换

注意表之间连接的数据类型,避免不同类型数据之间的连接。

注意存储过程中参数和数据类型的关系。

注意insert、update操作的数据量,防止与其他应用冲突。如果数据量超过200个数据页面(400k),那么系统将会进行锁升级,页级锁会升级成表级锁。

b)索引的使用规范:

索引的创建要与应用结合考虑,建议大的OLTP表不要超过6个索引。

尽可能的使用索引字段作为查询条件,尤其是聚簇索引,必要时可以通过index index_name来强制指定索引

避免对大表查询时进行tablescan,必要时考虑新建索引。

在使用索引字段作为条件时,如果该索引是联合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用。

要注意索引的维护,周期性重建索引,重新编译存储过程。

c)tempdb的使用规范:

尽量避免使用distinct、order by、group by、having、join、cumpute,因为这些语句会加重tempdb的负担。

避免频繁创建和删除临时表,减少系统表资源的消耗。

在新建临时表时,如果一次性插入数据量很大,那么可以使用select into代替create table,避免log,提高速度;如果数据量不大,为了缓和系统表的资源,建议先create table,然后insert。

如果临时表的数据量较大,需要建立索引,那么应该将创建临时表和建立索引的过程放在单独一个子存储过程中,这样才能保证系统能够很好的使用到该临时表的索引。

如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先truncatetable,然后drop table,这样可以避免系统表的较长时间锁定。

慎用大的临时表与其他大表的连接查询和修改,减低系统表负担,因为这种操作会在一条语句中多次使用tempdb的系统表。

d)合理的算法使用:

根据上面已提到的SQL优化技术和ASE Tuning手册中的SQL优化内容,结合实际应用,采用多种算法进行比较,以获得消耗资源最少、效率最高的方法。具体可用ASE调优命令:setstatistics io on, set statisticstimeon , set showplan on 等。
select a.personMemberID, * from chineseresume a,personmember b where personMemberID = b.referenceid and a.personMemberID = ’JCNPRH39681′ (A = B ,B = ’ 号码’)
select a.personMemberID, * from chineseresume a,personmember b where a.personMemberID = b.referenceid and a.personMemberID = ’JCNPRH39681′ and b.referenceid = ’JCNPRH39681′ (A = B ,B = ’ 号码’, A = ’号码’)
select a.personMemberID, * from chineseresume a,personmember b where b.referenceid = ’JCNPRH39681′ and a.personMemberID = ’JCNPRH39681′ (B = ’ 号码’, A = ’号码’)

燕之庐 网站建设

PHP业界

Discuz!和phpwind中各自获取用户IP的方法

Tags:

}disuz!:
if(getenv(’HTTP_CLIENT_IP’) && strcasecmp(getenv(’HTTP_CLIENT_IP’), ‘unknown’)) {
$onlineip = getenv(’HTTP_CLIENT_IP’);
} elseif(getenv(’HTTP_X_FORWARDED_FOR’) && strcasecmp(getenv(’HTTP_X_FORWARDED_FOR’), ‘unknown’)) {
$onlineip = getenv(’HTTP_X_FORWARDED_FOR’);
} elseif(getenv(’REMOTE_ADDR’) && strcasecmp(getenv(’REMOTE_ADDR’), ‘unknown’)) {
$onlineip = getenv(’REMOTE_ADDR’);
} elseif(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], ‘unknown’)) {
$onlineip = $_SERVER['REMOTE_ADDR'];
}

phpwind:

if($_SERVER['HTTP_X_FORWARDED_FOR']){
$onlineip = $_SERVER['HTTP_X_FORWARDED_FOR'];
$c_agentip=1;
} elseif($_SERVER['HTTP_CLIENT_IP']){
$onlineip = $_SERVER['HTTP_CLIENT_IP'];
$c_agentip=1;
} else{
$onlineip = $_SERVER['REMOTE_ADDR'];
$c_agentip=0;

}

燕之庐 网站建设

seo

404页面该怎么做?

Tags:

404页面的目的是:告诉浏览者其所请求的页面不存在或链接错误,同时引导用户使用网站其他页面而不是关闭窗口离开。

很多开源系统包括CMS系统、Blog系统等不提供404页面或提供的404页面并未达到SEO的要求,这让网站的权威性大打折扣。

404页面该达到怎么样的效果才符合SEO要求?

搜索引擎通过HTTP状态码来 识别网页的状态。当搜索引擎获得了一个错误链接时,网站应该返回404状态码,告诉搜索引擎放弃对该链接的索引。而如果返回200或302状态码,搜索引 擎就会为该链接建立索引,这导致大量不同的链接指向了相同的网页内容。结果是,搜索引擎对该网站的信任度大幅降低。——很多网站存在这个问题:404页面 返回的是200或302状态码而不是404状态码。

正确建立404页面的方法是:(仅适合Apache服务器)

  • 在.htaccess 文件中加入代码: ErrorDocument 404 /Error.html
  • 建立一个简单的html404页面命名 Error.html
  • 把 Error.html放置在网站根目录

注意:

  • 不要将404错误直接转向到网站首页,这将导致首页不被收录;
  • /Error.html 前面不要带主域名,否者返回的状态码是302或200状态码。

燕之庐 网站建设