透明 发表于 2015-1-16 22:22:20

MYSQL编程:创立索引对SQL语句实行的影响

一些典型的RDBMS功能并不总是在DBaaS系统中可用。例如MySQL学习教程,WindowsAzureSQLDatabase(以前的SQLAzure)是微软的DBaaS产品,提供了一个类似于SQLServer的数据库平台。<pstyle="TEXT-INDENT:2em">1、创立索引对实行企图的影响<pstyle="TEXT-INDENT:2em">在SQL入手下手实行之前,Oracle会断定SQL语句的实行企图,并依照实行企图的步骤会见响应的表和索引。<pstyle="TEXT-INDENT:2em">一旦实行企图断定上去,Oracle会依照这个实行企图完成SQL语句的实行,在SQL语句实行入手下手以后创建的索引不会改动SQL语句的实行企图。<pstyle="TEXT-INDENT:2em">因而,创立索引不会对实行企图有任何的影响,也就不会对运转中的SQL语句有影响。上面经由过程一个例子复杂考证一下:<pstyle="TEXT-INDENT:2em">SQL>CREATETABLETEST(IDNUMBER,FIDNUMBER,NAMEVARCHAR2(30),BID_COLUMNSCHAR(2000));<pstyle="TEXT-INDENT:2em">Tablecreated.<pstyle="TEXT-INDENT:2em">SQL>INSERTINTOTESTVALUES(1,0,OBJECT,0);<pstyle="TEXT-INDENT:2em">1rowcreated.<pstyle="TEXT-INDENT:2em">SQL>INSERTINTOTESTVALUES(2,1,TABLE,0);<pstyle="TEXT-INDENT:2em">1rowcreated.<pstyle="TEXT-INDENT:2em">SQL>INSERTINTOTESTVALUES(3,1,INDEX,0);<pstyle="TEXT-INDENT:2em">1rowcreated.<pstyle="TEXT-INDENT:2em">SQL>INSERTINTOTESTVALUES(4,1,VIEW,0);<pstyle="TEXT-INDENT:2em">1rowcreated.<pstyle="TEXT-INDENT:2em">SQL>INSERTINTOTESTVALUES(5,1,SYNONYM,0);<pstyle="TEXT-INDENT:2em">1rowcreated.<pstyle="TEXT-INDENT:2em">SQL>INSERTINTOTESTVALUES(6,1,SOURCE,0);<pstyle="TEXT-INDENT:2em">1rowcreated.<pstyle="TEXT-INDENT:2em">SQL>INSERTINTOTESTSELECT20000+ROWNUM,2,TABLE_NAME,0FROMDBA_TABLES;<pstyle="TEXT-INDENT:2em">874rowscreated.<pstyle="TEXT-INDENT:2em">SQL>INSERTINTOTESTSELECT30000+ROWNUM,3,INDEX_NAME,0FROMDBA_INDEXES;<pstyle="TEXT-INDENT:2em">1074rowscreated.<pstyle="TEXT-INDENT:2em">SQL>INSERTINTOTESTSELECT40000+ROWNUM,4,VIEW_NAME,0FROMDBA_VIEWS;<pstyle="TEXT-INDENT:2em">2929rowscreated.<pstyle="TEXT-INDENT:2em">SQL>INSERTINTOTESTSELECT50000+ROWNUM,5,TABLE_NAME,0FROMDBA_SYNONYMS;<pstyle="TEXT-INDENT:2em">2437rowscreated.<pstyle="TEXT-INDENT:2em">SQL>INSERTINTOTESTSELECT60000+ROWNUM,6,NAME,0FROMDBA_SOURCE;<pstyle="TEXT-INDENT:2em">99717rowscreated.<pstyle="TEXT-INDENT:2em">SQL>COMMIT;<pstyle="TEXT-INDENT:2em">Commitcomplete.<pstyle="TEXT-INDENT:2em">SQL>settimingon<pstyle="TEXT-INDENT:2em">SQL>SELECTCOUNT(*)FROMTEST<pstyle="TEXT-INDENT:2em">2STARTWITHID=1<pstyle="TEXT-INDENT:2em">3CONNECTBYPRIORID=FID;<pstyle="TEXT-INDENT:2em">COUNT(*)<pstyle="TEXT-INDENT:2em">----------<pstyle="TEXT-INDENT:2em">107037Elapsed:00:02:03.84



<pstyle="TEXT-INDENT:2em">机关一个树状查询,然跋文录这个树状查询的运转工夫。<pstyle="TEXT-INDENT:2em">SQL>SELECTCOUNT(*)FROMTEST<pstyle="TEXT-INDENT:2em">2STARTWITHID=1<pstyle="TEXT-INDENT:2em">3CONNECTBYPRIORID=FID;<pstyle="TEXT-INDENT:2em">COUNT(*)<pstyle="TEXT-INDENT:2em">----------<pstyle="TEXT-INDENT:2em">107037<pstyle="TEXT-INDENT:2em">Elapsed:00:05:26.15<pstyle="TEXT-INDENT:2em">再次运转查询,在查询运转入手下手,即刻在另外一个SESSION创立索引。经由过程察看实行工夫能够发明,创立索引不会对运转中的SQL语句带来功能提拔,并且极可能因为体系资本的争用形成查询速率变慢。假如在IO散布的对照公道的体系中,能够看到,创立索引能够很快完成,并且随后实行一样的查询因为会利用索引,也会很快的前往布局,可是索引的创立不会加速已处于运转形态的语句的速率。<pstyle="TEXT-INDENT:2em">SESSION2:<pstyle="TEXT-INDENT:2em">SQL>SETTIMINGON<pstyle="TEXT-INDENT:2em">SQL>CREATEINDEXIND_TEST_IDONTEST(ID)TABLESPACEUSERS;<pstyle="TEXT-INDENT:2em">索引已创立。<pstyle="TEXT-INDENT:2em">已用工夫:000:01:56.92<pstyle="TEXT-INDENT:2em">SQL>CREATEINDEXIND_TEST_FIDONTEST(FID)TABLESPACEUSERS;<pstyle="TEXT-INDENT:2em">索引已创立。<pstyle="TEXT-INDENT:2em">已用工夫:00:02:00.57<pstyle="TEXT-INDENT:2em">创建索引后,一样的查询速率失掉分明的提拔。<pstyle="TEXT-INDENT:2em">SQL>SELECTCOUNT(*)FROMTEST<pstyle="TEXT-INDENT:2em">2STARTWITHID=1<pstyle="TEXT-INDENT:2em">3CONNECTBYPRIORID=FID;<pstyle="TEXT-INDENT:2em">COUNT(*)<pstyle="TEXT-INDENT:2em">----------<pstyle="TEXT-INDENT:2em">107037<pstyle="TEXT-INDENT:2em">已用工夫:00:01:02.11<pstyle="TEXT-INDENT:2em">下面创建两个索引的语句和查询语句是在独自的SESSION2上运转的。SESSION2上的三个操纵――创立两个索引和实行不异的查询语句――都实行完成了,而第一个会话的的运转了局仍旧没有前往。<pstyle="TEXT-INDENT:2em">2、创立索引对ORACLE外部机制的影响<pstyle="TEXT-INDENT:2em">下面经由过程一个复杂的例子申明,创立索引不会改动已运转的SQL的实行企图。可是并非说,创立索引不克不及给已运转的SQL语句带来功能的提拔。<pstyle="TEXT-INDENT:2em">上面看一个对照特别的例子:<pstyle="TEXT-INDENT:2em">SQL>CREATETABLETESTASSELECTROWNUMID,A.*FROMDBA_OBJECTSA;<pstyle="TEXT-INDENT:2em">表已创立。<pstyle="TEXT-INDENT:2em">SQL>CREATETABLETEST1ASSELECTROWNUMID,ROWNUMFID,A.*FROMDBA_SYNONYMSA;<pstyle="TEXT-INDENT:2em">表已创立。<pstyle="TEXT-INDENT:2em">SQL>ALTERTABLETESTADDCONSTRAINTPK_TESTPRIMARYKEY(ID);<pstyle="TEXT-INDENT:2em">表已变动。<pstyle="TEXT-INDENT:2em">SQL>ALTERTABLETEST1ADDCONSTRAINTFK_TEST1_FIDFOREIGNKEY(FID)REFERENCESTEST(ID);<pstyle="TEXT-INDENT:2em">表已变动。<pstyle="TEXT-INDENT:2em">SQL>INSERTINTOTEST1SELECT*FROMTEST1;<pstyle="TEXT-INDENT:2em">已创立1616行。<pstyle="TEXT-INDENT:2em">SQL>INSERTINTOTEST1SELECT*FROMTEST1;<pstyle="TEXT-INDENT:2em">已创立3232行。<pstyle="TEXT-INDENT:2em">SQL>INSERTINTOTEST1SELECT*FROMTEST1;<pstyle="TEXT-INDENT:2em">已创立6464行。<pstyle="TEXT-INDENT:2em">SQL>INSERTINTOTEST1SELECT*FROMTEST1;<pstyle="TEXT-INDENT:2em">已创立12928行。<pstyle="TEXT-INDENT:2em">SQL>INSERTINTOTEST1SELECT*FROMTEST1;<pstyle="TEXT-INDENT:2em">已创立25856行。<pstyle="TEXT-INDENT:2em">SQL>COMMIT;<pstyle="TEXT-INDENT:2em">提交完成。<pstyle="TEXT-INDENT:2em">SQL>DELETETEST1;<pstyle="TEXT-INDENT:2em">已删除51712行。<pstyle="TEXT-INDENT:2em">SQL>COMMIT;<pstyle="TEXT-INDENT:2em">提交完成。<pstyle="TEXT-INDENT:2em">SQL>SETTIMINGON<pstyle="TEXT-INDENT:2em">SQL>DELETETEST;<pstyle="TEXT-INDENT:2em">已删除6208行。<pstyle="TEXT-INDENT:2em">已用工夫:00:00:17.03<pstyle="TEXT-INDENT:2em">SQL>ROLLBACK;<pstyle="TEXT-INDENT:2em">回退已完成。已用工夫:00:00:00.06



<pstyle="TEXT-INDENT:2em">机关两张表,TEST1的FID创建了参考TEST表ID列的外键。可是这里并没有在外键列上创建索引。<pstyle="TEXT-INDENT:2em">向TEST和TEST1表中填进必定数据量的数据,入手下手测试。这里测试的是删除TEST表的实行工夫。起首将TEST1用DELETE命令删除,提交后盘算删除TEST表的工夫,约莫必要17秒,然后将数据回滚。<pstyle="TEXT-INDENT:2em">上面筹办举行第二次删除测试,所分歧的是,在删除操纵入手下手后,即刻在另外一个SESSION中给外键列增添索引,经由过程测试能够发明,几近在索引创立完的同时,第一个SESSION就前往了却果,删除必要的工夫延长到了3秒。<pstyle="TEXT-INDENT:2em">第一个SESSION的删除语句:<pstyle="TEXT-INDENT:2em">SQL>DELETETEST;<pstyle="TEXT-INDENT:2em">已删除6208行。<pstyle="TEXT-INDENT:2em">已用工夫:?00:00:03.00<pstyle="TEXT-INDENT:2em">第二个SESSION的索引创立语句:<pstyle="TEXT-INDENT:2em">SQL>CREATEINDEXIND_TEST1_FIDONTEST1(FID);<pstyle="TEXT-INDENT:2em">索引已创立<pstyle="TEXT-INDENT:2em">这个测试中索引的创立影响到了已在运转的SQL语句,并分明地进步了实行效力。这个征象和上一篇文章中形貌的概念其实不抵触。关于用户收回的SQL语句,Oracle的实行企图是稳定的,可是为了实行用户收回的SQL语句,Oracle在外部做了大批的操纵,包含权限的反省、语法的反省、方针工具是不是存在,和保护数据的完全性等等。这个例子中,用户收回的SQL语句的实行企图没有改动,产生改动的是Oracle外部保护操纵语句的实行企图。<pstyle="TEXT-INDENT:2em">假如在第一个SESSION实行DELETE操纵的同时,经由过程上面的SQL语句反省第一个SESSION正在运转的语句,会发明上面的了局(9i及之前版本,假如是10g,则只能看到DELETETEST)。<pstyle="TEXT-INDENT:2em">SQL>SELECTSQL_TEXTFROMV$SESSIONA,V$SQLB<pstyle="TEXT-INDENT:2em">2WHEREA.SQL_HASH_VALUE=B.HASH_VALUE<pstyle="TEXT-INDENT:2em">3ANDA.SQL_ADDRESS=B.ADDRESS<pstyle="TEXT-INDENT:2em">4ANDA.SID=17;<pstyle="TEXT-INDENT:2em">SQL_TEXT<pstyle="TEXT-INDENT:2em">----------------------------------------------------------------------------<pstyle="TEXT-INDENT:2em">select/**//*+all_rows*/count(1)from"YANGTK"."TEST1"where"FID"=:1<pstyle="TEXT-INDENT:2em">这个SQL语句就是Oracle用来保护完全性的外部SQL。<pstyle="TEXT-INDENT:2em">回忆一下我们的例子,创建了外键,可是没有创建索引。当每删除一条TEST的纪录,Oracle都要反省这个主键是不是在TEST1中被援用。因为没有索引,Oracle只能经由过程全表扫描来寻觅TEST1中的纪录。固然TEST1没有纪录,可是删除TEST时利用的是DELETE而不是TRUNCATE,因而TEST1的高水位线并没有下落,也就是说,每删除一条TEST的纪录,都必要全表扫描一张具有5万条数据的表,这就是为何谁人DELETE操纵实行很慢的缘故原由。<pstyle="TEXT-INDENT:2em">而我们创建的索引恰是加速了这个步骤,Oracle外部保护的SQL语句在索引可用后选择了索引扫描,因而DELETE操纵在索引创立后敏捷前往。<pstyle="TEXT-INDENT:2em">3、小结<pstyle="TEXT-INDENT:2em">创立索引关于用户已收回的正在运转的SQL不会带来功能的提拔。这是因为用户实行的语句要依照实行企图来运转,而实行企图在运转入手下手的时分就断定上去了,且不会在SQL语句的运转过程当中产生变更。关于SQL实行过程当中,Oracle外部实行的用于保护的SQL语句,是有大概重新创立的索引中取得功能提拔的。

“通过有能力的DBA的一个简单计划,MySQL可以达到令人难以想像的运行速度,”一位资深DBA如此表示。MySQL中没有多余的功能来拖累CPU或占用内存。

爱飞 发表于 2015-1-19 09:36:10

我是新手,正在学习数据库和操作系统,深感理论的泛广,唯有一步一步来,但是又感觉时间不够,收集了很多资料却总是没能认真的看完,希望有一个讨论板块,大家共同解决,共同分享,共同努力

小女巫 发表于 2015-1-26 22:35:21

备份方面可能还是一个老大难的问题。不能单独备份几个表总是感觉不爽。灵活备份的问题不知道什么时候才能解决。

海妖 发表于 2015-2-4 22:19:11

原理很简单,对要求长时间计算某一时间点的报表生成和防用户操作错误很有帮助。但是比起Oracle10g的闪回技术还是细粒度不够。可惜!

不帅 发表于 2015-2-10 21:55:28

微软对CLR作了大篇幅的宣传,这是因为数据库产品终于融入.net体系中。最开始我们也是狂喜,感觉对象数据库的一些概念可以实现了。

飘灵儿 发表于 2015-3-1 16:15:42

我是一个ERP初学者,对于前台运用基本熟悉,但对于后台SQLServer的运用一点也不懂,特想学习下相关资料。至少懂得一些基本的运用。希望各位能给于建议,小弟再谢过!

若天明 发表于 2015-3-10 20:45:27

呵呵,这就是偶想说的

小魔女 发表于 2015-3-17 10:14:55

如果你是从“学习某一种数据库应用软件,从而获得应聘的资本和工作机会”的角度来问的话。

活着的死人 发表于 2015-3-24 07:21:08

所以你总能得到相应的升级版本,来满足你的需求。
页: [1]
查看完整版本: MYSQL编程:创立索引对SQL语句实行的影响