搜档网
当前位置:搜档网 › MySQL优化

MySQL优化

MySQL优化
MySQL优化

Mysql应用层面的优化

本书若不讲解一章关于连接到MySQL的应用程序优化的内容,那就不能算完整,因为人们常常把一些性能方面的问题都归咎到MySQL身上。书里面我们更多地是讲到MySQL 的优化,但是,我们不想让你错过这个更大的图景。一个糟糕的应用设计会使你无论怎么优化MySQL也弥补不了它带来的损失。实际上,有时候对于这类问题的答案是把它们从MySQL上脱离开来,让应用自己或其他工具来做这些事情,这样或许会有较好的性能表现。

本章不是构建高性能应用的参考书,我们只是希望通过阅读这一章让你避免那些常见的会伤及MySQL性能的小错误。下文中我们以Web应用为主要讲解对象,因为MySQL主要是用在Web应用上的。

1 应用程序性能概述

对于更快性能的追求开始时很简单:应用响应请求花费了太长的时间,你总要为此做点什么吧。然而,真正的问题是什么呢?通常的瓶颈是缓慢的查询、锁、CPU饱和、网络延时和文件I/O。如果应用配置错误,或者不恰当地使用资源,以上任何一个因素都会引出一个大问题。

1.1找出问题的根源

第一个任务是找出"肇事者"。如果你的应用具备了显示系统运行概况的功能,这做起来就简单了。如果你已经做到了这一步,但还是没法找出引起性能低下的原因,那你就要增加更多的概况信息的调用,去找出那些要么缓慢要么被多次调用的资源。

如果你的应用因为CPU高占用率而一直等待,并且应用里有高并发性,那我们提到过的"丢失的时间"可能就成问题了。鉴于此,有些时候在有限的并发条件下生成应用的概况信息是很有用的。

网络延时会占用大块的时间,哪怕是在局域网里。应用层面的概况信息已经包括了网络延时,因此,你应该在概况系统里看到网络往返延时带来的影响了。举例来说,如果一个页面执行了1 000个查询,即使每次只有1毫秒的延时,那累加起来也有0.5秒的响应时间,这对高性能应用来说已经是个很大的数目了。

如果应用层面概况信息收集得很充分,那就不难找出问题的根源。如果还没有内置概况功能,那就尽可能地加上它。如果你无法添加这个功能,那也可以试试第76页的"当你无法加入概况信息代码时"里提供的那些建议。这个总比钻研像"什么引起应用变慢"那样没头绪的理论设想要更快更容易。

1.2寻找常见问题

同样的问题我在应用里一次又一次地遇到,其原因往往是人们使用了设计糟糕的原有系统,或者采用了简化开发的通用框架。虽然这在某些时候能让你在开发一些功能时变得方便又快速,但它们也给应用增加了风险,因为你不知道它们底下是怎么工作的。这里有一张清单你应该逐个检查一下:

在各个机器上的CPU、磁盘、网络和内存资源的使用情况如何?使用率对你而言是否合理?如果不合理,就检查那些影响资源使用的应用的程序基础。配置文件有时就是解决问题的最简单方法,举例来说,如果Apache耗光了内存,那是因为它创建1 000个工作者进程,

每个工作进程需要50MB内存,这样,你就可通过配置文件配置这个应用能申请的Apache 工作者进程数。你也可以配置系统,使之创建进程时少用些内存。

应用是否真正使用了它所取得的数据?一个常见的错误是:读取了1 000行数据,却只要显示10行就够了,其他990行就丢弃了(然而,如果应用缓存了余下的990条记录供以后使用,那么这可能是特意做的优化)。

应用里是否做了本该由数据库来做的处理?反之亦然。有个对应的例子是:读取了所有行的数据,然后在应用里计算它们的总数;以及在数据库里做复杂的字符串处理。数据库擅长于计数,而应用的编程语言擅长于正则表达式。你该使用正确的工具去干正确的活。

应用里执行了太多的查询?那些号称能"把程序员从SQL代码里解救出来"的ORM (Object-Relational Mapping)就因此常被人们责备。数据库服务器是被设计用来匹配多表数据的,因为要移除那些嵌套循环,代之以联接(Join)来做同样的查询。

应用里执行的查询太少了?我们只知道执行了太多的查询会成为问题。但是,有时"手工的联接"和与其相似的查询是个好主意,因为它们可以更加有效地利用缓存,更少的锁(尤其是MyISAM),有时当你在应用的代码里使用一个散列联接时(MySQL的嵌套循环的联接方法往往是低效的),查询的执行速度会更快。

应用是不是在毫无必要的时候还连到MySQL上去了?如果你能从缓存里读取数据,就不要去连数据库了。

应用连接到同一个MySQL实例的次数是不是太多了?这可能是因为应用的各个部分都各自开启了自己的数据库连接。有个建议在通常情况下都很对:从头到尾都重用同一个数据库连接。

应用是不是做了太多的"垃圾"查询?一个常见的例子是在做查询前才去选择需要的数据库。一个较好的做法是连接到名称明确的数据库,并使用表的全名做查询。(这样做,也便于通过日志或SHOW PROCESSLIST去查询情况,因为你可以直接执行这些查询语句,无需再更改数据库)。"准备"数据库连接又是另一个常见的问题,特别是Java写的数据库驱动程序,它在准备连接时会做大量的工作,它们中的大多数你都可以关闭。另一种垃圾查询是SET NAMES UTF8,这纯粹是多此一举(它无法改变客户端连接库的字符集,它只对服务器有影响)。如果你的应用已确定在多数任务下使用的是某一个字符集,那你就可以避免这样无谓的字符集设置命令。

应用使用连接池了吗?这既是好事情也是坏事情。它限制了连接的数量,这在连接上查询数不多的情况下(Ajax应用就是个典型的例子)是有利的;然而,它的不好的一面是,应用会受限于使用事务、临时表、连接指定的设置和定义用户变量。

应用使用了持久性连接吗?这样做的直接结果是会产生太多的数据库连接连到MySQL 上。通常情况下,这是个坏主意,除了一种情形:由于慢速的网络导致MySQL的连接成本很高,如果每条连接上只执行一两个快速的查询,或者频繁地连接到MySQL,那样你会很快用完客户端的所有本地端口(更多内容请查看第328页的"网络配置")。如果你正确地配置了MySQL,根本不需要持久性连接,可以使用"跳过名称解析"来防止DNS的查找,并确认该线程的优先级足够高。

即使没有使用,应用是不是还打开着连接?如果是,特别是当这些连接连向多台服务器时,它们可能占用了其他进程需要的连接。举例来说,假设你连接到10台MySQL服务器。

由一个Apache进程占用10个连接数,这不是个问题,但是它们中只有一条连接是在任何指定时间里做着一些操作,而其他9条连接绝大多数时间都处于睡眠状态。如果有一台服务器响应变得迟缓,或者网络延时变长,那其他几台服务器就遭殃了,因为它们根本没连接可用。对于这个问题的解决办法是控制应用使用数据库连接的方式。

举例来说,你可以在各个MySQL实例中依次做批量操作,在向下一个MySQL发起查询前,关闭当前的所有连接。如果你要的是时间消耗很大的操作,比如调用一个Web Service,可以先关闭与MySQL的连接,等这个耗时的调用完成后,再打开MySQL的连接,完成剩余的需要在数据库上操作的任务。

持久性连接与连接池的不同点比较模糊。持久性连接有与连接池相同的副作用,因为在各种情况下重新使用的连接往往都带有状态。

然而,连接池并不总是导致许多连接到服务器的联接,因为它们是队列化的,并在各进程间共享这些连接。在另一方面,持久化连接是基于每个进程来创建的,无法被其他进程所使用。与持久性连接相比,连接池在连接策略上有更多的控制。你可以把一个连接池配置成自动扩充的,但是通常的做法还是当连接池满的时候,新的连接请求都被放在队列里等待。这使得这些请求都在应用服务器上等待,总好过MySQL因为连接太多而超载。有太多的方法使查询和连接更加快速,一般性准则是避免把它们放在一起,胜于试着把它们加速。

2 Web服务器的议题

Apache是Web应用中使用最广泛的服务器软件。在各种用途下,它都能运行良好,但如果使用得不恰当,它也会占用大量的资源。最常见的一个情况是让它的进程活动了太长的时间,并把它用在各种不同类型的任务下却没有做相应的优化。

Apache经常在prefork配置项里使用mod_php、mod_perl、mod_python。预分叉(Prefork)是为每个请求分配一个进程。因为PHP、Perl和Python等脚本语言运行起来很费资源,每个进程占用50MB或100MB内存的情形也不罕见。当一个请求处理完后,它会把绝大多数内存归还给操作系统,但不会是全部。Apache会让这个进程保持在运行状态,以处理将要到来的请求。这就意味着如果这个新来的请求只是为了获得一个静态文件,比如一个CSS文件或一张图片,你都需要重新启用那个又"肥"又"大"的进程来处理这个简单请求。这也是为什么把Apache用作多用途Web服务器是件危险的事情。它是多用途的,若你对它进行了有针对性的配置,它才会有更好的性能表现。

另外有个主要的问题是如果你打开了Keep-Alive参数项,进程就会长时间地保持忙碌状态。即使你不这么做,有些进程也会这样。如果内容是像"填鸭"一样传给客户端的,那这个读取数据的过程也会很漫长。

人们也经常犯这样的错误:按Apache默认开启的模块来运行。你可以按照Apache使用手册里的说明,把你不需要的模块都关闭掉,做法也很简单:查看Apache的配置文件,把不需要的模块都注释掉,然后重启Apache。你可以从php.ini文件中把不需要的PHP模块都移除。

如果你创建了一个多用途Apache才需要的配置当作Web服务器来用,你最后可能会被众多繁重的Apache进程所拖垮,这些进程纯粹浪费你的Web服务器上的资源。而且,它们会占用大量与MySQL的连接,以至于也浪费了MySQL的资源。这里有一些方法能给你的服务器"减负":

不要把Apache用作静态内容的服务,如果一定要用,那也至少要换个另外的Apache 实例来处理这些事情。常见的替代品有lighttpd和nginx。

使用一个缓存代理服务器,比如Squid或Varnish,使用户请求无须抵达Web服务器后才能被响应。即使在这个层面上你无法缓存所有的页面,你也能缓存大部分页面,并通过Edge Side Includes(ESL,https://www.sodocs.net/doc/f714901162.html,)技术把页面上的小块动态部分放到缓存的静态部分里。

对动态内容和静态内容都设置过期策略。你可以使用缓存代理软件,像Squid,去验证内容的明确性。Wikipedia就是用这样的技术在缓存里移除内容已发生变化的文档。

有时你可能需要改变一下应用,使它能使用更长的超期时间。举例来说,如果你告诉浏览器要永久缓存CSS和JavaScript文件,然后又对这个网站静态HTML文件做了一些修改,这样这些页面的显示效果可能会变得很糟。对此,你需要使用一个唯一的文件名对每次修订后的页面文件都作一个明确的版本标记。举例来说,你可以自定义你的网站发布脚本,把CSS文件复制到/css/123_frontpage.css目录下,这里的123就是Subversion里的修订号。你也可以用同样的方法来处理图片文件-- 不要重用原来的文件名,否则,即使你更新了文件内容,页面不会再被更新,不管浏览器要将原来的页面缓存多久。

不要让Apache与客户端做"填鸭"式通信。这不仅仅是慢,而且很容易招致拒绝性服务攻击。典型地,硬件化的负载平衡器会处理好缓存,Apache就能很快地结束响应,然后让负载平衡器从缓存里读出数据去"喂"客户端。你也可以使用lighttpd、Squid,或者设为事件驱动模式下的Apache作为应用的前端。

开启gzip压缩。现在的CPU很廉价,它可以用来节省大量的网络流量。如果你想节省CPU周期,那可以使用轻量级的Web服务器,比如lighttpd,来缓存和提供压缩过的页面。

不要将Apache上的长距离连接配置为"保活"(Keep-Alive)模式,因为它会使Apache 上臃肿的进程长时间处于运行状态。代替的方案是,用一个服务端的代理来处理"保活"的连接,使服务器免受这类客户端的伤害。如果将Apache与代理之间的连接方式设为"保活",那是不错的主意,因为代理仅使用几个连接从服务器上读取数据。下图说明了以上两者的差异。

以上这些策略应该可以帮助Apache减少进程的使用数,使你的服务器不会因为太多的进程而崩溃。然而,有些具体的操作仍然会引起Apache的进程长时间地运行,吞掉大量的系统资源。有一个例子就是查询外部资源时具有很高的延迟,比如访问一个远程Web服务器。这样的问题还是无法用上述那些方法来解决。

2.1找出最佳并发数

每个Web服务器都有它的一个最佳并发数--它的含义是服务器能同时处理的并发连接数目,它们既能尽可能快地处理客户端请求,又不会使服务器过载。这个"神奇的数目"需要做多次的尝试-失败的反复才能得到,相比于它能带来的好处,这还是值得一做。

对于大流量的网站而言,Web服务器同时处理几千个连接是件很平常的事情。然而,这些连接中只有很少的一部分需要主动地去处理请求,而其他那些都是读取请求、文件上传、"喂"内容,或者仅仅等待客户端的下一步请求。

并发数增加时,服务器会在某一点上达到它的吞吐量顶峰,在此之后,吞吐量会变得平稳,往往还会开始下降。更重要的是,系统的响应时间(延迟)开始增加。

想要知道究竟,就要设想如果你只有一颗CPU,而服务器同时接收到100个请求,接下来会发生什么?假如一个CPU秒只能处理一个请求,而且你使用了一个完美的操作系统,没有任务调度的开销,也没有上下文切换的开销,那么这些请求总共需要100个CPU秒才能完成。

那么,怎样去做才是处理这些请求的最好办法?你可以把它们一个接一个放进队列里,或者对它们进行并行处理,每个请求在每一个轮回中都获得一样多的处理时间。这两种方式里,吞吐量都是每一秒一个请求。然而,如果使用队列,平均延迟有50秒(并发数=1),如果并行处理,那延迟有100秒(并发数=100)。在实际环境下,并发处理方法的平均延迟还会更高,因为其中还有个切换开销。

对于高CPU占有率的工作负载而言,其最佳并发数就是CPU(或者是CPU里的核)的数目。然而,进程不总是可以运行的,因为它们会执行阻塞式调用,比如I/O、数据库查询和网络请求等。因此,最佳并发数往往会多于CPU数目。

你可以估计最佳并发数,但是这需要精确的分析模型。通常情况下,还是通过实验的方法比较容易,你尝试着不同的并发数,然后观察系统在降低响应时间前,能达到多大的顶峰吞吐量。

3 缓存

缓存对于高负载的应用而言极其重要。一个典型Web应用里,直接提供服务要比使用缓存(包括缓存校验、作废)多生成很多内容,所以,缓存能够将应用的性能提高好几个数量级。这个技巧的关键在于找出缓存粒度和作废策略的最佳结合点。同时,你需要决定缓存哪些内容,在哪里缓存。

一个典型的高负载应用有许多层的缓存。缓存不仅仅发生在你的服务器上:它出现在整个流程的每一个步骤上,包括用户的Web浏览器里(这就是网页头部的有关作废设置内容的用途)。通常而言,缓存越靠近客户端,就越能节省更多的资源,更加高效。一副图片从浏览器缓存里读出要好于从Web服务器的内存里读取,而后者又好于从服务器的磁盘上读取。每一种缓存都其独有的特性,比如尺寸、延时等,在接下来的章节里我们将对它们逐一进行叙述。

你可以把缓存想象成两大类:被动缓存和主动缓存。被动缓存除了保存和返回数据不做其他事情。当你从被动缓存那里请求一些内容时,它要么给你需要的结果,要么告诉你"你要的数据不存在"。一个被动缓存的例子就是memcached。

相反地,主动缓存在找不到请求的数据时,它会做点别的事情。一般就是把你的请求传递给应用的某一部分--它能生成请求所需要的内容,然后主动缓存就会存储这部分内容,并返回给客户端。Squid缓存代理服务器就是一个主动缓存。

当设计应用时,你总希望你的缓存是主动型(也叫透明型)的,因为对于应用,它们可以隐藏"检查-生成-存储"这个逻辑。你可以在被动缓存之上构建你的主动缓存。

缓存并不总是有用, 你需要确定缓存是不是真地提高了系统的性能,因为它可能一点用处也没有。举例来说,在实际应用中,从lighttpd的内存中读取内容要比从缓存代理那里读取快一些。如果那个代理的缓存是建于磁盘上的,那结论会更明显。这个原因很简单:缓存也有自己的运行开销,它们主要检查缓存的开销和提供被命中缓存内容的开销,另外还有将缓存内容作废和保存数据的开销。只有当这些开销的总和小于服务器生成和提供数据所要的开销时,缓存才有用。

如果你知道所有这些操作的总开销,你就能计算缓存能起多大的作用。没有缓存时的开销就是服务器为每个请求生成数据所需要的总开销。有缓存时的开销就是检查缓存的开销,加上缓存没命中的可能性乘以生成这些数据的开销,再加上缓存命中的可能性乘以从缓存里取出这些数据的开销。

如果有缓存时的开销小于没缓存的时候的开销,那使用缓存就可以提高系统性能,但是也不能保证肯定是这样。记在脑子里的一个例子就是从lighttpd内存里读取内容的开销要比代理从磁盘缓存上读取的开销要小,一些缓存总会比另外一些便宜。

3.1在应用之下的缓存

MySQL服务器有它自己的内部缓存,你也可以构建你自己的缓存和汇总表。你可以自定义缓存表,以便于更好地将它用于过滤、排序、与其他表做联接、计数,以及其他用途。缓存表比其他应用层的缓存更加持久,因为它们在服务器重启后还会继续存在。

3.2应用层面的缓存

典型的应用层面的缓存一般都是将数据放在本机内存里,或者放在网络上的另外一台机器的内存里。

应用层面的缓存一般要比更低层面的缓存有更高的效率,因为应用可以把部分计算结果存放在缓存里。因而,缓存对两类工作很有帮助:读取数据和在这些读取数据之上做计算。一个很好的例子是HTML文本的各个分块。应用能够产生HTML段落,比如头条新闻,然后将它们缓存起来。随后打开的页面里就能将这些被缓存起来的头条新闻直接放到页面上。通常来讲,缓存之前处理的数据越多,使用缓存之后能节省的工作量也越多。

这里有个不足之处就是缓存的命中率越多,要提高它而花费的钱就越多。假如你需要50个不同版本的头条新闻,能根据用户所在的不同地域来显示不同的头条。你需要有足够的内存来保存这全部50个版本的头条新闻,任何一个给定版本的头条被请求得越少,那它的作废操作也会越复杂。

应用缓存有许多种类型,以下是其中的一部分:

本地缓存

这种缓存一般都比较小,只存在于请求处理时的进程内存空间里。它们可用于避免对同一资源的多次请求。因此,它也没什么精彩之处:它往往只是应用程序代码里的一个变量或一个散列表。举例来说,如果需要显示用户名,而你只知道用户ID,于是就设计一个函数叫get_name_from_id,把缓存功能放在这个函数里,具体代码如下:

如果你使用的是Perl,那么Memoize模块就是缓存函数调用结果的标准办法:

本地共享内存式缓存

这种缓存大小中等(几个GB)、访问快速,同时,难于在各机器间同步。它们适用于小型的、半静态的数据存储。举例来说,像每个州的城市列表、共享数据存储里的分块函数(使用映射表),或者应用了存活时间(Time-to-live,TTL)策略的数据。共享内存的最大好处是访问时非常快速--一般要比任何一种远程缓存要快很多。

分布存内存式缓存

分布式内存缓存的最著名的例子是memcached。分布式缓存比本地共享缓存要大,增长也容易。每一份缓存的数据只被创建一次,因为不会浪费你的内存,当同一份数据在各处缓存时也不会引起数据一致性问题。分布式内存擅长于对共享对象的排序,比如用户信息文件、评论和HTML片段。

这种缓存比本地共享缓存有更高的延迟,因此最有效的使用它们的方法是"多取"操作(比如在一次往返时,读取多个对象数据)。它们也要事先规划好怎么加入更多的节点,以及当一个节点崩溃时该怎么做。在这两种情形下,应用都要决定如何在各节点间分布或重新分布缓存对象。

磁盘缓存

磁盘是慢速的,所以,持久性对象最适合做磁盘缓存。对象往往不适合放在内存里,静态内容也是(比如预生成的自定义图片)。

非常有效地使用磁盘缓存和Web服务器的技巧是用404错误处理过程来捕捉没命中的缓存。加入你的Web应用要在页面的头部显示一个用户自定义的图片,暂且将这个图片命名为/images/welcomeback/john.jpg。如果这个图片不存在,它就会产生一个404错误,同时触发错误处理过程。接着,错误处理过程就生成这个图片,并存放在磁盘上,然后再启动一个重定向,或者仅仅把这个图片"回填"到浏览器里,那么,以后的访问都可以直接从文件里返回这个图片了。你可以将这项技巧用于许多类型的内容,举例来说,你用不着再缓存

那块用来显示最新头条新闻的HTML代码了,而把它们放入一个JavaScript文件里,然后在页面的头部插入指向这个js文件的引用。

缓存失效的操作也很简单:删除这个文件就可以了。你可以通过运行一个周期性的任务,将N分钟前创建的文件都删除掉,来实现TTL失效策略。如果想对缓存的尺寸做限制,那你可以实现一个最近最少使用(Least Recently Used,LRU)的失效策略,根据缓存内容的创建时间来删除内容。这个失效策略需要你在文件系统的挂接(Mount)选项上开启"访问时间"这个开关项。(实际操作时忽略noatime挂接选项来达到这个目的)。如果这么做了,你就应该使用内存文件系统来避免大量的磁盘操作。更多内容请查看第331页的"选择文件系统"。

3.3缓存控制策略

缓存引出的问题跟你数据库设计时违背了基本范式一样:它们包含了重复数据,这意味更新数据时要更新多个地方,还要避免读到过期的"坏"数据。以下是几个常用的缓存控制策略:

存活时间

每个缓存的对象都带有一个作废日期,用一个删除进程定时检查该数据的作废时间是否到达,如果是就立即删除它,你也可以暂时不理会它,直到下一次访问它时,如果已经超过作废时间,那才用一个更新的版本来替换它。这种作废策略最适用于很少变动或几乎不用刷新的数据。

显式作废

如果缓存里的数据过于"陈旧"而无法被接受,那么更新缓存数据的进程就立即将该旧版本的数据作废。这个策略里有两个变体类型:写-作废和写-更新。写-作废策略非常简单:直接将该数据标志为作废(也可以有从缓存里把它删除掉的选择)。写-更新策略就有更多的工作要做,因为你还要用最新的数据来替换旧缓存数据。但是,这个策略非常有用。特别是当生成缓存数据的代价很昂贵时(这个功能在写的进程里可能已经具备)。更新了缓存之后,将来的请求就用不着再等应用来生成这份数据了。如果你是在后台执行作废过程的,比如是基于TTL的作废过程,你可以在一个独立于任何用户请求的进程里生成最新版本的数据去替换缓存里已作废的数据。

读时作废

相对于在改变源数据时使缓存里对应的旧数据作废,有一个替代性的方法是保存一些信息来帮你判断从缓存里读出的数据是否已经作废。它有个比显式作废更显著的优点:随着时间的增长,它开销是固定的。假设你要将一个对象作废,而缓存里有100万个对象依赖于它。如果在写时将它作废,你就不得不将缓存里的相关100万个对象都作废。而100万次读的延迟是相当小的,这样就可以摊薄作废操作的时间成本,避免了加载时的长时间延迟。

采用写时作废策略的最简单的方法是实行对象版本化管理。在这个方法里,当把对象保存到缓存里时,你同时要保存该数据所依赖的版本号或时间戳。举例来说,假设你将一个用户在博客发表的文章的统计信息保存到缓存里,这些信息包括了发表文章的数量。当将它作为blog_stats对象缓存时,你同时也要把该用户当前的版本号也保存起来,因为这个统计信息依赖于具体某个用户。

无论什么时候你更新了依赖于用户的数据,也要随之改变用户的版本号。假设用户版本初始为0,你生成并缓存这些统计信息。当用户发表了一篇文章后,你就将用户版本号改为1(最好将这个版本号与文章存放在一起,尽管这个例子我们不必这么做)。那么,当你需要显示统计信息时,就先比较缓存的blog_stats对象的版本和缓存的用户版本,因为这时用户的版本比这个对象的版本要高,这样你就知道这份统计信息里的数据已经陈旧,须要更新了。这种用于内容作废的方法相当粗糙,因为它预先假设了缓存里的依赖于用户的数据也跟其他数据进行互动。这个条件并不总是成立。举例来说,如果用户编辑了一篇文章,你也会去增加用户的版本号,这使得缓存里的统计数据都要作废了,哪怕真正的统计信息(文章的数目)实际上根本没发生变化。折中的方案是朴素的,一个简单的缓存作废策略不仅仅要易于实现,还要有更高的效率。

对象版本化管理是标签式缓存的一个简化形式,后者可以处理更复杂的依赖关系。一个标签化缓存了解不同类别的依赖关系,并能单独追踪每一个对象的版本号。在上一章的图书俱乐部的例子里,你可以这样给评论做缓存:用用户版本号和书本版本号一起给评论做标签,具体像user_ver=1234和book_ver=5678这样。如果其中一个版本发生了变化,你就要刷新缓存。

3.4缓存对象的层次

把对象按层次结构存放在缓存中,有助于读取、作废和内存使用的操作。你不仅要将对象本身缓存起来,还要缓存它们的ID和对象分组的ID,这样就能方便成组地读取它们。

电子商务网站上的搜索结果就是这种技术很好的例子。一次搜索可能返回一个匹配的产品清单,清单里包含了产品的名称、描述、缩略图和价格。如果把整个列表存放到缓存里,那读取时的效率是低下的,因为其他的搜索可能也会包含了同样的某几个产品,这样做的结果就是数据重复、浪费内存。这个策略也难以在产品价格发生变化时到缓存里找到对应的产品并使其作废,因为必须逐个清单地去查看是否存在这个价格变化了的产品。

一个可以代替缓存整个清单的方法是把搜索结果里尽量少的信息缓存起来,比如搜索的结果数目和结果清单里的产品ID,这样你就可以单独缓存每一个产品资料了。这个方法解决了两个问题:一是消除了重复数据;二是更容易在单独产品的粒度上将缓存数据作废。

这个方法的缺点是你不得不从缓存里读取多个对象数据,而不是立即读取到整个搜索结果。然而,另一方面这也让你能更快地按照产品ID对搜索结果进行排序。现在,一次缓存命中就返回一个ID列表,如果缓存允许一次调用返回多个对象(Memcached有一个mget()调用支持这个功能),你就可以用这些ID再到缓存里去读取对应的产品资料。

如果你使用不当,这个方法也会产生古怪的结果。假设你使用TTL策略来作废搜索结果,当产品资料发生变化时,明确地将缓存里对应的单个产品资料作废。现在试着想象一个产品的描述发生了变化,它不再包含跟缓存里搜索结果匹配的关键字,而搜索结果还没到作废时间。于是,你的用户就会看到"陈旧"的搜索结果,因为缓存里的这个搜索结果仍然引用了那个描述已经发生变化的产品。

于多数应用来说,这一般不成为问题。如果你的应用无法容忍这个问题,那么就可以使用以版本为基础的缓存策略,在搜索之后,把产品版本号和搜索结果放在一起。在缓存里找到一个搜索结果后,把结果里的每个产品的版本号跟当前产品的版本号(也是在缓存里的)进行比较,如果发现有版本不符的,就通过重新搜索来获取新的搜索结果。

3.5内容的预生成

除了在应用层面上缓存数据之外,你还可以使用后台进程向服务器预先请求一些页面,然后将它们转换为静态页面保存在服务器上。如果页面是动态变化的,那你可以预生成页面中的一部分,然后使用一种技术,比如服务端整合,来生成最终页面。这样有助于减少预生成内容的大小和开销,因为本来你要为了各个最终页面上的细微差别而不得不重复存储大量的内容。

缓存预生成的内容会占用大量空间,也不可能总是去预生成所有东西。无论哪种形式的缓存,预生成内容里的最重要部分就是请求最多的那些内容。因此,像我们在本章的前面提到过的那样,你可以通过404错误处理程序来对内容作"按需生成"。这些预生成的内容一般都放在内存文件系统里,避免放在磁盘上。

4 扩展Mysql

如果MySQL完不成你所需要的任务,有一种可能性就是扩展它的能力。在这里,我们不是打算告诉你怎么去做扩展,而是要提一下这个可能性里的一些具体途径。如果你有兴趣去深究其中的任何一条途径,那么网上有很多资源可供使用,也有很多关于这个主题的书可以参考。当我们说"MySQL完不成你所需要的任务"时,其中包含了两个含义:一是MySQL 根本做不到,二是MySQL能做到,但是使用的办法不够好。无论哪个含义都是我们要扩展MySQL的理由。一个好消息是MySQL现在变得越来越模块化、多用途了。举例来说,MySQL 5.1 有大量可用的功能插件,它甚至允许存储引擎也是插件形式的,这样你就用不着把它们编译到MySQL服务器里了。

使用存储引擎将MySQL扩展为特定用途的数据库服务器是个伟大的想法。Brian Aker 已经编写了一个存储引擎的框架和一系列的文章、幻灯片来指导用户如何开发自己的存储引擎。这已经构成了一些主要的第三方存储引擎的基础。如果跟踪MySQL的内部邮件列表,你会发现现在有许多公司正在编写他们自己的内置存储引擎。举例来说,Friendster使用一个特别的存储引擎来做社交图操作,另外,我们还知道有一家公司正在做一个用来做模糊搜索的引擎。编写一个简单的自定义引擎一点也不难。

你也可以把存储引擎直接用作软件某一部分的接口。Sphinx就是个很好的例子,它直接与Sphinx全文检索软件通信。

MySQL 5.1 也允许全文检索解析器插件,如果你能编写UDF(请查看第5章),它擅长处理CPU密集的任务,这些任务必须在服务器线程环境下运行,对于SQL而言又太慢太笨重。因此,你可以用它们完成系统管理、服务集成、读取操作系统信息、调用Web服务、同步数据,以及其他更多相类似的任务。

MySQL代理另外有一个很棒的选项,可以让你向MySQL协议增加你自己的功能。Paul McCullagh的可扩展大二进制流框架项目(https://www.sodocs.net/doc/f714901162.html,)为你打通了在MySQL里存储大型对象的道路。因为MySQL是免费的、开源的软件,所以当你感觉它功能不够用时,你还可以去查看服务器代码。我们知道一些公司已经扩展了MySQL内部解析器的语法。近年来,还有第三方提交的许多有趣的MySQL扩展,涵盖了性能概要、扩展及

其他新奇的应用。当人们想扩展MySQL,MySQL的开发者们总是反应积极,并乐于提供帮助。你可以通过邮件列表internals@https://www.sodocs.net/doc/f714901162.html,(注册用户请访问

https://www.sodocs.net/doc/f714901162.html,)、MySQL论坛和IRC频道#mysql-dev跟他们取得联系。

5 可替代的Mysql

MySQL不是一个能适用于所有需要的万能解决方案。有些工作全部放到MySQL之外会更好,即使MySQL在理论上也能做到。

一个很明显的例子是在传统的文件系统里对数据进行排序而不是在表里。图像文件是又一个经典的案例:你可以把它们都放在BLOB字段里,但是这在多数时候都不是个好主意(注3)。通常的做法是把图像文件或其他大型二进制文件存在文件系统里,然后把文件名放在MySQL里。这样,应用就可以在MySQL之外读取文件了。在Web应用里,你可以把文件名放在元素的src属性里。

全文检索也是应该放在MySQL之外处理的任务之一--MySQL不像Lucene或Sphinx那样擅长于这类检索。

NDB API 可以被用于某一类型的任务。比如,虽然MySQL的NDB Cluster存储引擎不适合在高性能要求的Web应用中作排序操作,但是可以通过直接使用NDB API 来存储网站的session数据或用户注册信息。关于NDB API,你可以访问

https://www.sodocs.net/doc/f714901162.html,/doc/ndbapi/ en/index.html来获取更多信息。Apache上也有相应的NDB模块,你可以从http://code.google. com/p/mod-ndb/下载。

最后,对于有些操作,比如图形化的关系、树的遍历,关系数据库并不擅长做这些。MySQL 也不擅长分布式数据处理,因为它缺少并行查询的执行能力。你可能需要使用别的工具(与MySQL一起使用)来达到这一目的。

大型ORACLE数据库优化设计方案

大型ORACLE数据库优化设计方案 本文主要从大型数据库ORACLE环境四个不同级别的调整分析入手,分析ORACLE的系统结构和工作机理,从九个不同方面较全面地总结了ORACLE数据库的优化调整方案。 对于ORACLE数据库的数据存取,主要有四个不同的调整级别,第一级调整是操作系统级 包括硬件平台,第二级调整是ORACLE RDBMS级的调整,第三级是数据库设计级的调整,最后一个调整级是SQL级。通常依此四级调整级别对数据库进行调整、优化,数据库的整体性能会得到很大的改善。下面从九个不 同方面介绍ORACLE数据库优化设计方案。 一.数据库优化自由结构OFA(Optimal flexible Architecture) 数据库的逻辑配置对数据库性能有很大的影响,为此,ORACLE公司对表空间设计提出了一种优化结构OFA。使用这种结构进行设计会大大简化物理设计中的数据管理。优化自由结构OFA,简单地讲就是在数据库中可以高效自由地分布逻辑数据对象,因此首先要对数据库中的逻辑对象根据他们的使用方式和物理结构对数据库的影响来进行分类,这种分类包括将系统数据和用户数据分开、一般数据和索引数据分开、低活动表和高活动表分开等等。数据库逻辑设计的结果应当符合下面的准则:(1)把以同样方式使用的段类型存储在一起; (2)按照标准使用来设计系统;(3)存在用于例外的分离区域;(4)最小化表空间冲突;(5)将数 据字典分离。 二、充分利用系统全局区域SGA(SYSTEM GLOBAL AREA) SGA是oracle数据库的心脏。用户的进程对这个内存区发送事务,并且以这里作为高速缓存读取命中的数据,以实现加速的目的。正确的SGA大小对数据库的性能至关重要。SGA 包括以下几个部分: 1、数据块缓冲区(data block buffer cache)是SGA中的一块高速缓存,占整个数据库大小 的1%-2%,用来存储从数据库重读取的数据块(表、索引、簇等),因此采用least recently used (LRU,最近最少使用)的方法进行空间管理。 2、字典缓冲区。该缓冲区内的信息包括用户账号数据、数据文件名、段名、盘区位置、表 说明和权限,它也采用LRU方式管理。 3、重做日志缓冲区。该缓冲区保存为数据库恢复过程中用于前滚操作。 4、SQL共享池。保存执行计划和运行数据库的SQL语句的语法分析树。也采用LRU算法 管理。如果设置过小,语句将被连续不断地再装入到库缓存,影响系统性能。 另外,SGA还包括大池、JAVA池、多缓冲池。但是主要是由上面4种缓冲区构成。对这

mysql优化笔记

◆Mysql数据库的优化技术<大型网站优化技术> 对mysql优化时一个综合性的技术,主要包括 a: 表的设计合理化(符合3NF) b: 添加适当索引(index) [四种: 普通索引、主键索引、唯一索引unique、全文索引] c: 分表技术(水平分割、垂直分割) d: 读写[写: update/delete/add]分离 e: 存储过程[模块化编程,可以提高速度] 数据库的三层结构: f: 对mysql配置优化[配置最大并发数my.ini, 调整缓存大小] g: mysql服务器硬件升级 h: 定时的去清除不需要的数据,定时进行碎片整理(MyISAM) CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name [USING index_type] ON tbl_name (index_col_name,...) ◆什么样的表才是符合3NF (范式) 表的范式,是首先符合1NF, 才能满足2NF , 进一步满足3NF 1NF: 即表的列的具有原子性,不可再分解,即列的信息,不能分解, 只有数据库是关系型数据库(mysql/oracle/db2/informix/sysbase/sql server),就自动的满足1NF ?数据库的分类 关系型数据库: mysql/oracle/db2/informix/sysbase/sql server 非关系型数据库: (特点: 面向对象或者集合) NoSql数据库: MongoDB(特点是面向文档) 2NF: 表中的记录是唯一的, 就满足2NF, 通常我们设计一个主键来实现id primary key ; 3NF: 即表中不要有冗余数据, 就是说,表的信息,如果能够被推导出来,就不应该单独的设计一个字段来存放. 比如下面的设计就是不满足3NF:显示推导处理

数据库及SQL代码优化方案

1.1、数据库及SQL代码优化方案 (1)每周检查统计信息是否及时更新。 (2)每周检查各索引是否有效。 (3)每周检查分区是否正确。 (4)每周检查执行计划是否正确。 (5)每天检查RAC和ASM是否正常运行。 (6)每天检查相关日志是否正常备份。 (7)每天检查相关文件系统和表空间的占用率是否在国家税务总局规定的阀值以下。 (8)在每月申报高峰等业务繁忙期采样并找出消耗I/O资源和CPU资源较多的SQL语句。 (9)分析上述SQL语句,与软件服务商充分沟通后,提出优化建议。 (10)在每月申报高峰期每隔15分钟检查一次数据库连接数,发现异常及时处理。 1.1.1、系统数据库索引、表分区和对象优化方案 数据库对象的优化主要包括:表、索引和sequence等对象,通过优化对象参数、调整对象属性(例如分区表、分区索引、反转索引等等)等方法来实现对数据库对象的优化改造。 1.1.1.1表和索引并行参数优化 数据库的表和索引的并行参数值的设置对相关的sql语句的执行计划会造成影响,表和索引的degree值大于1,执行计划就偏向于使用全表和全索引扫描,另外如果并行参数值过大,短时间内也会对主机和数据库的资源造成很大的压力,因此在oltp的数据库下建议将表和索引的degree值设为1。 1.1.1.2热点大表的分区改造 对访问量很大、表的记录数很多、存在热块争用的表,可以考虑对表和索引进行适当的分区改造,分散访问压力,提高数据访问的性能。 对以下表的记录数超过1000万并且记录数持续增长的大表,建议进行分区

改造(地区+时间): 1.1.1.3分区索引的清理 对最近30天数据库分区索引访问情况进行统计,对访问次数为0的分区索引和应用部门进行确认,若确认为多余的索引,建议进行删除清理。 1.1.1.4Sequence序列优化 加大sequence 的 cache,并使用noorder选项。在RAC中经常会遇到SQ 锁等待,这是因为在RAC环境下,sequence也成为全局性的了,不同节点要生成序列号,就会产生对sequence资源的争用。而目前大多数系统中,sequence 大多数被作为主键发生器来使用,使用的频率十分高,在RAC环境中,需要设置较大的 sequence cache,否则会造成较为严重的争用,从而影响业务。 1.1.2、SQL硬解析优化方案 1.1. 2.1相关知识点介绍 1.1. 2.1.1Oracle的硬解析和软解析 Oracle对sql的处理过程:当发出一条sql语句交付Oracle,在执行和获取结果前,Oracle对此sql将进行几个步骤的处理过程: 1、语法检查(syntax check) 检查此sql的拼写是否语法。 2、语义检查(semantic check) 诸如检查sql语句中的访问对象是否存在及该用户是否具备相应的权限。 3、对sql语句进行解析(prase) 利用内部算法对sql进行解析,生成解析树(parse tree)及执行计划(execution plan)。 4、执行sql,返回结果(execute and return) 其中,软、硬解析就发生在第三个过程里。 Oracle利用内部的hash算法来取得该sql的hash值,然后在library cache

mysql服务性能优化my_cnf配置说明详解16G内存

mysql服务性能优化—https://www.sodocs.net/doc/f714901162.html,f配置说明详解 (16G内存) MYSQL服务器https://www.sodocs.net/doc/f714901162.html,f配置文档详解 硬件:内存16G [client] port = 3306 socket = /data/3306/mysql.sock [mysql] no-auto-rehash [mysqld] user = mysql port = 3306 socket = /data/3306/mysql.sock basedir = /usr/local/mysql datadir = /data/3306/data open_files_limit = 10240 back_log = 600 #在MYSQL暂时停止响应新请求之前,短时间内的多少个请求可以被存在堆栈中。如果系统在短时间内有很多连接,则需要增大该参数的值,该参数值指定到来的TCP/IP连接的监听队列的大小。默认值50。 max_connections = 3000 #MySQL允许最大的进程连接数,如果经常出现Too Many Connections的错误提示,则需要增大此值。 max_connect_errors = 6000 #设置每个主机的连接请求异常中断的最大次数,当超过该次数,MYSQL服务器将禁止host 的连接请求,直到mysql服务器重启或通过flush hosts命令清空此host的相关信息。 table_cache = 614 #指示表调整缓冲区大小。# table_cache 参数设置表高速缓存的数目。每个连接进来,都会至少打开一个表缓存。#因此, table_cache 的大小应与 max_connections 的设置有关。例如,对于 200 个#并行运行的连接,应该让表的缓存至少有 200 × N ,这里 N 是应用可以执行的查询#的一个联接中表的最大数量。此外,还需要为临时表和文件保留一些额外的文件描述符。 # 当 Mysql 访问一个表时,如果该表在缓存中已经被打开,则可以直接访问缓存;如果#还

大型数据库的优化方法及实例

大型数据库的优化方法及实例 尹德明杨富玉杨莹时鹏泉 中国金融电子化公司 E_mail: dm_mis@https://www.sodocs.net/doc/f714901162.html, 1.引言 随着银行业数据集中,作为整个系统核心的数据库,其存放、管理的数据越来越庞大,已经超越GB而到达TB数据量层次,数据库的性能成为整个系统性能的关键。 国库会计核算系统是国库部门用以进行国库业务的会计核算,并通过支付系统、国库内部往来、同城票据交换系统进行资金清算的计算机网络系统。国家金库会计核算系统每天处理的税票数据多达10万笔,税收高峰可能会到100万笔,这样一年累计下来其中历史登记簿中的数据达到2000万条以上,给检索和数据处理带来非常大的困难。 如何对于一个已经上线运行的重要业务系统,通过对数据库的优化和简单的系统流程调整,实现系统性能的大幅提升具有现实、迫切、重要的意义。 2.优化策略 根据Sybase的数据存储机制,在进行一段时期的数据删除、插入和更新等操作后,数据库往往会产生大量的碎片。大量碎片的存在,会严重影响数据库的I/O性能,如果在使用数据库一段时间后,整理碎片,可以提高数据库的性能。由于国家金库会计核算系统在预处理、日间报解、日初始化等步骤,会大批量进行数据删除、插入和更新等操作,因此会产生大量的数据碎片。碎片整理对于国家金库会计核算系统性能优化将会有重要效果。 Sybase Adaptive Server对于按顺序存储和访问的页,在单个I/O中最多读取八个数据页。由于大部分I/O时间都花在磁盘上的物理定位和搜寻上,因此大I/O可极大地减少磁盘访问时间。在大多数情况下,希望在缺省数据高速缓存中配置一个16K缓冲池。为事务日志创建4K缓冲池可极大地减少数据库系统日志写操作的数量。 好的性能同优良的数据库设计及优秀的程序写法关系极大,可以这样说,如果一个数据库没有好的设计及对程序未进行优化的话即使对参数进行调整也不可能有好的性能。 3.数据库碎片整理 由于Sybase是通过OAM页、分配单元和扩展页来管理数据的,所以对OLTP应用的Database Server会十分频繁地进行数据删除、插入和更新等操作,时间一长就会出现以下几种情况: (1)页碎片 即本来可以存放在一个页上的数据却分散地存储在多个页上。如果这些页存储在不同的扩展单元上,Database Server就要访问多个扩展单元,因此降低了系统性能。 (2)扩展单元碎片 在堆表中,当删除数据链中间的记录行时,会出现空页。随着空页的累积,扩展单元的利用率也会下降,从而出现扩展单元碎片。带cluster index的table也有可能出现扩展单元碎片。当有扩展单元碎片存在,会出现以下问题: 对表进行处理时,常常出现死锁;利用较大的I/O操作或增加I/O缓冲区的大小也无法改变较慢的I/O速度;行操作的争用。 (3)扩展单元遍历 带有cluster index的table会由于插入记录而导致页分裂,但当删除记录后,页会获得释放,从而形成跨几个扩展单元和分配单元的数据,而要访问该数据就必须遍历几个扩展单元和分配单元。这将导致访问/查询记录的时间大大延长,开始时数据库的性能虽然较高,

谈谈项目中常用的MySQL优化方法

谈谈项目中常用的MySQL优化方法 本文我们来谈谈项目中常用的MySQL优化方法,共19条,具体如下: 一、EXPLAIN 做MySQL优化,我们要善用EXPLAIN查看SQL执行计划。 下面来个简单的示例,标注(1、2、3、4、5)我们要重点关注的数据: type列,连接类型。一个好的SQL语句至少要达到range级别。杜绝出现all级别。 key列,使用到的索引名。如果没有选择索引,值是NULL。可以采取强制索引方式 key_len列,索引长度。 rows列,扫描行数。该值是个预估值。 extra列,详细说明。注意,常见的不太友好的值,如下:Using filesort,Using temporary。 二、SQL 语句中IN 包含的值不应过多 MySQL对于IN做了相应的优化,即将IN中的常量全部存储在一个数组里面,而且这个数组是排好序的。但是如果数值较多,产生的消耗也是比较大的。再例如:select id from t where num in(1,2,3) 对于连续的数值,能用between就不要用in了;再或者使用连接来替换。 三、SELECT语句务必指明字段名称 SELECT*增加很多不必要的消耗(CPU、IO、内存、网络带宽);增加了使用覆盖索引的可能性;当表结构发生改变时,前断也需要更新。所以要求直接在select后面接上字段名。 四、当只需要一条数据的时候,使用limit 1 这是为了使EXPLAIN中type列达到const类型 五、如果排序字段没有用到索引,就尽量少排序 六、如果限制条件中其他字段没有索引,尽量少用or or两边的字段中,如果有一个不是索引字段,而其他条件也不是索引字段,会造成该查询不走索引的情况。很多时候使用union all或者是union(必要的时候)的方式来代替“or”

SQL Server数据库优化方案汇总

SQL Server数据库优化方案汇总 50种方法优化SQL Server 1、没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷) 2、I/O吞吐量小,形成了瓶颈效应。 3、没有创建计算列导致查询不优化。 4、内存不足 5、网络速度慢 6、查询出的数据量过大(可以采用多次查询,其他的方法降低数据量) 7、锁或者死锁(这也是查询慢最常见的问题,是程序设计的缺陷) 8、sp_lock,sp_who,活动的用户查看,原因是读写竞争资源。 9、返回了不必要的行和列 10、查询语句不好,没有优化 可以通过如下方法来优化查询 : 1、把数据、日志、索引放到不同的I/O设备上,增加读取速度,以前可以将Tempdb应放在RAID0上,SQL2000不在支持。数据量(尺寸)越大,提高I/O越重要. 2、纵向、横向分割表,减少表的尺寸(sp_spaceuse) 3、升级硬件 4、根据查询条件,建立索引,优化索引、优化访问方式,限制结果集的数据量。注意填充因子要适当(最好是使用默认值0)。索引应该尽量小,使 用字节数小的列建索引好(参照索引的创建),不要对有限的几个值的字段建单一索引如性别字段 5、提高网速; 6、扩大服务器的内存,Windows 2000和SQL server 2000能支持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、DB Server 和APPLication Server 分离;OLTP和OLAP分离

MySQL5.1性能优化方案

MySQL5.1性能优化方案 1.平台数据库 1.1.操作系统 Red Hat Enterprise Linux Server release 5.4 (Tikanga) ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.9, dynamically linked (uses shared libs), for GNU/Linux 2.6.9, stripped 32位Linux服务器,单独作为MySQL服务器使用。 1.2.M ySQL 系统使用的是MySQL5.1,最新的MySQL5.5较之老版本有了大幅改进。主要体现在以下几个方面: 1)默认存储引擎更改为InnoDB InnoDB作为成熟、高效的事务引擎,目前已经广泛使用,但MySQL5.1之前的版本默认引擎均为MyISAM,此次MySQL5.5终于将默认数据库存储引擎改为InnoDB,并且引进了Innodb plugin 1.0.7。此次更新对数据库的好处是显而易见的:InnoDB的数据恢复时间从过去的一个甚至几个小时,缩短到几分钟(InnoDB plugin 1.0.7,InnoDB plugin 1.1,恢复时采用红-黑树)。InnoDB Plugin 支持数据压缩存储,节约存储,提高内存命中率,并且支持adaptive flush checkpoint, 可以在某些场合避免数据库出现突发性能瓶颈。 Multi Rollback Segments:原来InnoDB只有一个Segment,同时只支持1023的并发。现已扩充到128个Segments,从而解决了高并发的限制。 2)多核性能提升

SQL数据库优化方法

SQL数据库优化方法

目录 1 系统优化介绍 (1) 2 外围优化 (1) 3 SQL优化 (2) 3.1 注释使用 (2) 3.2 对于事务的使用 (2) 3.3 对于与数据库的交互 (2) 3.4 对于SELECT *这样的语句, (2) 3.5 尽量避免使用游标 (2) 3.6 尽量使用count(1) (3) 3.7 IN和EXISTS (3) 3.8 注意表之间连接的数据类型 (3) 3.9 尽量少用视图 (3) 3.10 没有必要时不要用DISTINCT和ORDER BY (3) 3.11 避免相关子查询 (3) 3.12 代码离数据越近越好 (3) 3.13 插入大的二进制值到Image列 (4) 3.14 Between在某些时候比IN 速度更快 (4) 3.15 对Where条件字段修饰字段移到右边 (4) 3.16 在海量查询时尽量少用格式转换。 (4) 3.17 IS NULL 与IS NOT NULL (4) 3.18 建立临时表, (4) 3.19 Where中索引的使用 (5) 3.20 外键关联的列应该建立索引 (5) 3.21 注意UNion和`UNion all 的区别 (5) 3.22 Insert (5) 3.23 order by语句 (5) 3.24 技巧用例 (6) 3.24.1 Sql语句执行时间测试 (6)

1系统优化介绍 在我们的项目中,由于客户的使用时间较长或客户的数据量大,造成系统运行速度慢,系统性能下降就容易造成数据库阻塞。这是个非常痛苦的事情,用户的查询、新增、修改等需要花很多时间,甚至造成系统死机的现象。速度慢的原因主要是来自于资源不足。 数据库的优化通常可以通过对网络、硬件、操作系统、数据库参数和应用程序的优化来进行。最常见的优化手段就是对硬件的升级。根据统计,对网络、硬件、操作系统、数据库参数进行优化所获得的性能提升,全部加起来最多只占数据库系统性能提升的40%左右(我将此暂时称之为外围优化);其余大部分系统性能提升来自对应用程序的优化,对于应用程序的优化可以分为对源代码的优化及数据库SQL语句的优化。在本文档只介绍外围优化及SQL语句的优化,对于源代码的优化需要相关方面的专家,形成统一的规范。 一个数据库系统的生命周期可以分成:设计、开发和成品三个阶段。在设计阶段进行数据库性能优化的成本最低,收益最大。在成品阶段进行数据库性能优化的成本最高,收益最小。规范的代码和高性能的语句,功在平时,利在千秋。 2外围优化 1、将操作系统与SQL数据库的补丁打到最高版本,WIN2003最高补丁是SP4, SQL SERVER2000最高补丁是SP4(版本号:2039)。 2、在服务器上不要安装与VA程序任何无相关的软件,甚至一些与VA运行 无关的服务都可以停掉。一般只安装SQL数据库、VA服务端服务及杀毒 软件。 3、杀毒软件避免对大文件进行扫描,特别是数据库(MDF和LDF)文件,一 定要从杀毒软件的范围内排除掉。 4、在进行服务器分区时,分区不要太多,两三个分区就可以了。分区最好 都使用NTFS格式。

MySQL优化原则

MySQL优化原则 转载2014年05月20日10:27:13 1113 数据库已成为互联网应用必不可少的底层依赖,其中MySQL作为开源数据库得到了更加广泛的应用。最近一直专注于项目工程的开发,对开发过程中使用到的一些关于数据库的优化原则进行了总结,希望能够帮助更多的应用开发人员更好的使用MySQL数据库。 MySQL的优化主要包括三个方面,首先是SQL语句的优化,其次是表结构的优化,这里主要指索引的优化,最后是服务器配置的优化。第四点代码结构的优化!!! 1.SQL语句的优化 1)查询语句应该尽量避免全表扫描,首先应该考虑在Where子句以及OrderBy子句上建立索引,但是每一条SQL语句最多只会走一条索引,而建立过多的索引会带 来插入和更新时的开销,同时对于区分度不大的字段,应该尽量避免建立索引,可 以在查询语句前使用explain关键字,查看SQL语句的执行计划,判断该查询语 句是否使用了索引; 2)应尽量使用EXIST和NOT EXIST代替 IN和NOT IN,因为后者很有可能导致全表扫描放弃使用索引; 3)应尽量避免在Where子句中对字段进行NULL判断,因为NULL判断会导致全表扫描; 4)应尽量避免在Where子句中使用or作为连接条件,因为同样会导致全表扫描; 5)应尽量避免在Where子句中使用!=或者<>操作符,同样会导致全表扫描; 6)使用like “%abc%”或者like “%abc”同样也会导致全表扫描,而like “abc%”会使用索引。 7)在使用Union操作符时,应该考虑是否可以使用Union ALL来代替,因为Union 操作符在进行结果合并时,会对产生的结果进行排序运算,删除重复记录,对于没

数据库优化设计方案

数据库优化方案设计 XX信息管理平台从大型数据库环境四个不同级别的调整分析入手,分析数据库平台的系统结构和工作机理,从九个不同方面设计数据库的优化方案。 对于数据库的数据优化,主要有四个不同的调整级别,第一级调整是操作系统级包括硬件平台,第二级调整是RDBMS级的调整,第三级是数据库设计级的调整,最后一个调整级是SQL级。通常依此四级调整级别对数据库进行调整、优化,数据库的整体性能会得到很大的改善。下面从九个不同方面介绍数据库优化设计方案。 一、数据库优化自由结构 数据库的逻辑配置对数据库性能有很大的影响。为此,数据库平台一般对表空间设计提出有相应的优化结构,如ORACLE公司的OFA(Optimal flexible Architecture),使用这种结构进行设计会大大简化物理设计中的数据管理。优化自由结构,简单地讲就是在数据库中可以高效自由地分布逻辑数据对象,因此首先要对数据库中的逻辑对象根据他们的使用方式和物理结构对数据库的影响来进行分类,这种分类包括将系统数据和用户数据分开、一般数据和索引数据分开、低活动表和高活动表分开等等。 数据库逻辑设计的结果应当符合下面的准则: (1)把以同样方式使用的段类型存储在一起; (2)按照标准使用来设计系统; (3)存在用于例外的分离区域; (4)最小化表空间冲突; (5)将数据字典分离。 二、充分利用系统全局区域 系统全局区域是数据库平台的心脏,如Oracle数据库的SGA(SYSTEM GLOBAL AREA) 。用户的进程对这个内存区发送事务,并且以这里作为高速缓存读取命中的数据,以实现加速的目的。正确的SGA大小对数据库的性能至关重要。SGA包括以下几个部分: 1、数据块缓冲区(data block buffer cache)是SGA中的一块高速缓存,占整个数据库大小的1%-2%,用来存储从数据库重读取的数据块(表、索引、簇等),因此采用least recently used (LRU,最近最少使用)的方法进行空间管理。 2、字典缓冲区。该缓冲区内的信息包括用户账号数据、数据文件名、段名、盘区位置、表说明和权限,它也采用LRU方式管理。 3、重做日志缓冲区。该缓冲区保存为数据库恢复过程中用于前滚操作。 4、SQL共享池。保存执行计划和运行数据库的SQL语句的语法分析树。也采用LRU 算法管理。如果设置过小,语句将被连续不断地再装入到库缓存,影响系统性能。 另外,SGA还包括大池、JAVA池、多缓冲池。但是主要是由上面4种缓冲区构成。对这些内存缓冲区的合理设置,可以大大加快数据查询速度,一个足够大的内存区可以把绝大多数数据存储在内存中,只有那些不怎么频繁使用的数据,才从磁盘读取,这样就可以大大提高内存区的命中率。 三、规范与反规范设计数据库

千万级的mysql数据库与优化方法

千万级的mysql数据库与优化方法 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在where 及order by 涉及的列上建立索引。 2.应尽量避免在where 子句中对字段进行null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如: Sql代码 可以在num上设置默认值0,确保表中num列没有null值,然后这样查询: Sql代码 3.应尽量避免在where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。 4.应尽量避免在where 子句中使用or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:Sql代码 可以这样查询: Sql代码 5.in 和not in 也要慎用,否则会导致全表扫描,如: 对于连续的数值,能用between 就不要用in 了: 6.下面的查询也将导致全表扫描: Sql代码

若要提高效率,可以考虑全文检索。 7.如果在where 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。如下面语句将进行全表扫描: Sql代码 可以改为强制查询使用索引: 8.应尽量避免在where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如: 应改为: 9.应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:Sql代码 应改为: 10.不要在where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。 11.在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。 12.不要写一些没有意义的查询,如需要生成一个空表结构:

大型ORACLE数据库优化设计方案

大型ORACLE数据库优化设计方案 摘要主要从大型数据库ORACLE环境四个不同级别的调整分析入手,分析ORACLE的系统结构和工作机理,从九个不同方面较全面地总结了ORACLE数据库的优化调整方案。 关键词ORACLE数据库环境调整优化设计方案 对于ORACLE数据库的数据存取,主要有四个不同的调整级别,第一级调整是操作系统级包括硬件平台,第二级调整是ORACLERDBMS级的调整,第三级是数据库设计级的调整,最后一个调整级是SQL级。通常依此四级调整级别对数据库进行调整、优化,数据库的整体性能会得到很大的改善。下面从九个不同

方面介绍ORACLE数据库优化设计方案。 一.数据库优化自由结构OFA(OptimalflexibleArchitecture) 数据库的逻辑配置对数据库性能有很大的影响,为此,ORACLE公司对表空间设计提出了一种优化结构OFA。使用这种结构进行设计会大大简化物理设计中的数据管理。优化自由结构OFA,简单地讲就是在数据库中可以高效自由地分布逻辑数据对象,因此首先要对数据库中的逻辑对象根据他们的使用方式和物理结构对数据库的影响来进行分类,这种分类包括将系统数据和用户数据分开、一般数据和索引数据分开、低活动表和高活动表分开等等。 二、充分利用系统全局区域SGA (SYSTEMGLOBALAREA) SGA是oracle数据库的心脏。用户的进程对这个内存区发送事务,并且以这里作为高速缓存读取命中的数据,以实现加速的目的。正确的SGA大小对数据库

的性能至关重要。SGA包括以下几个部分: 2、字典缓冲区。该缓冲区内的信息包括用户账号数据、数据文件名、段名、盘区位置、表说明和权限,它也采用LRU 方式管理。 3、重做日志缓冲区。该缓冲区保存为数据库恢复过程中用于前滚操作。 4、SQL共享池。保存执行计划和运行数据库的SQL语句的语法分析树。也采用LRU算法管理。如果设置过小,语句将被连续不断地再装入到库缓存,影响系统性能。 另外,SGA还包括大池、JA V A池、多缓冲池。但是主要是由上面4种缓冲区构成。对这些内存缓冲区的合理设置,可以大大加快数据查询速度,一个足够大的内存区可以把绝大多数数据存储在内存中,只有那些不怎么频繁使用的数据,才从磁盘读取,这样就可以大大提高内存区的命中率。三、规范与反规范设计数据库

数据库查询优化实验报告_SQLServer2008

SQL Server 2008数据查询的优化方法研究摘要 随着数据存储需求的日益增长,对关系数据的管理和访问就成为数据库技术必须解决的问题。本文主要论述关系数据库查询优化技术,并从它的优化技术进行深入探讨,对系统实现做了一定的论述,并进行了部分的程序实现。 关键词:数据库查询系统优化 引言 SQLServer是是由微软公司开发的基于Windows操作系统的关系型数据库管理系统,它是一个全面的、集成的、端到端的数据解决方案,为企业中的用户提供了一个安全、可靠和高效的平台用于企业数据管理和商业智能应用。目前,许多中小型企业的数据库应用系统都是用SQLServer作为后台数据库管理系统设计开发的。设计一个应用系统并不难,但是要想使系统达到最优化的性能并不是一件容易的事。根据多年的实践,由于初期的数据库中表的记录数比较少,性能不会有太大问题,但数据积累到一定程度,达到数百万甚至上千万条,全面扫描一次往往需要数十分钟,甚至数小时。20%的代码用去了80%的时间,这是程序设计中的一个著名定律,在数据库应用程序中也同样如此。如果用比全表扫描更好的查询策略,往往可以使查询时间降为几分钟。而且我们知道,目前数据库系统应用中,查询操作占了绝大多数,查询优化成为数据库性能优化最为重要的手段之一。 影响查询效率的因素 SQLServer处理查询计划的过程是这样的:在做完查询语句的词法、语法检查之后,将语句提交给SQLServer的查询优化器,查询优化器通过检查索引的存在性、有效性和基于列的统计数据来决定如何处理扫描、检索和连接,并生成若干执行计划,然后通过分析执行开销来评估每个执行计划,从中选出开销最小的执行计划,由预编译模块对语句进行处理并生成查询规划,然后在合适的时间提交给系统处理执行,最后将执行结果返回给用户。所以,SQLServer中影响查询效率的因素主要有以下几种: 1.没有索引或者没有用到索引。索引是数据库中重要的数据结构,使用索引的目的是避免全表扫描,减少磁盘I/O,以加快查询速度。 2.没有创建计算列导致查询不优化。 3.查询出的数据量过大(可以采用多次查询,其他的方法降低数据量)。 4.返回了不必要的行和列。 5.查询语句不好,没有优化。其中包括:查询条件中操作符使用是否得当;查询条件中的数据类型是否兼容;对多个表查询时,数据表的次序是否合理;多个选择条件查询时,选择条件的次序是否合理;是否合理安排联接选择运算等。 SQLServer数据查询优化方法 1、避免使用不兼容的数据类型。例如float和int、char和varchar、binary和varbinary 是不兼容的。数据类型的不兼容可能使优化器无法执行一些本来可以进行的优化操作。例如: select name from employee where salary >60000

Mysql千万级别数据优化方案总结

Mysql千万级别数据优化方案 目录 目录 (1) 一、目的与意义 (2) 1)说明 (2) 二、解决思路与根据(本测试表中数据在千万级别) (2) 1)建立索引 (2) 2)数据体现(主键非索引,实际测试结果其中fid建立索引) (2) 3)MySQL分页原理 (2) 4)经过实际测试当对表所有列查询时 (2) 三、总结 (3) 1)获得分页数据 (3) 2)获得总页数:创建表记录大数据表中总数通过触发器来维护 (3)

一、目的与意义 1)说明 在MySql单表中数据达到千万级别时数据的分页查询结果时间过长,对此进行优达 到最优效果,也就是时间最短;(此统计利用的jdbc连接,其中fid为该表的主键;) 二、解决思路与根据(本测试表中数据在千万级别) 1)建立索引 优点:当表中有大量记录时,若要对表进行查询,第一种搜索信息方式是全表搜 索,是将所有记录一一取出,和查询条件进行一一对比,然后返回满足条件的记 录,这样做会消耗大量数据库系统时间,并造成大量磁盘I/O操作;第二种就是 在表中建立索引,然后在索引中找到符合查询条件的索引值,最后通过保存在索 引中的ROWID(相当于页码)快速找到表中对应的记录。 缺点:当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,降 低了数据的维护速度。 2)数据体现(主键非索引,实际测试结果其中fid建立索引) 未创建索引:SELECT fid from t_history_data LIMIT 8000000,10结果:13.396s 创建索引:SELECT fid from t_history_data LIMIT 8000000,10结果:2.896s select*fromt_history_datawherefidin (任意十条数据的id )结果:0.141s 首先通过分页得到分页的数据的ID,将ID拼接成字符串利用SQL语句 select * from table where ID in (ID字符串)此语句受数据量大小的影响比较小 (如上测试); 3)MySQL分页原理 MySQL的limit工作原理就是先读取n条记录,然后抛弃前n条,读m条想要 的,所以n越大,性能会越差。 优化前SQL: SELECT * FROM v_history_data LIMIT 5000000, 1010.961s 优化后SQL: SELECT * FROM v_history_data INNER JOIN (SELECT fid FROM t_history_data LIMIT 5000000, 10) a USING (fid)1.943s 分别在于,优化前的SQL需要更多I/O浪费,因为先读索引,再读数据,然后 抛弃无需的行。而优化后的SQL(子查询那条)只读索引(Cover index)就可以了, 然后通过member_id读取需要的列 4)经过实际测试当对表所有列查询时 select * from table 会比select (所有列名)from table 快些(以查询8000000

优化MySQL数据库性能的几个好方法

1、选取最适用的字段属性 MySQL可以很好的支持大数据量的存取,但是一般说来,数据库中的表越小,在它上面执行的查询也就会越快。因此,在创建表的时候,为了获得更好的性能,我们可以将表中字段的宽度设得尽可能小。例如,在定义邮政编码这个字段时,如果将其设置为CHAR(255),显然给数据库增加了不必要的空间,甚至使用VARCHAR这种类型也是多余的,因为CHAR(6)就可以很好的完成任务了。同样的,如果可以的话,我们应该使用MEDIUMINT而不是BIGIN来定义整型字段。 另外一个提高效率的方法是在可能的情况下,应该尽量把字段设置为NOT NULL,这样在将来执行查询的时候,数据库不用去比较NULL值。 对于某些文本字段,例如“省份”或者“性别”,我们可以将它们定义为ENUM类型。因为在MySQL中,ENUM类型被当作数值型数据来处理,而数值型数据被处理起来的速度要比文本类型快得多。这样,我们又可以提高数据库的性能。 2、使用连接(JOIN)来代替子查询(Sub-Queries) MySQL从4.1开始支持SQL的子查询。这个技术可以使用SELECT语句来创建一个单列的查询结果,然后把这个结果作为过滤条件用在另一个查询中。例如,我们要将客户基本信息表中没有任何订单的客户删除掉,就可以利用子查询先从销售信息表中将所有发出订单的客户ID取出来,然后将结果传递给主查询,如下所示: DELETE FROM customerinfo WHERE CustomerID NOT in (SELECT CustomerID FROM salesinfo ) 使用子查询可以一次性的完成很多逻辑上需要多个步骤才能完成的SQL操作,同时也可以避免事务或者表锁死,并且写起来也很容易。但是,有些情况下,子查询可以被更有效率的连接(JOIN).. 替代。例如,假设我们要将所有没有订单记录的用户取出来,可以用下面这个查询完成:

sql优化方案讲解

Sql优化方案 一.数据库优化技术 1.索引(强烈建议使用) 1.1优点 创建索引可以大大提高系统的性能。 第一,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。 第二,可以大大加快数据的检索速度,这也是创建索引的最主要的原因。 第三,可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。 第四,在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。 第五,通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的 性能。 1.2 缺点 第一,创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。 第二,索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。 第三,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这 样就降低了数据的维护速度。 1.3 使用准则 索引是建立在数据库表中的某些列的上面。因此,在创建索引的时候,应该仔细考虑在哪些列上可以创建索引,在哪些列上不能创建索引。 一般来说,应该在这些列上创建索引。 第一,在经常需要搜索的列上,可以加快搜索的速度;

第二,在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构; 第三,在经常用在连接的列上,这些列主要是一些外键,可以加快连接的速度; 第四,在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的; 第五,在经常需要排序的列上创建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间; 第六,在经常使用在WHERE子句中的列上面创建索引,加快条件的判断速度。 同样,对于有些列不应该创建索引。一般来说,不应该创建索引的的这些列具有下列特点: 第一,对于那些在查询中很少使用或者参考的列不应该创建索引。这是因为,既然这些列很少使用到,因此有索引或者无索引,并不能提高查询速度。相反,由 于增加了索引,反而降低了系统的维护速度和增大了空间需求。 第二,对于那些只有很少数据值的列也不应该增加索引。这是因为,由于这些列的取值很少,例如人事表的性别列,在查询的结果中,结果集的数据行占了表中数据行的很大比例,即需要在表中搜索的数据行的比例很大。增加索引,并不能明显加快检索速度。 第三,对于那些定义为text, image和bit数据类型的列不应该增加索引。这是因为,这些列的数据量要么相当大,要么取值很少。 第四,当修改性能远远大于检索性能时,不应该创建索引。这是因为,修改性能 和检索性能是互相矛盾的。当增加索引时,会提高检索性能,但是会降低修改性能。当减少索引时,会提高修改性能,降低检索性能。因此,当修改性能远远大 于检索性能时,不应该创建索引。 1.4 总结 1)索引提高了数据库的检索性能,但一定程度上牺牲了修改性能。因此适用于 “多查询少修改”(insert,update,delete)的表。 2)对此类表中的外键,需要分组,排序或作为检索条件的字段建立索引 3)对此类表中查询使用少,字段取值少,字段数据量大的不应创建索引

MySQL数据库性能(SQL)优化方案-期末论文

高级数据库技术——期末论文 基于SQL查询的MySQL数据库性能优化研究 :XX 学号:2014XXXXX 学院:计算机学院

摘要: 查询是数据库系统中最基本也是最常用的一种操作,是否具有较快的执行速度,已成为数据库用户和设计者极其关心的问题。在研究开源数据库管理系统MySQL 查询优化技术的基础上,主要结合传统SQL操作优化、深度分析 MySQL 源代码、现代数据库发展几方面进行诸如参数调优,MySQL关联查询,重写相关规则等容展开优化分析研究。 关键词:查询优化,查询重用,查询重写,计划优化

一、传统SQL查询优化操作 1.选取最适用的字段属性 MySQL可以很好的支持大数据量的存取,但是一般说来,数据库中的表越小,在它上面执行的查询也就会越快。因此,在创建表的时候,为了获得更好的性能,我们可以将表中字段的宽度设得尽可能小。例如,在定义邮政编码这个字段时,如果将其设置为CHAR(255),显然给数据库增加了不必要的空间,甚至使用VARCHAR这种类型也是多余的,因为CHAR(6)就可以很好的完成任务了。同样的,如果可以的话,我们应该使用MEDIUMINT而不是BIGIN来定义整型字段。 另外一个提高效率的方法是在可能的情况下,应该尽量把字段设置为NOT NULL,这样在将来执行查询的时候,数据库不用去比较NULL值。 对于某些文本字段,例如“省份”或者“性别”,我们可以将它们定义为ENUM类型。因为在MySQL中,ENUM类型被当作数值型数据来处理,而数值型数据被处理起来的速度要比文本类型快得多。这样,我们又可以提高数据库的性能。 2.使用连接(JOIN)来代替子查询(Sub-Queries) MySQL从4.1开始支持SQL的子查询。这个技术可以使用SELECT语句来创建一个单列的查询结果,然后把这个结果作为过滤条件用在另一个查询中。例如,我们要将客户基本信息表中没有任何订单的客户删除掉,就可以利用子查询先从销售信息表中将所有发出订单的客户ID取出来,然后将结果传递给主查询,如下所示: DELETE FROM customerinfo WHERE CustomerID NOT in (SELECT CustomerID FROM salesinfo ) 使用子查询可以一次性的完成很多逻辑上需要多个步骤才能完成的SQL操作,同时也可以避免事务或者表锁死,并且写起来也很容易。但是,有些情况下,

相关主题