仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 879|回复: 8
打印 上一主题 下一主题

[学习教程] MYSQL网页编程之优化Oracle库表计划的多少办法

[复制链接]
愤怒的大鸟 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-16 22:31:58 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
DBaaS并不意味着解决方案提供者要让自己失业。与其他系统一样,在实施DBaaS解决方案时,客户可能需要部署、迁移、支持、异地备份、系统集成和灾难恢复等方面的帮助。oracle|计划|优化媒介  尽年夜多半的Oracle数据库功能成绩都是因为数据库计划分歧理酿成的,只要少部分成绩根植于DatabaseBuffer、SharePool、RedoLogBuffer等外存模块设置分歧理,I/O争用,CPU争用等DBA职责局限上。以是除非是面临一个业已完成不成变动的体系,不然我们不该过量地将存眷点投向内存、I/O、CPU等功能调剂项目上,而应存眷数据库表自己的计划是不是公道,库表计划的公道性才是程序功能的真正执盟主者。
公道的数据库计划必要思索以下的方面:
  ・营业数据以何种体例表达。如一个员工有多个Email,你能够在T_EMPLOYEE表中创建多个Email字段如email_1、email_2、email_3,也能够创立一个T_EMAIL子表来存储,乃至能够用逗号分开开多个Email地点寄存在一个字段中。
  ・数据以何种体例物理存储。如年夜表的分区,表空间的公道计划等。
  ・怎样创建公道的数据表索引。表索引几近是进步数据表查询功能最无效的办法,Oracle具有范例丰厚的数据表索引范例,怎样弃取选择显得出格主要。
  本文我们将眼光次要聚焦于数据表的索引上,同时也将说起其他两点的内容。经由过程对一个复杂的库表计划实例的剖析引出计划中的不敷,并一一更正。思索得手工编写库表的SQL剧本原始且低效,我们将用今朝最盛行的库表计划工具PowerDesigner10来说述表计划的历程,以是在本文中你还会懂得到一些相干的PowerDesigner的利用技能。
  一个复杂的例子
  某个开辟职员动手计划一个定单的体系,这个体系中有两个次要的营业表,分离是定单基础信息表和定单条目表,这两张表具有主从干系的表,个中T_ORDER是定单主表,而T_ORDER_ITEM是定单条目表。数据库计划职员的计划功效如所示:


定单主从表  ORDER_ID是定单号,为T_ORDER的主键,经由过程名为SEQ_ORDER_ID的序列发生键值,而ITEM_ID是T_ORDER_ITEM表的主键,经由过程名为SEQ_ORDER_ITEM的序列发生键值,T_ORDER_ITEM经由过程ORDER_ID外键联系关系到T_ORDER表。  需求文档指出定单纪录将经由过程以下两种体例来查询数据:  ・CLIENT+ORDER_DATE+IS_SHPPED:依据"客户+定货日期+是不是发货"前提查询定单及定单条目。  ・ORDER_DATE+IS_SHIPPED:依据"定货日期+是不是发货"前提查询定单及定单条目。  数据库计划职员依据这个请求,在T_ORDER表的CLIENT、ORDER_DATE及IS_SHPPED三字段上创建了一个复合索引IDX_ORDER_COMPOSITE;在T_ORDER_ITEM为外键ORDER_ID创建IDX_ORDER_ITEM_ORDER_ID索引。  让我们看一下该份计划的终极SQL剧本:/*定单表*/
createtableT_ORDER(
  ORDER_IDNUMBER(10)notnull,
  ADDRESSVARCHAR2(100),
  CLIENTVARCHAR2(60),
  ORDER_DATECHAR(8),
  IS_SHIPPEDCHAR(1),
  constraintPK_T_ORDERprimarykey(ORDER_ID)
);createindexIDX_CLIENTonT_ORDER(
 CLIENTASC,
 ORDER_DATEASC,
 IS_SHIPPEDASC);/*定单条目子表*/createtableT_ORDER_ITEM(
 ITEM_IDNUMBER(10)notnull,
 ORDER_IDNUMBER(10),
 ITEMVARCHAR2(20),
 COUNTNUMBER(10),
 constraintPK_T_ORDER_ITEMprimarykey(ITEM_ID)
);createindexIDX_ORDER_ITEM_ORDER_IDonT_ORDER_ITEM(
 ORDER_IDASC);
 altertableT_ORDER_ITEMaddconstraintFK_T_ORDER__REFERENCE_T_ORDERforeignkey(ORDER_ID)referencesT_ORDER(ORDER_ID);  我们供认在ER干系上,这份计划其实不存在的缺点,但却存在以下有待优化的中央:  ・未将表数据和索引数据存储到分歧的表空间中,而不加区分地将它们存储到统一表空间里。如许,不仅会形成I/O合作,也为数据库的保护事情带来方便。  ・ORACLE会主动为表的主键列创立一个一般B-Tree索引,但因为这两张表的主键值都经由过程序列供应,具有严厉的按次性(升序或降序),此时手工为其指定一个反键索引(reversekeyindex)将加倍公道。  ・在子表T_ORDER_ITEM外键列ORDER_ID上创建的IDX_ORDER_ITEM_ORDER_ID的一般B-Tree索引十分合适设置为紧缩型索引,即创建一个紧缩型的B-Tree索引。由于一份定单会对应多个定单条目,这就意味着T_ORDER_ITEM表存在很多同值的ORDER_ID列值,经由过程将其索引指定为紧缩型的B-Tree索引,不仅能够削减IDX_ORDER_ITEM_ORDER_ID所需的存储空间,还将进步表操纵的功能。  ・妄图仅经由过程创建一个包括3字段IDX_ORDER_COMPOSITE复合索引满意如前所述的两种查询前提体例的索引是有成绩的,现实上利用ORDER_DATE+IS_SHIPPED复合前提的查询将使用不到IDX_ORDER_COMPOSITE索引。  优化计划  1、将表数据和索引数据分隔表空间存储  1.1表数据和索引为什么必要利用自力的表空间  Oracle激烈创建,任何一个使用程序的库表最少必要创立两个表空间,个中之一用于存储表数据,而另外一个用于存储表索引数据。由于假如将表数据和索引数据放在一同,表数据的I/O操纵和索引的I/O操纵将发生影响体系功能的I/O合作,下降体系的呼应效力。将表数据和索引数据寄存在分歧的表空间中(如一个为APP_DATA,另外一个为APP_IDX),并在物理层面将这两个表空间的数据文件放在分歧的物理磁盘上,就能够制止这类合作了。  具有自力的表空间,就意味着能够自力地为表数据和索引数据供应自力的物理存储参数,而不会产生互相影响,究竟表数据和索引数据具有分歧的特征,而这些特征又间接影响了物理存储参数的设定。  别的,表数据和索引数据自力存储,还会带来数据办理和保护上的方面。如你在迁徙一个营业数据库时,为了下降数据巨细,能够只迁出表数据的表空间,在方针数据库中经由过程重修索引的体例就能够天生索引数据了。  1.2表数据和索引利用分歧表空间的SQL语法  指定表数据及索引数据存储表空间语句最复杂的情势以下。  将表数据存储在APP_DATA表空间里:createtableT_ORDER(ORDER_IDNUMBER(10)notnull,…)tablespaceAPP_DATA;  将索引数据存储在APP_IDX表空间里:createindexIDX_ORDER_ITEM_ORDER_IDonT_ORDER_ITEM(ORDER_IDASC)tablespaceAPP_IDX;  1.3PowerDesigner中怎样操纵  1)起首,必需创立两个表空间。经由过程Model->Tablespace...在ListofTablespaces中创立两个表空间:
创立表空间  2)为每张表指定表数据存储的表空间。在计划区中双击表,翻开TableProperties计划窗口,切换到options页,按所示指定表数据的存储表空间。
指定表数据的存储表空间  3)为每一个索引指定索引数据的存储表空间。在TableProperties中切换到Indexes页,在这里列出了表的一切索引,双击需设置表空间的索引,在弹出的IndexProperties窗口中切换到Options页,按以下体例指定索引的存储表空间。
指定索引数据的存储表空间  将表空间的成绩延展一下:一个使用体系库表的表空间能够举行更精密的分别。  起首,假如表中存在LOB范例的字段,无为其指定一个特定的表空间,由于LOB范例的数据在物理存储布局的办理上和一样平常数据的战略有很年夜的分歧,将其放在一个自力的表空间中,便可便利地设置其物理存储参数了。  其次,必要思索库表数据的DML操纵特征:依据DML(INSERT,UPDATE,DELETE)操纵频仍水平,将几近不产生任何DML操纵的数据放在自力的表空间中,由于少少DML操纵的表可设置切合其特征的物理参数:如PCTFREE可置为0,其BUFFER_POOL指定为KEEP,以便将数据缓存在KEEP数据缓存区中等等,所在多有。  别的,还能够思索按营业必要将分歧的营业模块分隔寄存,这次要是思索到备份成绩。假定我们有一部分营业数据主要性很强,而其他的营业数据主要性绝对较弱,如许就能够将二者分隔存储,以便设置分歧的备份战略。  固然,无克制的细化表空间也将带来办理上和部署上的庞大,依据营业需求公道地计划表空间以到达办理和功能上的最好常常必要更多的衡量。  2、显式为主键列创建反向键索引  2.1反向键索引的道理和用处  我们晓得Oracle会主动为表的主键列创建索引,这个默许的索引是一般的B-Tree索引。关于主键值是按按次(递增或递加)到场的情形,默许的B-Tree索引其实不幻想。这是由于假如索引列的值具有严厉按次时,跟着数据行的拔出,索引树的层级增加很快。搜刮索激发生的I/O读写次数和索引树的层级数成反比,也就是说,一棵具有5个层级的B-Tree索引,在终极读取到索引数据时最多大概产生多达5次I/O操纵。因此,削减索引的层级数是索引功能调剂的一个主要办法。  假如索引列的数据以严厉的有序的体例拔出,那末B-Tree索引树将酿成一棵不合错误称的"歪树",如所示:

不合错误称的B-Tree索引
  而假如索引列的数据以随机值的体例拔出,我们将失掉一棵趋势对称的索引树,如所示:


对称的B-Tree索引  对照和,在中搜刮到A块必要举行5次I/O操纵,而仅必要3次I/O操纵。
  既然索引列数据从序列中猎取,其有序性没法躲避,但在创建索引时,Oracle同意对索引列的值举行反向,即事后对列值举行比特位的反向,如1000,10001,10011,10111,1100经由反向后的值将是0001,1001,1101,0011。明显经由位反向处置的有序数据变得对照随机了,如许所失掉的索引树就对照对称,从而进步表的查询功能。
  但反向键索引也有它范围性:假如在WHERE语句中,必要对索引列的值举行局限性的搜刮,如BETWEEN、<、>等,其反向键索引没法利用,此时,Oracle将实行全表扫描;只要对反向键索引列举行和=的对照操纵时,其反向键索引才会失掉利用。
  2.2反向键索引的SQL语句
  回到我们下面的例子,因为T_ORDER和T_ORDER_ITEM的主键值来历于序列,主键值是有严厉按次的,以是我们应当摒弃默许的Oracle所供应的索引,而接纳显式为主键指定一个反向键索引的体例。
  ORDER_ID为T_ORDER表的主键,主键名为PK_ORDER,我们为ORDER_ID列上创建一个反向键索引IDX_ORDER_ID,并使PK_ORDER_ID利用这个索引,其SQL语句以下:
createtableT_ORDER(
 ORDER_IDNUMBER(10)notnull,
 CLIENTVARCHAR2(60),
 ADDRESSVARCHAR2(100),
 ORDER_DATECHAR(8));
createuniqueindexIDX_ORDER_IDonT_ORDER(ORDER_IDASC)reverse;altertableT_ORDERaddconstraintPK_ORDERprimarykey(ORDER_ID)usingindexIDX_ORDER_ID;
  要包管创立IDX_ORDER_ID的SQL语句在创立PK_ORDER主键的SQL语句之前,由于主键必要援用到这个反向键索引。
  因为主键列的数据是独一的,以是为IDX_ORDER_ID加上unique限制,使其成为独一型的索引。
  2.3PowerdDesigner怎样操纵
  1)起首,必要为ORDER_ID列创建一个反向键索引。翻开T_ORDER的TableProperties的窗口,切换到Indexes页,新建一个名为IDX_ORDER_ID的索引。填写完索引的称号后,双击这个索引,弹出IndexProperties窗口,在这个窗口的Columns当选择ORDER_ID列。然后,切换到Options页,按的体例将其设置为反向键索引。


设置反向键索引  2)显式指定主键PK_ORDER利用这个索引。在TableProperties窗口中切换到Keys页,默许情形下,PowerDesigner为T_ORDER所指定的主键名为Key1,我们将其改名为PK_ORDER,双击这个主键,弹出KeyProperties窗口,切换到Options页,按的体例为PK_ORDER指定IDX_ORDER_ID。
为主键指定特定的索引  不成否定PowerDesigner的确是今朝业界最壮大易用的数据库计划工具,但很遗憾,当我们为表主键指定一个索引时,其发生的语句在按次上有成绩:即创立主键的语句位于创立索引语句之前:createtableT_ORDER(…);altertableT_ORDERaddconstraintPK_T_ORDERprimarykey(ORDER_ID)usingindexIDX_ORDER_ID;createuniqueindexIDX_ORDER_IDonT_ORDER(ORDER_IDASC)reverse;  我们能够经由过程对PowerDesigner天生SQL语句的设置举行调剂,师长教师成创立表和索引的SQL语句,再创立为表增加主键和外键的SQL语句来到达曲线救国的目标,请看下一步。  3)经由过程菜单Database->GenerateDatabase...修改DatabaseConfiguration窗口,切换到Keys&Indexes页,按设置:

设置天生键和索引SQL的选项  这里,我们将PrimaryKeys和Foreignkeys的选项都作废,而将Indexes勾选,以到达只天生表的索引SQL语句的目标。  点击"断定"后,天生创立数据库表及其索引的SQL语句,运转该SQL创立数据库后,再按0设置天生为表增加主键和外键的SQL语句:

0天生创立表主键和外键的SQL语句  除此设置外,还必需切换到Tables&Views页下,作废一切选项,制止从头天生创立表的语句。  3、将子表的外键列的索引改成紧缩型  3.1紧缩型索引的道理和用处  在后面的例子中,因为一条定单会对应多条定单条目,以是T_ORDER_ITEM的ORDER_ID字段总会呈现反复的值,如:ITEM_IDORDER_IDITEMCOUNT
11001011
21001042
31002013
42003012
52004011
62002053  在ORDER_ID列上创立一个一般未紧缩的B-Tree索引,则索引数据的物理上的存储情势以下:

1未举行紧缩的索引存储  ORDER_ID的反复值在索引块中反复呈现,如许不仅增添了存储空间的需求,并且由于查询时必要读取更多的索引数据块,以是查询功能也会下降=。让我们来看一下经由紧缩后索引数据的存储体例:
2举行紧缩的索引存储  紧缩型的索引打消了反复的索引值,将不异索引列值所联系关系的ROWID存储在一同。如许,不仅节俭了存储空间,查询效力也进步了,真可谓分身齐美了。  工具T_ORDER和T_ORDER_ITEM如许的主从表举行查询时,一样平常情形下,我们都必需经由过程外键查询出子表一切联系关系的纪录,以是在子表的外键上创建紧缩型的索引长短常合适的。  3.2紧缩型索引的SQL语句  创立紧缩型索引的SQL语句十分复杂,在T_ORDER_ITEM的ORDER_ID上创立紧缩型索引的SQL以下所示:createindexIDX_ORDER_ITEM_ORDER_IDonT_ORDER_ITEM(ORDER_IDASC)compress;  必要在创立索引的语句后附上compress关头字就能够了。  3.3PowerDesigner怎样创立紧缩型索引  1)翻开T_ORDER_ITEM表的TableProperties的窗口,切换到Indexes页,为ORDER_ID列创立一个名为IDX_ORDER_ITEM_ORDER_ID的索引。  2)双击IDX_ORDER_ITEM_ORDER_ID弹出IndexProperties窗口,切换到Options页,按3将索引设置为紧缩型:

3将索引指定为紧缩型  4、创建满意需求的复合键索引  计划职员但愿经由过程T_ORDER表上的IDX_ORDER_COMPOSITE复合索引满意以下两种组合前提的查询:  ・CLIENT+ORDER_DATE+IS_SHIPPED  ・ORDER_DATE+IS_SHIPPED  为便利论述,我们专程将IDX_ORDER_COMPOSITE的创立SQL语句再次列出:createindexIDX_ORDER_COMPOSITEonT_ORDER(CLIENTASC,ORDER_DATEASC,IS_SHIPPEDASC);  现实上,在CLIENT+ORDER_DATE+IS_SHIPPED三列上所实行的复合前提查询会使用到这个索引,而在ORDER_DATE+IS_SHIPPED列上所实行的复合查询不会利用这个索引,因此将招致一个全表扫描的操纵。  能够用很多工具来懂得查询语句的实行企图,经由过程SETAUTOTRACEON来查询以上两个复合查询的实行企图:  翻开SQL/Plus,输出以下的语句:SQL>setautotraceon
SQL>select*fromt_orderwhereCLIENT=1andORDER_DATE=1andIS_SHIPPED=1;  剖析失掉的实行企图为:SELECTSTATEMENTOptimizer=CHOOSETABLEACCESS(BYINDEXROWID)OFT_ORDERINDEX(RANGESCAN)OFIDX_ORDER_COMPOSITE(NON-UNIQUE)  可见Oracle先使用IDX_ORDER_COMPOSITE失掉满意前提的纪录ROWID,再经由过程ROWID前往纪录。  而上面查询语句:SQL>select*fromt_orderwhereORDER_DATE=1andIS_SHIPPED=1  的实行企图则为:SELECTSTATEMENTOptimizer=CHOOSETABLEACCESS(FULL)OFT_ORDER  很分明,Oracle在T_ORDER表上实行了一个全表扫描的操纵,没有效到IDX_ORDER_COMPOSITE索引。  对复合列索引,我们得出这个结论:  假定在COL_1,COL_2,…,COL_n这些列上创建了一个复合索引:createindexIDX_COMPOSITEonTABLE1
{
COL_1,
COL_2,
…,
COL_n
}  则只要WHERE语句上包括COL_1(复合索引的第一个字段)的查询才会利用这个复合索引,而未包括COL_1的查询则不会利用这个复合索引。  回到我们的例子,怎样创建满意CLIENT+ORDER_DATE+IS_SHIPPED和ORDER_DATE+IS_SHIPPED两种查询的索引呢?  思索到IS_SHIPPED列基数很小,只要两个大概的值:0,1。在这类情形下,有两种计划:第一,分离为CLIENT+ORDER_DATE+IS_SHIPPED和ORDER_DATE+IS_SHIPPED创建一个复合索引;第二,分离在CLIENT和ORDER_DATE列上创建一个索引,而IS_SHIPEED列不创建索引。  第一种计划的查询效力最快,但由于CLIENT和ORDER_DATE在索引中会反复呈现两次,占用较年夜的存储空间。第二种计划CLIENT和ORDER_DATE不会在索引存储呈现两次,较为节俭空间,查询效力比之于第一种计划会稍低一些,但影响不年夜。  我们接纳第二种计划为CLIENT和ORDER_DATE分离创立索引IDX_CLIENT和IDX_ORDER_DATE,组合查询前提为CLIENT+ORDER_DATE+IS_SHIPPED时的实行企图为:SELECTSTATEMENTOptimizer=CHOOSETABLEACCESS(BYINDEXROWID)OFT_ORDERAND-EQUALINDEX(RANGESCAN)OFIDX_CLIENT(NON-UNIQUE)INDEX(RANGESCAN)OFIDX_ORDER_DATE(NON-UNIQUE)  而组合前提为ORDER_DATE+IS_SHIPPED时的实行企图为:SELECTSTATEMENTOptimizer=CHOOSETABLEACCESS(BYINDEXROWID)OFT_ORDERINDEX(RANGESCAN)OFIDX_ORDER_DATE(NON-UNIQUE)  经由过程如许的改革,我们失掉了一个满意两种组合查询的实行企图。  总结  贯串本文的定单主从表实例布局上很复杂,可是其粗拙的计划包括了很多成绩,这也是很多对Oracle物理存储布局没有很好了解的数据库计划师简单无视的中央。  在一样平常情形下,如许的计划其实不会招致严峻体系的功能成绩,可是不断改进是每位优异软件计划师的品德,别的,关于计划师,必定要分明如许一条纪律:关于等质的功能提拔,在编码层面常常必要比计划层面支付更多的艰苦。  在Oracle中进步数据库的功能必要思索的成绩,注重的误区还良多,本文涵盖是一些最多见的成绩。上面,我们将进步数据库操纵功能办法及一些误区作个小结:  ・关于年夜表,能够思索创立分区表,分区表有局限分区、散列分区、列表分区和散列分区几种,经由过程它能够到达化年夜表为小表的目标。  ・思索过量的数据冗余,如一个营业表有一个审批形态,审批必要经由多步,每步对应审批表的一笔记录,最初审批的那笔记录决意了营业的形态。我们年夜可在营业表中寄存一个审批形态的标记,以作废每次必要经由过程联系关系审批表猎取营业审批形态的庞大的联系关系表查询。  ・不要做太多的联系关系表查询,一些几近不产生数据变化的表码表,如性别,学历,婚姻形态等表码表,能够思索在使用程序启动时一次性地下载到使用程序的内存中缓存起来,在从数据库猎取了局集后,再由程序使用这些缓存的表码表数据来翻译这些表码字段,而不要在数据库中经由过程表间的联系关系查询体例来翻译这些字段。  ・常看到一些令我瞠目标计划:在必要举行频仍DML(INSERT,UPDATE,DELETE)操纵的表的某些基数低的字段(如性别,婚姻形态)上创立位图索引。位图索引是好器材,但它是有利用局限的,在OLTP体系中,必要举行频仍DML操纵的表中不该该呈现位图索引,位图索引只合用于几近不举行DML操纵,只举行查询的DSS体系中。别的,聚簇和索引构造表也都更合适DSS体系,而非O一些典型的RDBMS功能并不总是在DBaaS系统中可用。例如MySQL学习教程,WindowsAzureSQLDatabase(以前的SQLAzure)是微软的DBaaS产品,提供了一个类似于SQLServer的数据库平台。
山那边是海 该用户已被删除
沙发
发表于 2015-1-19 16:12:51 | 只看该作者
varchar(max)\\\\nvarchar(max)类型的引入大大的提高了编程的效率,可以使用字符串函数对CLOB类型进行操作,这是一个亮点。
小魔女 该用户已被删除
板凳
发表于 2015-1-28 08:08:10 | 只看该作者
我个人认为就是孜孜不懈的学习
小妖女 该用户已被删除
地板
发表于 2015-2-5 20:02:01 | 只看该作者
至于淘汰的问题,只能说在你的项目周期之内,微软应该都不会倒闭。
变相怪杰 该用户已被删除
5#
发表于 2015-2-13 10:41:43 | 只看该作者
记得在最开始使用2k的时候就要用到这个功能,可惜2k没有,现在有了作解决方案的朋友会很高兴吧。
爱飞 该用户已被删除
6#
发表于 2015-3-3 20:34:25 | 只看该作者
比如日志传送、比如集群。。。
愤怒的大鸟 该用户已被删除
7#
 楼主| 发表于 2015-3-11 13:30:59 | 只看该作者
作了些试验,发现使用CLR的存储过程或函数在达到一定的阀值的时候,系统性能会呈指数级下滑!这是非常危险的!只使用几个可能没有问题,当一旦大规模使用会造成严重的系统性能问题!
活着的死人 该用户已被删除
8#
发表于 2015-3-18 20:55:31 | 只看该作者
对于微软系列的东西除了一遍遍尝试还真没有太好的办法
再见西城 该用户已被删除
9#
发表于 2015-3-26 14:42:06 | 只看该作者
如果我们从集合论(关系代数)的角度来看,一张数据库的表就是一组数据元的关系,而每个SQL语句会改变一种或数种关系,从而产生出新的数据元的关系(即产生新的表)。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-5-16 05:53

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表