??xml version="1.0" encoding="utf-8" standalone="yes"?>欧美伊人久久大香线蕉综合 ,国产农村妇女毛片精品久久,国产农村妇女毛片精品久久http://www.shnenglu.com/beautykingdom/category/12296.htmlzh-cnMon, 05 Sep 2011 09:36:52 GMTMon, 05 Sep 2011 09:36:52 GMT60MySQL索引背后的数据结构及法原理http://www.shnenglu.com/beautykingdom/archive/2011/09/05/155112.htmlchatlerchatlerMon, 05 Sep 2011 02:36:00 GMThttp://www.shnenglu.com/beautykingdom/archive/2011/09/05/155112.htmlhttp://www.shnenglu.com/beautykingdom/comments/155112.htmlhttp://www.shnenglu.com/beautykingdom/archive/2011/09/05/155112.html#Feedback0http://www.shnenglu.com/beautykingdom/comments/commentRss/155112.htmlhttp://www.shnenglu.com/beautykingdom/services/trackbacks/155112.html阅读全文

chatler 2011-09-05 10:36 发表评论
]]>
What are the difference between DDL, DML and DCL commands?<转蝲>http://www.shnenglu.com/beautykingdom/archive/2011/08/19/153837.htmlchatlerchatlerFri, 19 Aug 2011 02:26:00 GMThttp://www.shnenglu.com/beautykingdom/archive/2011/08/19/153837.htmlhttp://www.shnenglu.com/beautykingdom/comments/153837.htmlhttp://www.shnenglu.com/beautykingdom/archive/2011/08/19/153837.html#Feedback0http://www.shnenglu.com/beautykingdom/comments/commentRss/153837.htmlhttp://www.shnenglu.com/beautykingdom/services/trackbacks/153837.htmlfrom:
http://www.orafaq.com/faq/what_are_the_difference_between_ddl_dml_and_dcl_commands

DDL


Data Definition Language (DDL) statements are used to define the database structure or schema. Some examples:

  • CREATE - to create objects in the database
  • ALTER - alters the structure of the database
  • DROP - delete objects from the database
  • TRUNCATE - remove all records from a table, including all spaces allocated for the records are removed
  • COMMENT - add comments to the data dictionary
  • RENAME - rename an object

DML


Data Manipulation Language (DML) statements are used for managing data within schema objects. Some examples:

  • SELECT - retrieve data from the a database
  • INSERT - insert data into a table
  • UPDATE - updates existing data within a table
  • DELETE - deletes all records from a table, the space for the records remain
  • MERGE - UPSERT operation (insert or update)
  • CALL - call a PL/SQL or Java subprogram
  • EXPLAIN PLAN - explain access path to data
  • LOCK TABLE - control concurrency

DCL


Data Control Language (DCL) statements. Some examples:

  • GRANT - gives user's access privileges to database
  • REVOKE - withdraw access privileges given with the GRANT command

TCL


Transaction Control (TCL) statements are used to manage the changes made by DML statements. It allows statements to be grouped together into logical transactions.

  • COMMIT - save work done
  • SAVEPOINT - identify a point in a transaction to which you can later roll back
  • ROLLBACK - restore database to original since the last COMMIT
  • SET TRANSACTION - Change transaction options like isolation level and what rollback segment to use


chatler 2011-08-19 10:26 发表评论
]]>
查询优化http://www.shnenglu.com/beautykingdom/archive/2009/11/24/101826.htmlchatlerchatlerTue, 24 Nov 2009 09:04:00 GMThttp://www.shnenglu.com/beautykingdom/archive/2009/11/24/101826.htmlhttp://www.shnenglu.com/beautykingdom/comments/101826.htmlhttp://www.shnenglu.com/beautykingdom/archive/2009/11/24/101826.html#Feedback0http://www.shnenglu.com/beautykingdom/comments/commentRss/101826.htmlhttp://www.shnenglu.com/beautykingdom/services/trackbacks/101826.html

数据?/strong>pȝ?a style="LINE-HEIGHT: normal !important; COLOR: rgb(51,51,51); WORD-BREAK: break-all; TEXT-DECORATION: underline" onclick="javascript:tagshow(event, '%B9%DC%C0%ED');" href="javascript:;" target=_self>信息pȝ的核心,Z数据库的联机事务处理QOLTPQ以及联机分析处?OLAP)是银行、企业、政府等部门最为重要的计算机应 用之一。从大多数系l的应用实例来看Q查询操作在各种数据库操作中所占据的比重最大,而查询操作所Z的SELECT语句?a style="LINE-HEIGHT: normal !important; COLOR: rgb(51,51,51); WORD-BREAK: break-all; TEXT-DECORATION: underline" onclick="javascript:tagshow(event, 'SQL');" href="javascript:;" target=_self>SQL语句中又是代h大的?句。D例来_如果数据的量U篏C定的E度Q比如一个银行的账户数据库表信息U篏C百万甚至上千万条记录Q全表扫描一ơ往往需要数十分钟,甚至数小 时。如果采用比全表扫描更好的查询策略,往往可以使查询时间降为几分钟Q由此可见查询优化技术的重要性?/p>

W者在应用目的实施中发现Q许多程序员在利用一些前端数据库开发工?/strong>Q如PowerBuilder、Delphi{)开发数据库应用E序Ӟ只注 重用L面的华丽Qƈ不重视查询语句的效率问题Q导致所开发出来的应用pȝ效率低下Q资源浪费严重。因此,如何设计高效合理的查询语句就昑־非常重要。本 文以应用实例为基Q结合数据库理论Q介l查询优化技术在现实pȝ中的q用?/p>

分析问题

许多E序员认为查询优化是DBMSQ数据库理pȝQ的dQ与E序员所~写的SQL语句关系不大Q这是错误的。一个好的查询计划往往可以使程序?能提高数十倍。查询计划是用户所提交的SQL语句的集合,查询规划是经q优化处理之后所产生的语句集合。DBMS处理查询计划的过E是q样的:在做完查?语句的词法、语法检查之后,语句提交给DBMS的查询优化器Q优化器做完代数优化和存取\径的优化之后Q由预编译模块对语句q行处理q生成查询规划,?后在合适的旉提交l系l处理执行,最后将执行l果q回l用戗在实际的数据库产品(如Oracle、Sybase{?的高版本中都是采用基于代L优化 ҎQ这U优化能Ҏ从系l字典表所得到的信息来估计不同的查询规划的代hQ然后选择一个较优的规划。虽然现在的数据库品在查询优化斚w已经做得来?好,但由用户提交的SQL语句是系l优化的基础Q很难设想一个原本糟p的查询计划l过pȝ的优化之后会变得高效Q因此用h写语句的优劣臛_重要。系l所 做查询优化我们暂不讨论,下面重点说明改善用户查询计划的解?a style="LINE-HEIGHT: normal !important; COLOR: rgb(51,51,51); WORD-BREAK: break-all; TEXT-DECORATION: underline" onclick="javascript:tagshow(event, '%B7%BD%B0%B8');" href="javascript:;" target=_self>Ҏ?br style="LINE-HEIGHT: normal !important; WORD-BREAK: break-all">解决问题

下面以关pL据库pȝInformixZQ介l改善用h询计划的Ҏ?/p>

1Q合理用烦?/strong>

索引是数据库中重要的数据l构Q它的根本目的就是ؓ了提高查询效率。现在大多数的数据库产品都采用IBM最先提出的ISAM索引l构。烦引的使用要恰到好处,其用原则如下:

●在l常q行q接Q但是没有指定ؓ外键的列上徏立烦引,而不l常q接的字D则׃化器自动生成索引?br style="LINE-HEIGHT: normal !important; WORD-BREAK: break-all">●在频繁q行排序或分l(卌行group by或order by操作Q的列上建立索引?br style="LINE-HEIGHT: normal !important; WORD-BREAK: break-all">●在条g表达式中l常用到的不同D多的列上建立索,在不同值少的列上不要徏立烦引。比如在雇员表的“性别”列上只有“?#8221;?#8220;?#8221;两个不同|因此无必要建立索引。如果徏立烦引不但不会提高查询效率,反而会严重降低更新速度?br style="LINE-HEIGHT: normal !important; WORD-BREAK: break-all">●如果待排序的列有多个,可以在这些列上徏立复合烦引(compound indexQ?br style="LINE-HEIGHT: normal !important; WORD-BREAK: break-all">?使用pȝ工具。如Informix数据库有一个tbcheck工具Q可以在可疑的烦引上q行查。在一些数据库服务器上Q烦引可能失效或者因为频J操作?使得d效率降低Q如果一个用烦引的查询不明不白地慢下来Q可以试着用tbcheck工具查烦引的完整性,必要时进行修复。另外,当数据库表更新大?数据后,删除q建烦引可以提高查询速度?/p>

2Q避免或化排?/strong>

应当化或避免对大型表q行重复的排序。当能够利用索引自动以适当的次序生输出时Q优化器避免了排序的步骤。以下是一些媄响因素:
●烦引中不包括一个或几个待排序的列;
●group by或order by子句中列的次序与索引的次序不一P
●排序的列来自不同的表?br style="LINE-HEIGHT: normal !important; WORD-BREAK: break-all">Z避免不必要的排序Q就要正地增徏索引Q合理地合ƈ数据库表Q尽有时可能媄响表的规范化Q但相对于效率的提高是值得的)。如果排序不可避免,那么应当试图化它Q如~小排序的列的范围等?/p>

3Q消除对大型表行数据的顺序存?/strong>

在嵌套查询中Q对表的序存取Ҏ询效率可能生致命的影响。比如采用顺序存取策略,一个嵌?层的查询Q如果每层都查询1000行,那么q个查询 p查询10亿行数据。避免这U情늚主要Ҏ是对连接的列进行烦引。例如,两个表:学生表(学号、姓名、年?#8230;…Q和选课表(学号、课E号、成l)?如果两个表要做连接,p?#8220;学号”q个q接字段上徏立烦引?/p>

q可以用ƈ集来避免序存取。尽在所有的查列上都有烦引,但某些Ş式的where子句优化器用顺序存取。下面的查询强q对orders表执行顺序操作:

SELECT Q?FROM orders WHERE (customer_num=104 AND order_num>1001) OR order_num=1008

虽然在customer_num和order_num上徏有烦引,但是在上面的语句中优化器q是使用序存取路径扫描整个表。因个语句要索的是分ȝ行的集合Q所以应该改为如下语句:
SELECT Q?FROM orders WHERE customer_num=104 AND order_num>1001
UNION
SELECT Q?FROM orders WHERE order_num=1008
q样p利用索引路径处理查询?/p>

4Q避免相兛_查询

一个列的标{֐时在L询和where子句中的查询中出玎ͼ那么很可能当L询中的列值改变之后,子查询必重新查询一ơ。查询嵌套层ơ越多,效率低Q因此应当尽量避免子查询。如果子查询不可避免Q那么要在子查询中过滤掉可能多的行?/p>

5Q避免困隄正规表达?/strong>

MATCHES和LIKE关键字支持通配W匹配,技术上叫正规表辑ּ。但q种匚w特别耗费旉。例如:SELECT Q?FROM customer WHERE zipcode LIKE “98_ _ _”
即在zipcode字段上徏立了索引Q在q种情况下也q是采用序扫描的方式。如果把语句改ؓSELECT Q?FROM customer WHERE zipcode >“98000”Q在执行查询时就会利用烦引来查询Q显然会大大提高速度?br style="LINE-HEIGHT: normal !important; WORD-BREAK: break-all">另外Q还要避免非开始的子串。例如语句:SELECT Q?FROM customer WHERE zipcode[2Q?] >“80”Q在where子句中采用了非开始子Ԍ因而这个语句也不会使用索引?/p>

6Q用时表加速查?/strong>

把表的一个子集进行排序ƈ创徏临时表,有时能加速查询。它有助于避免多重排序操作,而且在其他方面还能简化优化器的工作。例如:
SELECT cust.nameQrcvbles.balanceQ?#8230;…other columns
FROM custQrcvbles
WHERE cust.customer_id = rcvlbes.customer_id
AND rcvblls.balance>0
AND cust.postcode>“98000”
ORDER BY cust.name

如果q个查询要被执行多次而不止一ơ,可以把所有未付款的客h出来攑֜一个时文件中Qƈ按客L名字q行排序Q?br style="LINE-HEIGHT: normal !important; WORD-BREAK: break-all">SELECT cust.nameQrcvbles.balanceQ?#8230;…other columns
FROM custQrcvbles
WHERE cust.customer_id = rcvlbes.customer_id
AND rcvblls.balance>0
ORDER BY cust.name
INTO TEMP cust_with_balance
然后以下面的方式在时表中查询:
SELECT Q?FROM cust_with_balance
WHERE postcode>“98000”

临时表中的行要比主表中的行少Q而且物理序是所要求的顺序,减少了磁盘I/OQ所以查询工作量可以得到大幅减少?注意Q时表创徏后不会反映主表的修改。在主表中数据频J修改的情况下,注意不要丢失数据?/p>

7Q用排序来取代非序存取
非顺序磁盘存取是最慢的操作Q表现在盘存取臂的来回Ud。SQL语句隐藏了这一情况Q得我们在写应用程序时很容易写求存取大量非序늚查询?br style="LINE-HEIGHT: normal !important; WORD-BREAK: break-all">有些时候,用数据库的排序能力来替代非顺序的存取能改q查询?/p> 转自Q?br>http://space.itpub.net/47598/viewspace-223897

chatler 2009-11-24 17:04 发表评论
]]>
优化MySQL数据库性能的八大“妙手?/title><link>http://www.shnenglu.com/beautykingdom/archive/2009/11/24/101825.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Tue, 24 Nov 2009 09:01:00 GMT</pubDate><guid>http://www.shnenglu.com/beautykingdom/archive/2009/11/24/101825.html</guid><wfw:comment>http://www.shnenglu.com/beautykingdom/comments/101825.html</wfw:comment><comments>http://www.shnenglu.com/beautykingdom/archive/2009/11/24/101825.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/beautykingdom/comments/commentRss/101825.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/beautykingdom/services/trackbacks/101825.html</trackback:ping><description><![CDATA[<span style="WIDOWS: 2; TEXT-TRANSFORM: none; TEXT-INDENT: 0px; BORDER-COLLAPSE: separate; FONT: medium Simsun; WHITE-SPACE: normal; ORPHANS: 2; LETTER-SPACING: normal; COLOR: rgb(0,0,0); WORD-SPACING: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" class=Apple-style-span><span style="TEXT-ALIGN: left; LINE-HEIGHT: 21px; FONT-FAMILY: Arial, Helvetica, sans-serif; COLOR: rgb(51,51,51); FONT-SIZE: 12px" class=Apple-style-span>本文探讨了提高MySQL<span id="gayak6m" class=Apple-converted-space> </span><a style="LINE-HEIGHT: normal; COLOR: rgb(51,51,51); WORD-BREAK: break-all; TEXT-DECORATION: underline" onclick="javascript:tagshow(event, '%CA%FD%BE%DD%BF%E2');" href="javascript:;" target=_self><u style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><strong style="LINE-HEIGHT: normal; WORD-BREAK: break-all">数据?/strong></u></a>性能的思\Qƈ?个方面给Z具体的解x法?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  <strong style="LINE-HEIGHT: normal; WORD-BREAK: break-all">1、选取最适用的字D属?/strong><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  MySQL可以很好的支持大数据量的存取Q但是一般说来,数据库中的表小Q在它上面执行的查询也就会越快。因此,在创的时候,Z获得更好的?能,我们可以表中字D늚宽度讑־可能小。例如,在定义邮政编码这个字D|Q如果将其设|ؓCHAR(255),昄l数据库增加了不必要的空_甚至 使用VARCHARq种cd也是多余的,因ؓCHAR(6)可以很好的完成d了。同LQ如果可以的话,我们应该使用MEDIUMINT而不?BIGIN来定义整型字Dc?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  另外一个提高效率的Ҏ是在可能的情况下Q应该尽量把字段讄为NOT NULLQ这样在来执行查询的时候,数据库不用去比较NULL倹{?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  对于某些文本字段Q例?#8220;省䆾”或?#8220;性别”Q我们可以将它们定义为ENUMcd。因为在MySQL中,ENUMcd被当作数值型数据来处理,而数值型数据被处理v来的速度要比文本cd快得多。这P我们又可以提高数据库的性能?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  <strong style="LINE-HEIGHT: normal; WORD-BREAK: break-all">2、用连接(JOINQ来代替子查?Sub-Queries)</strong><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  MySQL?.1开始支?a style="LINE-HEIGHT: normal; COLOR: rgb(51,51,51); WORD-BREAK: break-all; TEXT-DECORATION: underline" onclick="javascript:tagshow(event, 'SQL');" href="javascript:;" target=_self><u style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><strong style="LINE-HEIGHT: normal; WORD-BREAK: break-all">SQL</strong></u></a>的子查询。这个技术可以用SELECT语句来创Z个单列的查询l果Q然后把q个l果作ؓqo条g用在另一个查?中。例如,我们要将客户基本信息表中没有M订单的客户删除掉Q就可以利用子查询先从销售信息表中将所有发单的客户ID取出来,然后结果传递给L 询,如下所C:<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <table style="LINE-HEIGHT: normal; WORD-BREAK: break-all" border=1 borderColor=#cccccc width="90%" bgColor=#e3e3e3 align=center> <tbody style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <tr style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <td style="LINE-HEIGHT: normal; WORD-BREAK: break-all">DELETE FROM customerinfo<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">WHERE CustomerID NOT in (SELECT CustomerID FROM salesinfo )</td> </tr> </tbody> </table> <br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  使用子查询可以一ơ性的完成很多逻辑上需要多个步骤才能完成的SQL操作Q同时也可以避免事务或者表锁死Qƈ且写h也很Ҏ。但是,有些情况下,?查询可以被更有效率的q接QJOINQ?. 替代。例如,假设我们要将所有没有订单记录的用户取出来,可以用下面这个查询完成:<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <table style="LINE-HEIGHT: normal; WORD-BREAK: break-all" border=1 borderColor=#cccccc width="90%" bgColor=#e3e3e3 align=center> <tbody style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <tr style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <td style="LINE-HEIGHT: normal; WORD-BREAK: break-all">SELECT * FROM customerinfo<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">WHERE CustomerID NOT in (SELECT CustomerID FROM salesinfo )</td> </tr> </tbody> </table> <br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  如果使用q接QJOINQ?. 来完成这个查询工作,速度会快很多。尤其是当salesinfo表中对CustomerID建有索引的话Q性能会更好Q查询如下:<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <table style="LINE-HEIGHT: normal; WORD-BREAK: break-all" border=1 borderColor=#cccccc width="90%" bgColor=#e3e3e3 align=center> <tbody style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <tr style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <td style="LINE-HEIGHT: normal; WORD-BREAK: break-all">SELECT * FROM customerinfo<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">LEFT JOIN salesinfoON customerinfo.CustomerID=salesinfo.<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">CustomerID<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">WHERE salesinfo.CustomerID IS NULL</td> </tr> </tbody> </table> <br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  q接QJOINQ?. 之所以更有效率一些,是因?MySQL不需要在内存中创Z时表来完成这个逻辑上的需要两个步骤的查询工作?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  <strong style="LINE-HEIGHT: normal; WORD-BREAK: break-all">3、用联?UNION)来代替手动创建的临时?/strong><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  MySQL ?4.0 的版本开始支?UNION 查询Q它可以把需要用时表的两条或更多?SELECT 查询合ƈ的一个查询中。在客户端的查询会话l束的时候,临时表会被自动删除,从而保证数据库整齐、高效。?UNION 来创建查询的时候,我们只需要用 UNION作ؓ关键字把多个 SELECT 语句q接h可以了Q要注意的是所?SELECT 语句中的字段数目要想同。下面的例子演CZ一个?UNION的查询?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <table style="LINE-HEIGHT: normal; WORD-BREAK: break-all" border=1 borderColor=#cccccc width="90%" bgColor=#e3e3e3 align=center> <tbody style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <tr style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <td style="LINE-HEIGHT: normal; WORD-BREAK: break-all">SELECT Name, Phone FROM client<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">UNION<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">SELECT Name, BirthDate FROM author<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">UNION<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">SELECT Name, Supplier FROM product</td> </tr> </tbody> </table> <br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  <strong style="LINE-HEIGHT: normal; WORD-BREAK: break-all">4、事?/strong><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  管我们可以使用子查询(Sub-QueriesQ、连接(JOINQ和联合QUNIONQ来创徏各种各样的查询,但不是所有的数据库操作都可以只用 一条或数几条SQL语句可以完成的。更多的时候是需要用Cpd的语句来完成某种工作。但是在q种情况下,当这个语句块中的某一条语句运行出错的?候,整个语句块的操作׃变得不确定v来。设想一下,要把某个数据同时插入两个相关联的表中Q可能会出现q样的情况:W一个表中成功更新后Q数据库H然?现意外状况,造成W二个表中的操作没有完成Q这P׃造成数据的不完整Q甚至会破坏数据库中的数据。要避免q种情况Q就应该使用事务Q它的作用是Q要?语句块中每条语句都操作成功,要么都失败。换句话_是可以保持数据库中数据的一致性和完整性。事物以BEGIN 关键字开始,COMMIT关键字结束。在q之间的一条SQL操作p|Q那么,ROLLBACK命o可以把数据库恢复到BEGIN开始之前的状态?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <table style="LINE-HEIGHT: normal; WORD-BREAK: break-all" border=1 borderColor=#cccccc width="90%" bgColor=#e3e3e3 align=center> <tbody style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <tr style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <td style="LINE-HEIGHT: normal; WORD-BREAK: break-all">BEGIN;<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">INSERT INTO salesinfo SET CustomerID=14;<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">UPDATE inventory SET Quantity=11<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">WHERE item='book';<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">COMMIT;</td> </tr> </tbody> </table> <p style="LINE-HEIGHT: 1.8em !important; MARGIN: 10px 0px; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal !important; WORD-BREAK: break-all">  事务的另一个重要作用是当多个用户同时用相同的数据源时Q它可以利用锁定数据库的Ҏ来ؓ用户提供一U?a style="LINE-HEIGHT: normal !important; COLOR: rgb(51,51,51); WORD-BREAK: break-all; TEXT-DECORATION: underline" onclick="javascript:tagshow(event, '%B0%B2%C8%AB');" href="javascript:;" target=_self><u style="LINE-HEIGHT: normal !important; WORD-BREAK: break-all"><strong style="LINE-HEIGHT: normal !important; WORD-BREAK: break-all">安全</strong></u></a>的访问方式,q样可以保证用户的操作不被其它的用户所q扰?/p> <p style="LINE-HEIGHT: 1.8em !important; MARGIN: 10px 0px; WORD-BREAK: break-all"> <strong style="LINE-HEIGHT: normal !important; WORD-BREAK: break-all">5、锁定表</strong><br style="LINE-HEIGHT: normal !important; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal !important; WORD-BREAK: break-all">  管事务是维护数据库完整性的一个非常好的方法,但却因ؓ它的独占性,有时会媄响数据库的性能Q尤其是在很大的应用pȝ中。由于在事务执行的过E中Q数据库会被锁定,因此其它的用戯求只能暂时等待直到该事务l束。如果一个数据库pȝ只有数几个用户<br style="LINE-HEIGHT: normal !important; WORD-BREAK: break-all">来用,事务造成的媄响不会成Z个太大的问题Q但假设有成千上万的用户同时讉K一个数据库pȝQ例如访问一个电子商务网站,׃产生比较严重的响应gq?br style="LINE-HEIGHT: normal !important; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal !important; WORD-BREAK: break-all">  其实Q有些情况下我们可以通过锁定表的Ҏ来获得更好的性能。下面的例子q锁定表的Ҏ来完成前面一个例子中事务的功能?br style="LINE-HEIGHT: normal !important; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal !important; WORD-BREAK: break-all"></p> <table style="LINE-HEIGHT: normal; WORD-BREAK: break-all" border=1 borderColor=#cccccc width="90%" bgColor=#e3e3e3 align=center> <tbody style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <tr style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <td style="LINE-HEIGHT: normal; WORD-BREAK: break-all">LOCK TABLE inventory WRITE<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">SELECT Quantity FROM inventory<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">WHEREItem='book';<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">...<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">UPDATE inventory SET Quantity=11<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">WHEREItem='book';<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">UNLOCK TABLES</td> </tr> </tbody> </table> <br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  q里Q我们用一?SELECT 语句取出初始数据Q通过一些计,?UPDATE 语句新值更新到表中。包含有 WRITE 关键字的 LOCK TABLE 语句可以保证?UNLOCK TABLES 命o被执行之前,不会有其它的讉K来对 inventory q行插入、更新或者删除的操作?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  6、用外?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  锁定表的Ҏ可以l护数据的完整性,但是它却不能保证数据的关联性。这个时候我们就可以使用外键。例如,外键可以保证每一条销售记录都指向某一个存?的客戗在q里Q外键可以把customerinfo 表中的CustomerID映射到salesinfo表中CustomerIDQQ何一条没有合法CustomerID的记录都不会被更新或插入?salesinfo中?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <table style="LINE-HEIGHT: normal; WORD-BREAK: break-all" border=1 borderColor=#cccccc width="90%" bgColor=#e3e3e3 align=center> <tbody style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <tr style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <td style="LINE-HEIGHT: normal; WORD-BREAK: break-all">CREATE TABLE customerinfo<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">(<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">CustomerID INT NOT NULL ,<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">PRIMARY KEY ( CustomerID )<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">) TYPE = INNODB;<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">CREATE TABLE salesinfo<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">(<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">SalesID INT NOT NULL,<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">CustomerID INT NOT NULL,<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">PRIMARY KEY(CustomerID, SalesID),<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">FOREIGN KEY (CustomerID) REFERENCES customerinfo<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">(CustomerID) ON DELETECASCADE<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">) TYPE = INNODB;</td> </tr> </tbody> </table> <br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  注意例子中的参数“ON DELETE CASCADE”。该参数保证?customerinfo 表中的一条客戯录被删除的时候,salesinfo 表中所有与该客L关的记录也会被自动删除。如果要?MySQL 中用外键,一定要C在创的时候将表的cd定义Z务安全表 InnoDBcd。该cd不是 MySQL 表的默认cd。定义的Ҏ是在 CREATE TABLE 语句中加?TYPE=INNODB。如例中所C?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  <strong style="LINE-HEIGHT: normal; WORD-BREAK: break-all">7、用烦?/strong><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  索引是提高数据库性能的常用方法,它可以o数据库服务器以比没有索引快得多的速度索特定的行,其是在查询语句当中包含有MAX(), MIN()和ORDERBYq些命o的时候,性能提高更ؓ明显。那该对哪些字段建立索引呢?一般说来,索引应徏立在那些用于JOIN, WHERE判断和ORDER BY排序的字D上。尽量不要对数据库中某个含有大量重复的值的字段建立索引。对于一个ENUMcd的字D|_出现大量重复值是很有可能的情况,例如 customerinfo中的“province”.. 字段Q在q样的字D上建立索引不会有什么帮助;相反Q还有可能降低数据库的性能。我们在创徏表的时候可以同时创建合适的索引Q也可以使用ALTER TABLE或CREATE INDEX在以后创建烦引。此外,MySQL<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">从版?.23.23开始支持全文烦引和搜烦。全文烦引在MySQL 中是一个FULLTEXTcd索引Q但仅能用于MyISAM cd的表。对于一个大的数据库Q将数据装蝲C个没有FULLTEXT索引的表中,然后再用ALTER TABLE或CREATE INDEX创徏索引Q将是非常快的。但如果数据装载到一个已l有FULLTEXT索引的表中,执行q程会非常慢?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  <strong style="LINE-HEIGHT: normal; WORD-BREAK: break-all">8、优化的查询语句</strong><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  l大多数情况下,使用索引可以提高查询的速度Q但如果SQL语句使用不恰当的话,索引无法发挥它应有的作用。下面是应该注意的几个方面。首先,最?是在相同cd的字D间q行比较的操作。在MySQL 3.23版之前,q甚x一个必ȝ条g。例如不能将一个徏有烦引的INT字段和BIGINT字段q行比较Q但是作为特D的情况Q在CHARcd的字D和 VARCHARcd字段的字D大相同的时候,可以它们进行比较。其ơ,在徏有烦引的字段上尽量不要用函数进行操作?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  例如Q在一个DATEcd的字D上使用YEAE()函数Ӟ会使烦引不能发挥应有的作用。所以,下面的两个查询虽然返回的l果一P但后者要比前者快得多?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <table style="LINE-HEIGHT: normal; WORD-BREAK: break-all" border=1 borderColor=#cccccc width="90%" bgColor=#e3e3e3 align=center> <tbody style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <tr style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <td style="LINE-HEIGHT: normal; WORD-BREAK: break-all">SELECT * FROM order WHERE YEAR(OrderDate)<2001;<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">SELECT * FROM order WHERE OrderDate<"2001-01-01";</td> </tr> </tbody> </table> <br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  同样的情形也会发生在Ҏ值型字段q行计算的时候:<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <table style="LINE-HEIGHT: normal; WORD-BREAK: break-all" border=1 borderColor=#cccccc width="90%" bgColor=#e3e3e3 align=center> <tbody style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <tr style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <td style="LINE-HEIGHT: normal; WORD-BREAK: break-all">SELECT * FROM inventory WHERE Amount/7<24;<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">SELECT * FROM inventory WHERE Amount<24*7;</td> </tr> </tbody> </table> <br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  上面的两个查询也是返回相同的l果Q但后面的查询将比前面的一个快很多。第三,在搜索字W型字段Ӟ我们有时会?LIKE 关键字和通配W,q种做法虽然单,但却也是以牺牲系l性能ZL。例如下面的查询会比较表中的每一条记录?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <table style="LINE-HEIGHT: normal; WORD-BREAK: break-all" border=1 borderColor=#cccccc width="90%" bgColor=#e3e3e3 align=center> <tbody style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <tr style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <td style="LINE-HEIGHT: normal; WORD-BREAK: break-all">SELECT * FROM books<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">WHERE name like "MySQL%"</td> </tr> </tbody> </table> <br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  但是如果换用下面的查询,q回的结果一P但速度p快上很多Q?.<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <table style="LINE-HEIGHT: normal; WORD-BREAK: break-all" border=1 borderColor=#cccccc width="90%" bgColor=#e3e3e3 align=center> <tbody style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <tr style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <td style="LINE-HEIGHT: normal; WORD-BREAK: break-all">SELECT * FROM books<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">WHERE name>="MySQL"and name<"MySQM"</td> </tr> </tbody> </table> <br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  最后,应该注意避免在查询中让MySQLq行自动cd转换Q因{换过E也会索引变得不v作用?br>选自Q?br><a ><u><font color=#0000ff>http://space.itpub.net/47598/viewspace-329728</font></u></a></span></span> <img src ="http://www.shnenglu.com/beautykingdom/aggbug/101825.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/beautykingdom/" target="_blank">chatler</a> 2009-11-24 17:01 <a href="http://www.shnenglu.com/beautykingdom/archive/2009/11/24/101825.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MySQL索引分析和优化解x?/title><link>http://www.shnenglu.com/beautykingdom/archive/2009/11/24/101823.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Tue, 24 Nov 2009 09:00:00 GMT</pubDate><guid>http://www.shnenglu.com/beautykingdom/archive/2009/11/24/101823.html</guid><wfw:comment>http://www.shnenglu.com/beautykingdom/comments/101823.html</wfw:comment><comments>http://www.shnenglu.com/beautykingdom/archive/2009/11/24/101823.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/beautykingdom/comments/commentRss/101823.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/beautykingdom/services/trackbacks/101823.html</trackback:ping><description><![CDATA[<span style="WIDOWS: 2; TEXT-TRANSFORM: none; TEXT-INDENT: 0px; BORDER-COLLAPSE: separate; FONT: medium Simsun; WHITE-SPACE: normal; ORPHANS: 2; LETTER-SPACING: normal; COLOR: rgb(0,0,0); WORD-SPACING: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" class=Apple-style-span><span style="TEXT-ALIGN: left; LINE-HEIGHT: 21px; FONT-FAMILY: Arial, Helvetica, sans-serif; COLOR: rgb(51,51,51); FONT-SIZE: 12px" class=Apple-style-span><strong style="LINE-HEIGHT: normal; WORD-BREAK: break-all">一、什么是索引Q?/strong><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  索引用来快速地L那些h特定值的记录Q所有MySQL索引都以B-树的形式保存。如果没有烦引,执行查询时MySQL必须从第一个记录开始扫描整 个表的所有记录,直至扑ֈW合要求的记录。表里面的记录数量越多,q个操作的代价就高。如果作为搜索条件的列上已经创徏了烦引,MySQL无需扫描M 记录卛_q速得到目标记录所在的位置。如果表?000个记录,通过索引查找记录臛_要比序扫描记录?00倍?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  假设我们创徏了一个名为people的表Q?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <table style="LINE-HEIGHT: normal; WORD-BREAK: break-all" border=1 cellSpacing=0 borderColor=#111111 cellPadding=2 bgColor=#e9e9e9 align=center> <tbody style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <tr style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <td style="LINE-HEIGHT: normal; WORD-BREAK: break-all">CREATE TABLE people ( peopleid SMALLINT NOT NULL, name CHAR(50) NOT NULL );</td> </tr> </tbody> </table> <br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  然后Q我们完全随机把1000个不同name值插入到people表。下图显CZpeople表所在数据文件的一部分:<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <center style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><img style="LINE-HEIGHT: normal; MAX-WIDTH: 400px; WORD-BREAK: break-all; CURSOR: pointer" title=点击囄可在新窗口打开 border=0 hspace=3 alt=点击查看原图 vspace=3 src="http://www.phpe.net/uploads/images/article_1043248393.gif" width=232 height=115 twffan="done"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"></center><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  可以看到Q在数据文g中name列没有Q何明的ơ序。如果我们创Zname列的索引QMySQL在索引中排序name列:<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <center style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><img style="LINE-HEIGHT: normal; MAX-WIDTH: 400px; WORD-BREAK: break-all; CURSOR: pointer" title=点击囄可在新窗口打开 border=0 hspace=3 alt=点击查看原图 vspace=3 src="http://www.phpe.net/uploads/images/article_1043248412.gif" width=162 height=119 twffan="done"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"></center><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  对于索引中的每一,MySQL在内部ؓ它保存一个数据文件中实际记录所在位|的“指针”。因此,如果我们要查找name{于“Mike”记录?peopleidQ?a style="LINE-HEIGHT: normal; COLOR: rgb(51,51,51); WORD-BREAK: break-all; TEXT-DECORATION: underline" onclick="javascript:tagshow(event, 'SQL');" href="javascript:;" target=_self><u style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><strong style="LINE-HEIGHT: normal; WORD-BREAK: break-all">SQL</strong></u></a>命o?#8220;SELECT peopleid FROM people WHERE name=\'Mike\';”Q,MySQL能够在name的烦引中查找“Mike”|然后直接转到数据文g中相应的行,准确地返回该行的 peopleidQ?99Q。在q个q程中,MySQL只需处理一个行可以返回结果。如果没?#8220;name”列的索引QMySQL要扫描数据文件中的所?记录Q即1000个记录!昄Q需要MySQL处理的记录数量越,则它完成d的速度p快?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><strong style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  二、烦引的cd</strong><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  MySQL提供多种索引cd供选择Q?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <ul style="PADDING-BOTTOM: 0px; LINE-HEIGHT: normal; MARGIN: 0px 0px 0px 3em; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; WORD-BREAK: break-all; PADDING-TOP: 0px"> <li style="LINE-HEIGHT: normal; WORD-BREAK: break-all">普通烦?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">q是最基本的烦引类型,而且它没有唯一性之cȝ限制。普通烦引可以通过以下几种方式创徏Q?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <ul style="PADDING-BOTTOM: 0px; LINE-HEIGHT: normal; MARGIN: 0px 0px 0px 3em; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; WORD-BREAK: break-all; PADDING-TOP: 0px"> <li style="LINE-HEIGHT: normal; WORD-BREAK: break-all" type=circle>创徏索引Q例如CREATE INDEX <索引的名?gt; ON tablename (列的列表);</li> <li style="LINE-HEIGHT: normal; WORD-BREAK: break-all" type=circle>修改表,例如ALTER TABLE tablename ADD INDEX [索引的名字] (列的列表);</li> <li style="LINE-HEIGHT: normal; WORD-BREAK: break-all" type=circle>创徏表的时候指定烦引,例如CREATE TABLE tablename ( [...], INDEX [索引的名字] (列的列表) );</li> </ul> <br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"></li> <li style="LINE-HEIGHT: normal; WORD-BREAK: break-all">唯一性烦?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">q种索引和前面的“普通烦?#8221;基本相同Q但有一个区别:索引列的所有值都只能出现一ơ,卛_d一。唯一性烦引可以用以下几种方式创徏Q?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <ul style="PADDING-BOTTOM: 0px; LINE-HEIGHT: normal; MARGIN: 0px 0px 0px 3em; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; WORD-BREAK: break-all; PADDING-TOP: 0px"> <li style="LINE-HEIGHT: normal; WORD-BREAK: break-all" type=circle>创徏索引Q例如CREATE UNIQUE INDEX <索引的名?gt; ON tablename (列的列表);</li> <li style="LINE-HEIGHT: normal; WORD-BREAK: break-all" type=circle>修改表,例如ALTER TABLE tablename ADD UNIQUE [索引的名字] (列的列表);</li> <li style="LINE-HEIGHT: normal; WORD-BREAK: break-all" type=circle>创徏表的时候指定烦引,例如CREATE TABLE tablename ( [...], UNIQUE [索引的名字] (列的列表) );</li> </ul> <br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"></li> <li style="LINE-HEIGHT: normal; WORD-BREAK: break-all">主键<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">主键是一U唯一性烦引,但它必须指定?#8220;PRIMARY KEY”。如果你曄用过AUTO_INCREMENTcd的列Q你可能已经熟悉主键之类的概念了。主键一般在创徏表的时候指定,例如“CREATE TABLE tablename ( [...], PRIMARY KEY (列的列表) ); ”。但是,我们也可以通过修改表的方式加入主键Q例?#8220;ALTER TABLE tablename ADD PRIMARY KEY (列的列表); ”。每个表只能有一个主键?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"></li> <li style="LINE-HEIGHT: normal; WORD-BREAK: break-all">全文索引<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">MySQL?.23.23版开始支持全文烦引和全文索。在MySQL中,全文索引的烦引类型ؓFULLTEXT。全文烦引可以在VARCHAR或?TEXTcd的列上创建。它可以通过CREATE TABLE命o创徏Q也可以通过ALTER TABLE或CREATE INDEX命o创徏。对于大规模的数据集Q通过ALTER TABLEQ或者CREATE INDEXQ命令创建全文烦引要比把记录插入带有全文索引的空表更快。本文下面的讨论不再涉及全文索引Q要了解更多信息Q请参见<u style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><font style="LINE-HEIGHT: normal; WORD-BREAK: break-all" color=#0000ff>MySQL documentation</font></u>?/li> </ul>   <strong style="LINE-HEIGHT: normal; WORD-BREAK: break-all">三、单列烦引与多列索引</strong><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  索引可以是单列烦引,也可以是多列索引。下面我们通过具体的例子来说明q两U烦引的区别。假设有q样一个people表:<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <table style="LINE-HEIGHT: normal; WORD-BREAK: break-all" border=1 cellSpacing=0 borderColor=#111111 cellPadding=2 bgColor=#e9e9e9> <tbody style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> </tbody> </table> <table style="LINE-HEIGHT: normal; WORD-BREAK: break-all" border=1 cellSpacing=0 borderColor=#111111 cellPadding=5 bgColor=#e9e9e9 align=center> <tbody style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <tr style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <td style="LINE-HEIGHT: normal; WORD-BREAK: break-all">ALTER TABLE people ADD INDEX fname_lname_age (firstname,lastname,age);</td> </tr> </tbody> </table> <br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  ׃索引文g以B-树格式保存,MySQL能够立即转到合适的firstnameQ然后再转到合适的lastnameQ最后{到合适的age。在没有扫描数据文gM一个记录的情况下,MySQL正地扑և了搜索的目标记录Q?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  那么Q如果在firstname、lastname、ageq三个列上分别创建单列烦引,效果是否和创Z个firstname、lastname?age的多列烦引一样呢Q答案是否定的,两者完全不同。当我们执行查询的时候,MySQL只能使用一个烦引。如果你有三个单列的索引QMySQL会试N?择一个限制最严格的烦引。但是,即是限制最严格的单列烦引,它的限制能力也肯定远q低于firstname、lastname、ageq三个列上的多列 索引?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><strong style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  四、最左前~</strong><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  多列索引q有另外一个优点,它通过UCؓ最左前~QLeftmost PrefixingQ的概念体现出来。l考虑前面的例子,现在我们有一个firstname、lastname、age列上的多列烦引,我们U这个烦?为fname_lname_age。当搜烦条g是以下各U列的组合时QMySQL用fname_lname_age索引Q?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <ul style="PADDING-BOTTOM: 0px; LINE-HEIGHT: normal; MARGIN: 0px 0px 0px 3em; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; WORD-BREAK: break-all; PADDING-TOP: 0px"> <li style="LINE-HEIGHT: normal; WORD-BREAK: break-all">firstnameQlastnameQage</li> <li style="LINE-HEIGHT: normal; WORD-BREAK: break-all">firstnameQlastname</li> <li style="LINE-HEIGHT: normal; WORD-BREAK: break-all">firstname</li> </ul>   从另一斚w理解Q它相当于我们创Z(firstnameQlastnameQage)?firstnameQlastname)以及(firstname)q些列组合上的烦引。下面这些查询都能够使用q个fname_lname_age索引Q?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><u style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><font style="LINE-HEIGHT: normal; WORD-BREAK: break-all" color=#0000ff></font></u> <table style="LINE-HEIGHT: normal; WORD-BREAK: break-all" border=1 cellSpacing=0 borderColor=#111111 cellPadding=5 bgColor=#e9e9e9> <tbody style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> </tbody> </table> <table style="LINE-HEIGHT: normal; WORD-BREAK: break-all" border=1 cellSpacing=0 borderColor=#111111 cellPadding=5 bgColor=#e9e9e9 align=center> <tbody style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <tr style="LINE-HEIGHT: normal; WORD-BREAK: break-all" align=middle bgColor=#dbdbdb> <td style="LINE-HEIGHT: normal; WORD-BREAK: break-all">table</td> <td style="LINE-HEIGHT: normal; WORD-BREAK: break-all">type</td> <td style="LINE-HEIGHT: normal; WORD-BREAK: break-all">possible_keys</td> <td style="LINE-HEIGHT: normal; WORD-BREAK: break-all">key</td> <td style="LINE-HEIGHT: normal; WORD-BREAK: break-all">key_len</td> <td style="LINE-HEIGHT: normal; WORD-BREAK: break-all">ref</td> <td style="LINE-HEIGHT: normal; WORD-BREAK: break-all">rows</td> <td style="LINE-HEIGHT: normal; WORD-BREAK: break-all">Extra</td> </tr> <tr style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <td style="LINE-HEIGHT: normal; WORD-BREAK: break-all">people</td> <td style="LINE-HEIGHT: normal; WORD-BREAK: break-all">ref</td> <td style="LINE-HEIGHT: normal; WORD-BREAK: break-all">fname_lname_age</td> <td style="LINE-HEIGHT: normal; WORD-BREAK: break-all">fname_lname_age</td> <td style="LINE-HEIGHT: normal; WORD-BREAK: break-all">102</td> <td style="LINE-HEIGHT: normal; WORD-BREAK: break-all">const,const,const</td> <td style="LINE-HEIGHT: normal; WORD-BREAK: break-all">1</td> <td style="LINE-HEIGHT: normal; WORD-BREAK: break-all">Where used</td> </tr> </tbody> </table> <font style="LINE-HEIGHT: normal; WORD-BREAK: break-all" color=#0000ff><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  下面我们来看看q个EXPLAIN分析l果的含义?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"> <ul style="PADDING-BOTTOM: 0px; LINE-HEIGHT: normal; MARGIN: 0px 0px 0px 3em; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; WORD-BREAK: break-all; PADDING-TOP: 0px"> <li style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><strong style="LINE-HEIGHT: normal; WORD-BREAK: break-all">table</strong>Q这是表的名字?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"></li> <li style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><strong style="LINE-HEIGHT: normal; WORD-BREAK: break-all">type</strong>Q连接操作的cd。下面是MySQL文档关于refq接cd的说明:<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">“对于每一U与另一个表中记录的l合QMySQL从当前的表d所有带有匹配烦引值的记录。如果连接操作只使用键的最左前~Q或者如果键不是 UNIQUE或PRIMARY KEYcdQ换句话_如果q接操作不能Ҏ键值选择出唯一行)Q则MySQL使用refq接cd。如果连接操作所用的键只匚w量的记录,则ref是一 U好的连接类型?#8221;<br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">在本例中Q由于烦引不是UNIQUEcdQref是我们能够得到的最好连接类型?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">如果EXPLAIN昄q接cd?#8220;ALL”Q而且你ƈ不想从表里面选择出大多数记录Q那么MySQL的操作效率将非常低,因ؓ它要扫描整个表。你可以加入更多的烦引来解决q个问题。预知更多信息,请参见MySQL的手册说明?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"></li> <li style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><strong style="LINE-HEIGHT: normal; WORD-BREAK: break-all">possible_keys</strong>Q?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">可能可以利用的烦引的名字。这里的索引名字是创建烦引时指定的烦引昵Uͼ如果索引没有늧Q则默认昄的是索引中第一个列的名字(在本例中Q它?#8220;firstname”Q。默认烦引名字的含义往往不是很明显?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"></li> <li style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><strong style="LINE-HEIGHT: normal; WORD-BREAK: break-all">Key</strong>Q?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">它显CZMySQL实际使用的烦引的名字。如果它为空Q或NULLQ,则MySQL不用烦引?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"></li> <li style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><strong style="LINE-HEIGHT: normal; WORD-BREAK: break-all">key_len</strong>Q?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">索引中被使用部分的长度,以字节计。在本例中,key_len?02Q其中firstname?0字节Qlastname?0字节Qage?字节。如果MySQL只用烦引中的firstname部分Q则key_len是50?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"></li> <li style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><strong style="LINE-HEIGHT: normal; WORD-BREAK: break-all">ref</strong>Q?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">它显C的是列的名字(或单?#8220;const”Q,MySQL根据这些列来选择行。在本例中,MySQLҎ三个帔R选择行?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"></li> <li style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><strong style="LINE-HEIGHT: normal; WORD-BREAK: break-all">rows</strong>Q?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">MySQL所认ؓ的它在找到正的l果之前必须扫描的记录数。显Ӟq里最理想的数字就??br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"></li> <li style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><strong style="LINE-HEIGHT: normal; WORD-BREAK: break-all">Extra</strong>Q?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">q里可能出现许多不同的选项Q其中大多数对查询产生负面影响。在本例中,MySQL只是提醒我们它将用WHERE子句限制搜烦l果集?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"></li> </ul>   <strong style="LINE-HEIGHT: normal; WORD-BREAK: break-all">七、烦引的~点</strong><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  到目前ؓ止,我们讨论的都是烦引的优点。事实上Q烦引也是有~点的?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  首先Q烦引要占用盘I间。通常情况下,q个问题不是很突出。但是,如果你创建每一U可能列l合的烦引,索引文g体积的增镉K度远q超q数据文件。如果你有一个很大的表,索引文g的大可能达到操作系l允许的最大文仉制?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  W二Q对于需要写入数据的操作Q比如DELETE、UPDATE以及INSERT操作Q烦引会降低它们的速度。这是因为MySQL不仅要把改动数据写入数据文gQ而且它还要把q些改动写入索引文g?br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  <strong style="LINE-HEIGHT: normal; WORD-BREAK: break-all">【结束语?/strong><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><br style="LINE-HEIGHT: normal; WORD-BREAK: break-all">  在大?a style="LINE-HEIGHT: normal; COLOR: rgb(51,51,51); WORD-BREAK: break-all; TEXT-DECORATION: underline" onclick="javascript:tagshow(event, '%CA%FD%BE%DD%BF%E2');" href="javascript:;" target=_self><u style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><strong style="LINE-HEIGHT: normal; WORD-BREAK: break-all">数据?/strong></u></a>中,索引是提高速度的一个关键因素。不表的结构是多么单,一?00000行的表扫描操作无论如何不会快。如果你的网站上也有q种大规模的表,那么你确实应该花些时间去分析可以采用哪些索引Qƈ考虑是否可以改写查询以优化应用。要了解更多信息Q请参见<u style="LINE-HEIGHT: normal; WORD-BREAK: break-all"><font style="LINE-HEIGHT: normal; WORD-BREAK: break-all" color=#0000ff>MySQL manual</font></u>。另外注意,本文假定你所使用的MySQL?.23版,部分查询不能?.22版MySQL上执行?br><br>转自Q?br><a ><u><font color=#810081>http://space.itpub.net/47598/viewspace-329730</font></u></a></font></span></span> <img src ="http://www.shnenglu.com/beautykingdom/aggbug/101823.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/beautykingdom/" target="_blank">chatler</a> 2009-11-24 17:00 <a href="http://www.shnenglu.com/beautykingdom/archive/2009/11/24/101823.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>优化Derby数据库技?/title><link>http://www.shnenglu.com/beautykingdom/archive/2009/11/24/101817.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Tue, 24 Nov 2009 08:40:00 GMT</pubDate><guid>http://www.shnenglu.com/beautykingdom/archive/2009/11/24/101817.html</guid><wfw:comment>http://www.shnenglu.com/beautykingdom/comments/101817.html</wfw:comment><comments>http://www.shnenglu.com/beautykingdom/archive/2009/11/24/101817.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/beautykingdom/comments/commentRss/101817.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/beautykingdom/services/trackbacks/101817.html</trackback:ping><description><![CDATA[ <div>Dejan Bosanac是一个Y件开发者,技术顾问和作家。他x不同技术的集成和互操作Q尤其是与Java以及Web开发相关的领域?/div><div><br></div><div>数据库在操作量试数据和大量数据的时候,表现行ؓ上有很大的差异。通常Q在开发过E前期,Z不会x数据库性能的问题,但是随着旉的发展,Z必须采取一些措施来保证数据库在大量数据的情况下正常工作?/div><div><br></div><div>Derbyq个完全Java开发的开源的数据库也不例外,因此你必M证它不会成ؓ你程序的一个瓶颈。尽h们可以在Derby的手册中扑ֈ关于q?个话题全面的资料Q我q是x详尽的关注一下这些问题,Z我的l验提供一些具体的例子。本文将着重于那些由在大的数据表中选择查询数据而生的E序性能 问题?/div><div><br></div><div>首先Q有很多关于调整Derby属性(诸如面大小和缓存大等Q的技巧。修改这些参数可以在一定程度上调整数据库的性能Q但是在通常情况下,更主要的问题来自与你的程序和数据库的设计Q因此,我们必须首先xq些问题Q最后再来考虑Derby的属性?/div><div><br></div><div>在接下来的段落里Q我介l一些能够优化程序中有问题部分的技术。但是,和其他性能优化操作一P我们需要在优化前先量q确认问题所在?/div><div><br></div><div>一个简单的例子</div><div><br></div><div>让我们从一个简单的例子开始:假设我们WebE序中拥有一?#8220;search/list”的页面,要处理一个有接近100Q?00行的表,q且那个?不是很小的(臛_?0栏)。用单的JDBC来写一个例子,q样我们可以专注在数据库和JDBC问题上来。这文章中介绍的所有准则对所有的面向对象?映射工具都适用?/div><div><br></div><div>Z使得用户能够列出一个大的表Q通常使用下面单的查询语句?select * from tbl</div><div><br></div><div><br></div><div>对应的JDBC语句如下QClass.forName("org.apache.derby.jdbc.ClientDriver").newInstance();</div><div>Connection connection = DriverManager.getConnection (</div><div>"jdbc:derby://localhost:1527/testDb;");</div><div>Statement stmt = connection.createStatement();</div><div>ResultSet rs = stmt.executeQuery("select * from tbl");</div><div>ArrayList allResults = new ArrayList();</div><div>while (rs.next()) {</div><div>// Object-Relation mapping code to populate your</div><div>// object from result set row</div><div>DomainObject domainObject = populate(rs);</div><div>allResults.add(modelObject);</div><div>}</div><div>System.out.println("Results Size: " + allResults.size());</div><div><br></div><div><br></div><div>在这儿,我们到了第一个问题。执行这L代码Qƈ产生100Q?00Q或更多Q个domain对象肯定会Djava用完堆栈I间Q生一?“java.lang.OutOfMemoryError”的错误。对于初学者来_我们首先必须扑ֈ一个方法来使得q个E序工作?/div><div><br></div><div>分页Result Sets</div><div><br></div><div>随着E序中数据量的增多,你首先想到的应该做的事就是ؓ特定的记录(通常是视图)提供分页支持。正如你在这个介l性的例子中看到的Q简单地去获取庞大的result sets很容易导?out of memory的错误?/div><div><br></div><div>许多数据库服务器支持特定的SQLl构Q它们可以用于获得一个查询结果的特定的子集。例如,在MySQL中,提供了LIMIT和OFFSET关键字,它们可以用于select查询。因此,如果你执行类g面的查询Qselect * from tbl LIMIT 50 OFFSET 100 </div><div><br></div><div><br></div><div>你的l果集将包含从第100个结果开始的50行,即原先的查询返回了100Q?00行。许多其他的数据库提供商通过不同的结构提供了怼的功能?不幸的是QDerbyq没有提供这L功能Q所以你必须l箋使用原先?#8220;select * from tbl”查询语句Q然后在应用E序中实C个分늚机制。让我们来看下面的例子:Class.forName("org.apache.derby.jdbc.ClientDriver").newInstance();</div><div>Connection connection = DriverManager.getConnection(</div><div>"jdbc:derby://localhost:1527/testDb;");</div><div>Statement stmt = connection.createStatement();</div><div>ResultSet rs = stmt.executeQuery("SELECT * FROM tbl");</div><div>ArrayList allResults = new ArrayList();</div><div>int i = 0;</div><div>while (rs.next()) {</div><div>if (i > 50 && i <= 100) {</div><div>// O-R mapping code populate your row from result set</div><div>DomainObject domainObject = populate(rs);</div><div>allResults.add(modelObject);</div><div>}</div><div>i++;</div><div>}</div><div>System.out.println("Results Size: " + allResults.size());</div><div><br></div><div><br></div><div>通过q些额外的语句,我们提供?#8220;分页”的功能。尽所有的l果都从数据库服务器中取ZQ但是只有那些我们感兴趣的行才真正的映射CJava?对象中。现在我们避免了先前到?#8220;OutOfMemoryError”的问题了Q这样保证了我们的程序可以真正的工作在大的数据表上?/div><div><br></div><div>然而,通过q个解决ҎQ数据库仍然会扫描整个表Q然后返回所有的行,q还是一个非常消耗时间的d。对于我的事例数据库来说Q这个操作的执行要花?0U钟Q这在程序中昄是不可接受的?/div><div><br></div><div>因此Q我们必ȝZ个解x案;我们q不需要返回所有的数据库行Q而只需要那些我们感兴趣的(或者至是所有行的最可能子集)。我们这儿用的 技巧就是显式的告诉JDBC驱动我们需要多行。我们可以用java.sql.Statement接口提供的setMaxRowsQ)函数来完成这个Q 务。看下面的例子:Class.forName("org.apache.derby.jdbc.ClientDriver").newInstance();</div><div>Connection connection = DriverManager.getConnection(</div><div>"jdbc:derby://localhost:1527/testDb;");</div><div>Statement stmt = connection.createStatement();</div><div>stmt.setMaxRows(101);</div><div>ResultSet rs = stmt.executeQuery("SELECT * FROM tbl");</div><div>ArrayList allResults = new ArrayList();</div><div>int i = 0;</div><div>while (rs.next()) {</div><div>if (i > 50 && i <= 100) {</div><div>// O-R mapping code populate your row from result set</div><div>DomainObject domainObject = populate(rs);</div><div>allResults.add(modelObject);</div><div>}</div><div>}</div><div>System.out.println("Results Size: " + allResults.size());</div><div><br></div><div><br></div><div>值得注意的是Q我们把最大行的D|ؓ了我们需要的最后一行(增加?Q。因此,通过q样的解x案,我们不是仅仅取得了我们想要的50行,而是?获取?00行,然后从中{选出我们感兴的50行。不q的是,我们没有办法告诉JDBC驱动从一个具体的行开始,因此我们必须说明要显C的记录的最大行 数。这意味着q回最初的一些记录的操作的性能是很好的Q但是随着用户览的结果的增多Q性能也会下降。好消息是在大多数的情形下Q用户不会浏览的太多 的记录,他们会在前几条记录重获得他们L的行Q或者改变查询策略。在我本人的环境中,上述的例子的执行旉?U降C0.8U?/div><div><br></div><div>q是一个描q如何浏览整个表的简单的例子。但是当查询语句中增加了特定的where条g和排序信息时Q事情又开始变化了。在接下来的部分里,我将解释Z么这U情况会发生Q以后我们如何保证在那些例子中获得可接受的性能?/div><div><div>保使用索引Q避免全表扫描)</div><div><br></div><div>索引在数据库设计中是一个非帔R要的概念。因为本文所涉及的范围有限,我ƈ不会详细的介l烦引理论。简单来_索引是特定的数据库结构,能够允许?表中的行q行快速访问。烦引通常是在一栏或多栏上创建的Q因Z们比整个表小了很多,他们的主要用处就是快速搜索一栏(多栏Q中的倹{?/div><div><br></div><div>Derby自动的ؓ主键和外键的栏以及具有唯一性限制的栏创建烦引。对于其他Q何栏Q我们必L式的创徏索引。在接下来的D落中,我们研I一些例子来介绍索引在什么时候有用以及ؓ什么有用?/div><div><br></div><div>但是首先Q我们必d一些准备。在我们开始优化之前,我们需要能够了解我们执行查询操作的时候数据库中发生了什么。Derby提供?derby.language.logQueryPlanq个参数。如果设|了q个参数QDerby会把所有执行的查询的查询计划(query planQ记录在derby.logq个文g中(q个文g在derby.system.home文g夹中Q。我们可以在启动服务器之前通过合适的 derby.properties文g或者执行如下的java语句来设|该参数?System.setProperty("derby.language.logQueryPlan", "true");</div><div><br></div><div><br></div><div>通过查查询计划,我们可以观察Derby在查询中是用了索引q是q行了全表查询,全表查询是一个很耗时间的操作?/div><div><br></div><div>既然我们已经讄好了环境Q我们可以开始我们的例子了。假设我们先前用的?tb1中有一个没有烦引的栏叫做owner。因为对查询l果的排序通常是查询性能低下的主要原因,我将介绍所有与排序有关的优化。现在,如果我们希望修改 先前的例子来Ҏq一栏的值来排序我们的结果,我们需要把我们的查询语句改成如下的样子Q?SELECT * FROM tbl ORDER BY owner</div><div><br></div><div><br></div><div>如果我们用这个查询语句代替先前的语句Q执行的旉是先前的好多倍。尽我们分(paginatedQ了所有的l果Qƈ心的设|了要获取的行数Qȝ执行旉会?U?/div><div><br></div><div>如果我们查看derby.log文g中查询执行计划,我们可以L的发现问题:Table Scan ResultSet for TBL at read committed isolation</div><div>level using instantaneous share row locking chosen</div><div>by the optimizer</div><div><br></div><div><br></div><div>q意味着DerbyZ记录排序,是在整个表中执行了查找这个操作。那我们可以做些什么来改善q个情况呢?{案很简单,在这一栏上创徏一个烦引。我们可以通过如下的SQL语句来做qg事: CREATE INDEX tbl_owner ON tbl(owner)</div><div><br></div><div><br></div><div>如果我们重复我们先前的例子,我们得C个和我们没有做排序前的那个例子相似的l果Q在我的机器上是不到1U)?/div><div><br></div><div>同样Q如果你现在查询derby.logQ你看C面的信息Q而不是和上面的一LQ:Index Scan ResultSet for TBL using index TBL_OWNER</div><div>at read committed isolation level using share row locking</div><div>chosen by the optimizer</div><div><br></div><div><br></div><div>q就意味着我们可以保Derby使用了刚创徏的烦引来获取合适的行?/div><div><br></div><div>使用合适的索引序</div><div><br></div><div>我们已经看到了烦引是如何帮助我们改善了排序某一栏数据时的性能。但是如果我们尝试去反{排序的顺序的时候会发生什么呢Q假设我们希望根据owner栏降序分cL们的数据。在q种情况下,我们原先的查询就会变成如下的语句Q?SELECT * FROM tbl ORDER BY owner DESC</div><div><br></div><div><br></div><div>注意Q我们增加了DESCq个关键字,该关键字按降序来排序我们的l果。如果我们执行这个新修改q的查询语句Q将会发现整个执行的旉又增加到先前?Q?U。ƈ且,在日志文件中Q你会发现又是执行了全表扫描?/div><div><br></div><div>解决的方法就是ؓq一栏创Z个降序的索引。对于我们的owner栏,我们执行如下的SQL语句?CREATE INDEX tbl_owner_desc ON tbl(owner desc)</div><div><br></div><div><br></div><div>现在我们对这一栏有两个索引了(两个序Q,因此查询性能又恢复到了可接受的范围了。注意查询日志中q一行:Index Scan ResultSet for TBL using index TBL_OWNER_DESC</div><div>at read committed isolation level using share row locking</div><div>chosen by the optimizer</div><div>q我们信我们使用了新建的索引。因此,如果你经常要对结果进行降序排序的话,你应该考虑创徏一个合适的索引来获取更高的性能?/div><div>转自Q?/div><div>http://space.itpub.net/?uid-47598-action-viewspace-itemid-207379</div></div><img src ="http://www.shnenglu.com/beautykingdom/aggbug/101817.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/beautykingdom/" target="_blank">chatler</a> 2009-11-24 16:40 <a href="http://www.shnenglu.com/beautykingdom/archive/2009/11/24/101817.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Informix数据库的锁技?http://www.shnenglu.com/beautykingdom/archive/2009/11/15/101025.htmlchatlerchatlerSun, 15 Nov 2009 15:22:00 GMThttp://www.shnenglu.com/beautykingdom/archive/2009/11/15/101025.htmlhttp://www.shnenglu.com/beautykingdom/comments/101025.htmlhttp://www.shnenglu.com/beautykingdom/archive/2009/11/15/101025.html#Feedback0http://www.shnenglu.com/beautykingdom/comments/commentRss/101025.htmlhttp://www.shnenglu.com/beautykingdom/services/trackbacks/101025.html
INFORMIX使用锁技术解军_多用戯问数据库情况下,对同一对象讉K的ƈ发控刉题。INFORMIX支持复杂的、可伸羃性的锁技术?

锁的cd

INFORMIX有三U不同类型的锁。它们在不同的情况下使用?

1. SHARED?

    SHARED锁只保留对象的可L。当锁存在时Q对象不能改变。多个程序可对同个对象加SHARED锁?

2. EXCLUSIVE?

    只能使单个程序用。在E序要改变对象时使用。当其他锁存在时QEXCLUSIVE锁不能用。当使用了EXCLUSIVE 锁后Q其他锁不能用于同一对象?

3. PROMOTABLE?/font>

    实现更新的目的。PROMOTABLE锁可以放在已l有SHARED锁的记录Q但不能攑֜已经有PROMOTABLE锁和EXCLUSIVE锁的地方。当记录上无其他锁(含SHARED 锁)情况下,q时在程序准备改变锁的记录时QPROMOTABLE锁可以提升ؓEXCLUSIVE锁。如果在已有SHARED锁的记录上设|了PROMOTABLE锁,在PROMOTABLE锁可以提升到EXCLUSIVE锁之前需要删除SHARED 锁。PROMOTABLE锁只能在INFORMIX Universal Server中支持?

锁的范围

    INFORMIX对于数据锁定提供了三U不同的方式Q范围由大到分别是数据库、表、记录锁。用的时机要看?
用状况而定?

1. 数据库?

    你可以用CONNECT, DATABASE, ?nbsp;CREATE DATABASE语句打开数据库。打开数据库的操作在数据库上讄了SHARED锁。只要程序打开一个数据库QSHARED锁就会阻止其他程序删除数据库或在数据库上讄EXCLUSIVE锁。你可以用语句DATABASE database name EXCLUSIVE锁定整个数据库。若此时其他用户正在使用该数据库Q该操作返回错误。一旦设|了EXCLUSIVE锁,其他E序׃能打开数据库,因ؓ打开时要攄一个SHARED锁。只有数据库关闭Ӟ数据库锁才释放。你可以用DISCONNECT或CLOSE DATABASE昄地处理,也可以运行其他的DATABASE语句隐含的处理。一般数据库UEXCLUSIVE锁是独占数据库资源,防止其他E序讉K数据库。它使得E序非常单,不会产生q发效果。常用在非高峰时期要改变大量数据时如数据库备份过E?

2. 表?/font>

    INFORMIX提供两种模式表锁:EXCLUSIVE MODE 和SHARE MODE。你可以锁整个表。在某些情况下,q个操作是自动进行。当INFORMIX处理下列语句Ӟ一般锁整个的表QALTER INDEX 、ALTER TABLE 、CREATE INDEX、DROP INDEX 、RENAME COLUMN、RENAME TABLE 。该语句l束或事务结束会释放该锁。在某些查询语句中,INFORMIX也自动锁整个表。你可以用LOCK TABLE语句昄地锁整个表。该语句允许你对整个表设|EXCLUSIVE锁或SHARED锁。当你程序从表中d数据ӞSHARED锁防止表中数据更新。INFORMIX Universal Server 通过讄隔离U别实现更大E度q发数据保护?nbsp;

    表EXCLUSIVE锁防止对同个表的q发使用。因此,如果其他许多E序要用该表时Q系l性能会受C重媄响。类似数据库UEXCLUSIVE锁,表EXCLUSIVE锁常用在非高峰时期要改变大量数据时。例如,有些应用在高峰期间ƈ不更新表Q它们可以在非高峰期间定期以批处理方式更新?

    通过UNLOCK TABLE table name 解除锁。当存在事务Ӟ事务l束时解除锁?

3. 记录U、页U、键字?/font>

    表的一个记录是可设|锁的最对象。一个程序可以锁一个记录或记录的集合,同时其他E序可以操作同一个表的其他记录。Universal Server 以磁盘页面(disk pagesQؓ单位存储数据。一个磁盘页面包含一个或多个记录。在有些情况下,锁比单个锁更好些。其他数据库服务器可能不存在、键字锁?

    在Universal Server上,当你创徏表时Q你可以选择使用记录U锁或页U锁。其他的数据库服务器不提供这U选择。页U、记录锁有相同的效果。当Universal Server需要锁一个记录时Q根据表创徏时的锁模式,锁这个记录或记录所在的面。在一定情况下Q数据库服务器需要锁一个不存在的记录。它的效果相当于在记录将要存在的地方放一?br>锁。当表用记录锁Ӟ对假想的记录使用键字锁。当表用页U锁Ӟ含有或可能含有键字的索引将被设|键U锁?

锁的时期

    E序控制数据库锁的时期。数据库关闭Ӟ数据库锁U也释放。表U、记录、烦引锁的时期依赖于用的SQL语句以及是否使用事务。如果数据库没有使用事务Q也是_事务日志不存在ƈ且你没有使用COMMIT WORK语句Q当q行UNLOCK TABLE语句Ӟ表锁就释放。当使用了事务时Q事务结束,表、记录、烦引锁都释放?/div>
 
修改旉的处?/font>

    当数据库服务器通过一个更新游标取一条记录时Q它在该记录上设|一个PROMOTABLE锁。如果这个动作成功,数据库服务器知道其他E序不能改变此记录。因为PROMOTABLE锁不是独占的Q其他程序能够l读q条记录。由于在取此记录的程序执行UPDATE、DELETE语句或简单地取下一条记录之前,它可能花一些时间。这样就提高了性能。当它改变一个记录时Q数据库服务器在q条记录上设|一个EXCLUSIVE锁。如果它已经有一个PROMOTABLE锁,它将锁改为EXCLUSIVE状态?

    EXCLUSIVE锁的时期依赖于是否用事务。如果没有用事务,被修改的记录写到盘上就会释放该锁。当使用了事务时Q? 锁就会保持到事务的结束。这个动作防止其他程序用可能回滚到原来状态的记录?

    当用了事务Ӟ只要删除记录键锁就会设|。用键U锁解决下列错误Q程序A删除一个记录,E序B插入有同样键的记录。程序A回滚事务Q数据库服务器恢复了删除的记录Q这时程序B插入的记录怎么办?通过锁烦引,数据库服务器{到E序A提交事务时才插入记录?

    ׃ Universal Server数据库服务器理自己的锁Q所以它能提供不同类型的锁。其他的数据库服务器是通过操作pȝ的特性实现锁Q所以不能提供多U选择。有些操作系l通过操作pȝ服务方式向外提供锁函数。在q些pȝQ数据库支持SET LOCK MODE语句。而有些操作系l不支持内核U的Ҏ,数据库这旉过在数据库目录下生小文g实现锁。这些文件带?lok后缀。如果你的程序用单个SELECT语句或没有用FOR UPDATE声明的游标提取一个记录,此记录不是否被一个未完成的交易上锁会马上被提取。这栯产生最好的性能。当你用FOR UPDATE声明的游标时Q它在提取前当前记录上锁。如果当前记录已l有锁,随作选择模式的不同,E序会等待或q回错误。当取下一个记录时Q数据库看当前记录是否更斎ͼ使用带WHERE CURRENT OF 的UPDATE)


锁的模式

锁的模式军_E序遇到被锁的数据会产生怎样的结果。当E序要提取或修改一个上锁的记录Ӟ会有下面几种情况Q?

1?nbsp;数据库马上通过SQLCODE变量或SQLSTATEl构l程序返回一个错误代码?

2?nbsp;在数据解锁前Q数据库程序挂赗?

3、数据库程序挂起一D|间。如果锁q未解,数据库给E序q回一个错误代码?/font>

你可以通过SET LOCK MODE模式选择以上l果?

如果你喜Ƣ程序等待(对大多数E序而言q是最好的选择Q,q行下列语句QSET LOCK MODE TO WAIT?

    当设|了锁模式后Q程序常忽视其他q发E序的存在性。如果程序需要访问其他程序已上锁的记录时Q它{待别的E序解锁Q然后l。gq的旉怸可预?

    {待解锁不利的一面就是可能会{待很长旉。如果不能接受很长gq,E序可以q行下列语句QSET LOCK MODE TONOT WAIT选择不等待。当E序需要一个锁记录Ӟ它马上返回一个错误代码,且当前的SQL语句l止。这ӞE序必须回滚当前的交易再试一ơ。程序开始时Q数据库初始讄Z{待?

    当你使用UNIVERSAL SERVERӞ你有另外的选择。你可以让数据库讄{待旉的上限。你可用下列语句QSETLOCK MODE TO WAIT 18让数据库?8U等待上限。若期间锁还没有解开Q将q回错误代码?

    在每个程序都选择了锁{待模式情况下,有可能出现死锁。死锁是E序之间怺dQ每个程序在其他E序要访问的对象上设|了锁。UNIVERSAL SERVER在单个网l服务器情况下会马上到死锁。如果程序选择了锁{待模式Q通过l程序返回错误代码,你就知道你遇C死锁。而在多个数据库服务器的情况下QUNIVERSAL SERVER不能马上到。每个数据库服务器都讄锁等待的上限。如果超Ӟ数据库服务器p为发生了死锁且返回相关的错误代码。数据库理员可以设|和修改{待旉的上限?/font>
转自Q?/div>
http://blog.chinaunix.net/u/14063/showart.php?id=114859


chatler 2009-11-15 23:22 发表评论
]]>锁的用处及脏诅R不可重复读和觉读的概?/title><link>http://www.shnenglu.com/beautykingdom/archive/2009/11/13/100899.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Fri, 13 Nov 2009 15:09:00 GMT</pubDate><guid>http://www.shnenglu.com/beautykingdom/archive/2009/11/13/100899.html</guid><wfw:comment>http://www.shnenglu.com/beautykingdom/comments/100899.html</wfw:comment><comments>http://www.shnenglu.com/beautykingdom/archive/2009/11/13/100899.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/beautykingdom/comments/commentRss/100899.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/beautykingdom/services/trackbacks/100899.html</trackback:ping><description><![CDATA[<br>        锁就是防止其他事务访问指定的资源的手Dc锁是实现ƈ发控制的主要ҎQ是多个用户能够同时操纵同一个数据库中的数据而不发生数据不一致现象的重要保障。一般来_锁可以防止脏诅R不可重复读和觉读? <p>        脏读是指当一个事务正在访问数据,q且Ҏ据进行了修改Q而这U修改还没有提交到数据库中,q时Q另外一个事务也讉Kq个数据Q然后用了q个数据。因个数据是q没有提交的数据Q那么另外一个事务读到的q个数据是脏数据Q依据脏数据所做的操作可能是不正确的?/p> <p>        不可重复L指在一个事务内Q多ơ读同一数据。在q个事务q没有结束时Q另外一个事务也讉K该同一数据。那么,在第一个事务中的两ơ读数据之间Q由于第二个事务的修改,那么W一个事务两ơ读到的的数据可能是不一L。这样就发生了在一个事务内两次d的数据是不一LQ因此称为是不可重复诅R?/p> <p>        q觉L指当事务不是独立执行时发生的一U现象,例如W一个事务对一个表中的数据q行了修改,q种修改涉及到表中的全部数据行。同ӞW二个事务也修改q个表中的数据,q种修改是向表中插入一行新数据。那么,以后׃发生操作W一个事务的用户发现表中q有没有修改的数据行Q就好象发生了觉一栗?/p> <p>隔离的概?</p> <p>        ANSI SQL中定义的4个隔ȝ实际上是用对锁的操作来定义的Q?nbsp; 脏读: L据时不加锁?nbsp; 提交? 在读数据之前加一个读锁,d之后释放锁?nbsp; 可重复读: 在读数据之前加一个读锁,d之后不释NQ直C务rollback或者commit后才释放锁?nbsp; 串行化读: 在读数据之前在读取的条g上加锁(UCؓ条g锁)Q读完之后不释放锁,直到事务rollback或者commit后才释放锁?/p> <br>转自Q?br><a >http://blog.chinaunix.net/u/14063/showart.php?id=114849</a> <img src ="http://www.shnenglu.com/beautykingdom/aggbug/100899.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/beautykingdom/" target="_blank">chatler</a> 2009-11-13 23:09 <a href="http://www.shnenglu.com/beautykingdom/archive/2009/11/13/100899.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://www.shnenglu.com/" title="精品视频久久久久">精品视频久久久久</a> <div class="friend-links"> </div> </div> </footer> <a href="http://www.wggls.cn" target="_blank">һձȾþۺ</a>| <a href="http://www.fozhun.cn" target="_blank">ŷþþXXX</a>| <a href="http://www.aeuou.cn" target="_blank">þþ뾫Ʒպ˳</a>| <a href="http://www.hsjituan.com.cn" target="_blank">þþþƷþþþþ</a>| <a href="http://www.icaew.com.cn" target="_blank">ѾƷþþþþĻ</a>| <a href="http://www.sanya99job.cn" target="_blank">޹þþۺ</a>| <a href="http://www.681lc.cn" target="_blank">ٸþ</a>| <a href="http://www.noahmachine.com.cn" target="_blank">þۺϺݺɫۺ</a>| <a href="http://www.gaguni.cn" target="_blank">þɫۺ</a>| <a href="http://www.janl.cn" target="_blank">Ʒþþø</a>| <a href="http://www.pareng.cn" target="_blank">һaɫƬþٸһHƬѷ </a>| <a href="http://www.cz27b1.cn" target="_blank">þۺձ츾</a>| <a href="http://www.taobaoluntan.net.cn" target="_blank">þþƷAV㽶</a>| <a href="http://www.sdlove.cn" target="_blank">һþaþþƷۺ</a>| <a href="http://www.pvzj.cn" target="_blank">޹ƷۺϾþһ</a>| <a href="http://www.wthangjia.cn" target="_blank">2022Ʒþþþ</a>| <a href="http://www.jianzhuhr.net.cn" target="_blank">һAvëƬþþƷ</a>| <a href="http://www.8910wan.cn" target="_blank">Ʒ99þ99þþ</a>| <a href="http://www.23tlbb.cn" target="_blank">þ޾Ʒվ</a>| <a href="http://www.tongdiaocj.cn" target="_blank">þþþAVרɫ</a>| <a href="http://www.ggfuns.cn" target="_blank">ɫۺϾþĻ</a>| <a href="http://www.pass3d.cn" target="_blank">RE99þþƷ66</a>| <a href="http://www.665m.cn" target="_blank">þþƷһ</a>| <a href="http://www.7111393.cn" target="_blank">ݺ88ۺϾþþþۺ</a>| <a href="http://www.5o42i9.cn" target="_blank">þŮcc98cm</a>| <a href="http://www.lpxiu.cn" target="_blank">պʮ˽һþ</a>| <a href="http://www.oaaz.cn" target="_blank">Ʒþþþþþþþ</a>| <a href="http://www.yssmtm.cn" target="_blank">91龫Ʒ91þþþ</a>| <a href="http://www.hgysc.cn" target="_blank">þ99ڹ</a>| <a href="http://www.quheitou.net.cn" target="_blank">ŷ˼Ծþ</a>| <a href="http://www.b5ezt1.cn" target="_blank">ٸŮþۺɫ</a>| <a href="http://www.sanbaotong.cn" target="_blank">պӰþþñ</a>| <a href="http://www.gmve.cn" target="_blank">㽶þƵ</a>| <a href="http://www.grcooling.com.cn" target="_blank">þѹۿƵ</a>| <a href="http://www.ceovod.cn" target="_blank">þþþþ޾Ʒ</a>| <a href="http://www.ctoshop163.cn" target="_blank">þ99ƷþþþþҰ</a>| <a href="http://www.masterflexpump.com.cn" target="_blank">Ʒþþþþ</a>| <a href="http://www.95dq.cn" target="_blank">ھƷþþþþþɬ </a>| <a href="http://www.fengshi800.cn" target="_blank">Ʒþþþþþ</a>| <a href="http://www.qqfzl.cn" target="_blank">yellowĻþ</a>| <a href="http://www.mechuo.cn" target="_blank">þ99Ʒþþþþ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>