÷ƒ’Ą;č TeX output 1995.03.20:1132‹’’’’ —ßż żGš‘ņs ŸöĄ‰ff©ōķŸ /„ /ffŸś×‘ó& ptmr7t¹In–€óLméV ptmri7tŗPrš”Goceedings“1‘’B1th“International“Confer˜ence“on“Data“Engineering¹,“pages“201{210,“T‘’LŠaipei,“March“1995ŽŽ’©(!„ /ffŽžff‰ff©ōķŽŽŽŽŽ šep žĶʍŸ‹ĢŹ‘R óB®vöG® ptmb7t¼Prairie:‘ĮA–QėRule“Speci cation“FrameworkŽŸ’˜’éfor–QėQuery“OptimizersŸłŗÆó!",š cmsy10ĀŽŽ“ŸłŗÆyŽŽŽŸ’‹ĄBó& ptmr7tÉDinesh–Das‘NEDon“BatoryŽŽ¤’˜wDepartment–of“Computer“SciencesŽŽ”’™yńThe–University“of“T‘’(łexas“at“AustinŽŽ”’Ŗ°™Austin,–T‘’(łexas“78712{1ŽV188ŽŽ”’£ˆ6ĀfÉddas,batoryĀgÉ@cs.utexas.eduŽŽŽŽŽŽ ć2:‘ņs  ž0ĶĘņ! TeXDict begin /box{newpath 2 copy moveto 3 copy pop exch lineto 4 copy pop pop lineto 4 copy exch pop exch pop lineto closepath } bind def /min{ 2 copy gt { exch } if pop } bind def/max{ 2 copy lt { exch } if pop } bind def/roundedbox{/radius exch store 3 2 roll 2 copy min radius sub /miny exch store max radius add /maxy exch store 2 copy min radius sub /minx exch store max radius add /maxx exch store newpath minx radius add miny moveto maxx miny maxx maxy radius arcto maxx maxy minx maxy radius arcto minx maxy minx miny radius arcto minx miny maxx miny radius arcto 16 {pop} repeat closepath }bind def /rectcartouche{box gsave .95 setgray fill grestore 1 setlinewidth stroke }bind def /cartouche{roundedbox gsave .95 setgray fill grestore 1 setlinewidth stroke }bind def end ļ+header=/u/ddas/tex/pstricks/ps/pstricks.proļ+header=/u/ddas/tex/pstricks/ps/pst-node.proņ! TeXDict begin /box{newpath 2 copy moveto 3 copy pop exch lineto 4 copy pop pop lineto 4 copy exch pop exch pop lineto closepath } bind def /min{ 2 copy gt { exch } if pop } bind def/max{ 2 copy lt { exch } if pop } bind def/roundedbox{/radius exch store 3 2 roll 2 copy min radius sub /miny exch store max radius add /maxy exch store 2 copy min radius sub /minx exch store max radius add /maxx exch store newpath minx radius add miny moveto maxx miny maxx maxy radius arcto maxx maxy minx maxy radius arcto minx maxy minx miny radius arcto minx miny maxx miny radius arcto 16 {pop} repeat closepath }bind def /rectcartouche{box gsave .95 setgray fill grestore 1 setlinewidth stroke }bind def /cartouche{roundedbox gsave .95 setgray fill grestore 1 setlinewidth stroke }bind def end Ÿ ó.B®vöff ptmb7tŁAbstractŽŸiŗFrš”Gom–0|our“experience,‘\›curr˜ent“rule-based“query“optimizersŽ¤ do–æOnot“pr”Govide“a“very“intuitive“and“well-de ned“frameworkŽ”to–¾Pde ne“rules“and“actions.‘gT‘’o“r”Gemedy“this“situation,‘ äweŽ”prš”Gopose–ū¬an“extensible“and“structur˜ed“algebraic“frameworkŽ”called–ŌĀPrairie“for“specifying“rules.‘R½Prairie“facilitates“rule-Ž”writing–ź·by“enabling“a“user“to“write“rules“and“actions“mor”GeŽ”‘’uõquickly‘’s8,‘$Xcorr”Gectly– nand“in“an“easy-to-understand“and“easy-to-Ž”debug‘€manner‘žć×.Ž© jT‘ Query– £optimizers“consist“of“thrš”Gee“major“parts:‘gæa“sear˜chŽ”“żspace,‘8Ia–&[cost“model“and“a“searš”Gch“strategy‘’s8.‘6—The“appr˜oach“weŽ”ģStake–o«is“only“to“develop“the“algebra“which“de nes“the“sear”GchŽ”space–ØUand“the“cost“model“and“use“the“V‘žć×olcano“optimizerĢŠ-Ž”generator–$Eas“our“searš”Gch“engine.‘AGUsing“Prairie“as“a“fr˜ont-Ž”end,‘[we–dItranslate“Prairie“rules“to“V‘žć×olcano“to“validate“ourŽ”claim–€that“Prairie“makes“it“easier“to“write“rules.Ž¦‘ ‡ØW‘’e–describe“our“algebra“and“prš”Gesent“experimental“r˜esultsŽ”‘’Qwhich–īĻshow“that“using“a“high-level“framework“like“Prairie“toŽ”‘’]“design–łMlar”Gge-scale“optimizers“does“not“sacri ce“eciency‘’s8.ŽŸ#ō½Ł1Ž‘™™Intr½«oductionŽŸi‘’%C¹Query–Źuoptimization“[8]“is“a“fundamental“part“of“database“sys-Ž”õwtems.‘QŽIt–wAis“the“process“of“generating“an“ecient“access“planŽ”for–żÄa“database“query–’Y .‘ĶÄInformally“,‘5an–żÄaccess“plan“is“an“exe-Ž”cution–!œstrategy“for“a“query;‘rjit“is“the“sequence“of“low-levelŽ”database–±retrieval“operations“that,›#]when“executed,˜produceŽ”the–ćdatabase“records“that“satisfy“the“query‘’Y .‘}ŹThere“are“threeŽ”basic–%aspects“that“de ne“and“in uence“query“optimization:Ž”the–€search“space,“the“cost“model,“and“the“search“strategy‘’Y .Ž¦‘ ņtThe–tĮŗsear”Gch“space“¹is“the“set“of“logically“equivalent“accessŽ”plans–`„that“can“be“used“to“evaluate“a“query‘’Y .‘öAll“plans“in“aŽŸ 8„‰ff^ŚYŸ @‘ Ÿż-:ó$q”% cmsy6ĻŽŽ‘fhó)& ptmr7tŌThis–‡research“was“supported“in“part“by“grants“from“The“University“ofŽ¤ €T‘’p¦exas–®Applied“Research“Laboratories,–Ł‚SchlumberŪ&ger®,“and–®Digital“Equip-Ž”ment‘Corporation.ŽŸ × ‘ t£Ÿż-:ĻyŽŽ‘fhŌAn–·Ļexpanded“version“of“this“paper“is“available“as“T‘’p¦echnical“Report“TRŽ”94{16–by“anonymous“ftp“from“ó,Ė»X« pcrr7t×ftp.cs.utexas.eduŌ.ŽŽŽ ž:Ķʍ’ö+r¹query'‘’s8s–“Csearch“space“return“the“same“result;‘œåhowever™Ÿ,‘˜someŽ¤ ’õ÷¹plans–Uare“more“ecient“than“others.‘F)The“ŗcost“model“¹assignsŽ”’öGa–mšcost“to“each“plan“in“the“search“space.‘NVThe“cost“of“a“plan“isŽ”’õ×ęan–:©estimate“of“the“resources“used“when“the“plan“is“executed;Ž”’õø”the– Ŗlower“the“cost,‘3»the“better“the“plan.‘4±The“ŗsear”Gch“strategy“¹isŽ”’ö+ra–Ӄspeci cation“of“which“plans“in“the“search“space“are“to“beŽ”’ö+rexamined.Ž”’+sT¦graditionally‘’Y ,‘‘#query–µoptimizers“have“been“built“as“mono-Ž”’ö+rlithic–ģYsubsystems“of“a“DBMS.“This“simply“re ects“the“factŽ”’õĆDthat–)‰traditional“database“systems“are“themselves“monolithic:Ž”’öthe–`algorithms“used“for“storing“and“retrieving“data“are“hard-Ž”’ö+rwired–œand“are“rather“dicult“to“change.‘-KThe“need“to“haveŽ”’õß extensible–@™database“systems,‘MGand“in“turn“extensible“optimiz-Ž”’ö+rers,‘[Ÿhas–/³long“been“recognized“in“systems“like“Genesis“[1],Ž”’õ¤rEXODUS‘Ų[9],–&^Starburst›õ[10],“and˜Postgres˜[12].‘/Rule-basedŽ”’ö!query–wĖoptimizers“are“among“the“major“conceptual“advancesŽ”’ö+rthat–ƒ¤have“been“proposed“to“deal“with“query“optimizer“ex-Ž”’ö+rtensibility›Ų[6,–Ŗ®7,“9,“10].‘Ü’The˜extensibility˜translates˜into˜theŽ”’ö+rability–Ąwto“incorporate“new“operators,–Š•algorithms,“cost‘Ąwmod-Ž”’ö+rels,‘A·or–łsearch“strategies“without“changing“the“optimizationŽ”’ö+ralgorithm.Ž”’+sIn–¦this“paper™Ÿ,‘Ƥwe“describe“an“algebraic“framework“calledŽ”’öŗPrairie–\Ģ¹for“specifying“rules“in“a“rule-based“query“optimizer‘’s8.Ž”’ö+rPrairie–Sis“similar“to“other“rule“speci cation“languages“likeŽ”’ö+rStarburst–å‡[10]“and“V‘žµĒolcano“[7],›žéand“indeed,˜we“have“basedŽ”’ö+rour–Żwork“on“V‘žµĒolcano“to“capture“most“of“the“advantages“ofŽ”’õ½erule-based–$Ŗoptimizers.‘6However™Ÿ,‘6ļPrairie“attempts“to“provideŽ”’õ¼÷some–$Nkey“features“that,›6„we“have“found,˜simplify“the“e ort“inŽ”’ö+rwriting‘€rules:ŽŸ2:’ż«t1.ŽŽŽ’ +tA‘4­framework–4Üin“which“users“can“de ne“a“query“opti-Ž”’ +tmizer–œfconcisely“in“terms“of“a“well-de ned“set“of“operĢŠ-Ž”’ +tators–¦and“algorithms.‘Ę°ŗAll“¹operators“and“algorithms“areŽ”’ +tconsidered– rst-class“objects,–“„i.e.,“ŗany–¹of“them“can“oc-Ž”’ +tcur–ķSin“any“rule,‘ ©and“ŗonly“¹these“operators“and“algorithmsŽ”’ +tcan–œappear“in“rules.‘'KThis“scheme“eliminates“the“needŽ”’ +tfor–>ųspecial“classes“of“operators“and“algorithms,‘Kśsuch“asŽ”’ +tenforcers–ŒŖin“V‘žµĒolcano“and“glue“in“Starburst,‘Õthat“signif-Ž”’ +ticantly–€complicate“rule“speci cation.ŽŽŽŽŽŽŽŒ‹* —ßż żGš šep żˆš‘łó ¹2.ŽŽŽ‘s A‘‰framework–„in“which“users“can“de ne“a“list“of“properĢŠ-Ž¤ ‘s ties–Öto“characterize“the“expressions“generated“in“the“op-Ž”‘s timization–IŃprocess.‘BiAgain,‘TØthe“goal“here“is“to“allow“theŽ”‘s user–’to“treat“ŗall“¹properties“as“having“equal“status.‘ŠÖThisŽ”‘s is–œdi erent“from“V‘žµĒolcano“where“the“user“must“classifyŽ”‘s properties–Ś±as“logical,–1^physical,“or‘Ś±operator/algorithmŽ”‘s arŃšguments.Ž©ž.‘łó 3.ŽŽŽ‘s A‘]framework–in“which“users“can“specify“mappingŽ”‘s functions–ą®between“properties“concomitantly“with“theŽ”‘s corresponding–Sxrules.‘ĪßThis“contrasts“with“existing“ap-Ž”‘s proaches–)Lin“which“mappings“between“properties“areŽ”‘s fragmented– Łinto“multiple“functions“and“at“logically“dif-Ž”‘s ferent–xCplaces“than“the“corresponding“rules.‘=AResearchŽ”‘s into– ¼rule-based“optimizers“has“revealed“that“property-Ž”‘s mapping–C¹functions“are“a“major“source“of“user“e ort,‘OČsoŽ”‘s this–€is“an“important“goal.Ž¦‘łó 4.ŽŽŽ‘s The–&Yformat“(Prairie)“in“which“users“can“cleanly“specifyŽ”‘s rules–ŁFis“not“necessarily“the“same“format“needed“for“gen-Ž”‘s erating–1 ecient“optimizers.‘g“Thus,‘]Kthere“is“a“need“forŽ”‘s a–’pre-processor“(written“by“us)“that“translates“betweenŽ”‘s these–€competing“representations.ŽŸž/‘üs Prairie–A@strives“for“uniformity“in“dealing“with“issues“thatŽ”‘ņBhave–WNbeen“a“source“of“most“user“e ort“and“potential“user“erĢŠ-Ž”‘ńšbe–ü4processed“eciently‘’Y .‘(ŠExperimental“results“to“support“thisŽ”‘ńŒųclaim–Į are“given“in“Section“4,‘ē>where“we“compare“implementa-Ž”‘ńņtions–žof“the“T‘’LŠexas“Instruments“Open“OODB‘ćquery“optimizerŽ”‘ņs using–‚both“Prairie“and“V‘žµĒolcano.‘,’W‘’37e“conclude“with“a“sum-Ž”‘ņs mary–€and“related“research.ŽŸ"†Å‘ńõ"Ł2Ž‘Ž»Prairie:‘€QA‘÷language–for“rule“speci -ŽŸ‘ ¤cationŽŸ˜Ź‘ņs ¹The–×Qbasic“concepts“and“de nitions“that“underlie“the“PrairieŽ”‘ńƀmodel–īNare“presented“in“this“section.‘#čThe“goal“is“to“lay“a“foun-Ž”‘ń÷dation–for“reasoning“about“query“optimization“algebraically;Ž”‘ņs this–”įis“necessary“for“our“subsequent“discussion“about“trans-Ž”‘ņs lating–€Prairie“speci cations“to“those“of“V‘žµĒolcano.ŽŸh ‘ņs ó/B®vö ptmb7tŚ2.1Ž‘ s Notation–and“assumptionsŽŸJ‘ņM¼ó0B®vö ptmb7tŪStoršŃšed–a Files“and“Str˜eams.‘ ¹A‘a le“is“ŗstor”Ged‘–ɹif“its“tuples“re-Ž”‘ņs side–„žon“disk.‘crIn“the“case“of“relational“databases,‘†=stored“ lesŽ”‘ńų6are–sometimes“called“ŗbase“r”Gelations¹;‘< we“will“denote“them“byŽ”‘ńŲ-ó  b> cmmi10µR‘>¹or–’wµRŸ’ó 0e—rcmmi7“iŽ‘TL¹.‘) In“object-oriented“schemas,‘-stored“ les“are“ŗclasses¹;Ž”‘ņs we–Øwill“denote“them“by“ŗCŽ‘ ū°¹or“ŗCŽ‘ S˜Ÿ’“iŽ‘ §ä¹.‘ĢĄHenceforth,‘²whenever“weŽ”‘ņ-Žrefer–FTto“a“stored“ le,‘QŻwe“mean“a“relation“or“a“class;‘YŽwhen“theŽ”‘ńŗdistinction–ęƒis“unimportant,‘6we“will“use“µF‘J¹or“µFŸ’“iŽ‘TL¹.‘!OA‘ę\ŗstr”Geam“¹is“aŽŽŽ żˆš’õż¢sequence–Yśof“tuples“and“is“the“result“of“a“computation“on“oneŽ¤ ’õcńor–Ślmore“streams“or“stored“ les;‘žtuples“of“streams“are“returnedŽ”’ö+rone––Sat“a“time,‘›čtypically“on“demand.‘—qStreams“can“be“ŗnamed¹,Ž”’ö+rdenoted–€by“µSŸ’“iŽ‘TL¹,“or“ŗunnamed¹.ŽŸš’ö+rŪDatabase–ˆtOperations.‘ ¹An“ŗoperation“¹is“a“computation“onŽ”’ö+rone–»£or“more“streams“or“stored“ les.‘`There“are“two“types“ofŽ”’ö }database–cŃoperations“in“Prairie:‘Faabstract“(or“implementation-Ž”’ö Īunspeci ed)–w,operators“and“concrete“algorithms.‘Q‡Each“is“de-Ž”’ö+rtailed‘€below‘’Y .Ž©TG’ +tŪOperators.ŽŽ’=Œ›¹Abstract–e(or“conceptual)“ŗoperators“¹spec-Ž”’ +tify–Śecomputations“on“streams“or“stored“ les;‘˜theyŽ”’ +tare–Žhdenoted“by“all“capital“letters“(e.g.,‘JOIN).Ž”’ +tOperators–3Żhave“two“types“of“parameters:‘¼1essen-Ž”’ +ttial–Źand“additional.‘ åÖŗEssential“parameters“¹areŽ”’ +tthe–zŅstream“or“ le“inputs“to“an“operator;‘xthe“primary“inputs“to“be“processed“by“anŽ”’ +toperator‘’s8.‘łQŗAdditional–¶óparameters“¹are“\ ne-grain"Ž”’ +tquali cations–9Ÿof“an“operator;‘–ntheir“purpose“is“toŽ”’ +tdescribe–h+an“operator“in“more“detail“than“essentialŽ”’ +tparameters.ŽŸāŚ’ +tŪAlgorithms.ŽŽ’A’ŹŗAlgorithms– &?¹are“concrete“implemen-Ž”’ +ttations–„Aof“conceptual“operators;‘athey“will“beŽ”’ +trepresented–…in“lower“case“with“the“ rst“letterŽ”’ +tcapitalized‘$(e.g.,‘ł-Nested‘™˜‰ffŽ‘™šloops).‘ćAlgorithmsŽ”’ +thave–&¶at“least“the“same“essential“and“additionalŽ”’ +tparameters–ž„as“the“conceptual“operators“that“theyŽ”’ +timplement.Ÿü^’óŁ“ Rcmr7±1ŽŽ‘‰e¹Furthermore,›·ˆthere–Ócan“be,˜andŽ”’ +tusually–COare,‘“#several“algorithms“for“a“particularŽ”’ +toperator‘’s8.Ž¦’ö+rT‘’LŠable–C1“lists“some“operators“and“algorithms“implementingŽ”’ö+rthem–€together“with“their“additional“parameters.ŽŸš’ö+rŪOperator–ĀŌT‘’BrŃšees.‘ ¹An“ŗoperator“tr”Gee“¹is“a“rooted“tree“whoseŽ”’ö+rnon-leaf,–˜?or›`3ŗinterior¹,“nodes˜are˜database˜operations˜(operĢŠ-Ž”’ö+rators–<‹or“algorithms)“and“whose“leaf“nodes“are“stored“ les.Ž”’ö+rThe–ķ’children“of“an“interior“node“in“an“operator“tree“are“theŽ”’ö+ressential–#2parameters“(i.e.,‘Kžthe“stream“or“ le“parameters)“ofŽ”’ö+rthe–$Ŗnode.‘BuAdditional“parameters“are“implicitly“attached“toŽ”’õ”Ōeach– Énode.‘.fAlgebraically‘’Y ,‘$”operator“trees“are“compositions“ofŽ”’õ,database–ü¤operations;‘(nthus,‘źwe“will“also“call“operator“trees“ŗex-Ž”’ö+rpr”Gessions¹;–€both“terms“will“be“used“interchangeably‘’Y .ŽŸTG’ö+ró9 $S ptmrc7täExample‘€1.ŽŽ’=uܹA‘Ō·simple–ŌĶexpression“and“its“operator“treeŽ”’ö+rrepresentation–ōvare“shown“in“Figure“1(a).‘±ŁRelations“µRŸ’±1Ž‘pé¹andŽ”’ö+rµRŸ’±2Ž‘Ēh¹are–Jõ rst“RET¦grieved,›}²then“JOINed,˜and“ nally“SOR‘’fgT‘’LŠedŽ”’ö+rresulting–Ēģin“a“stream“sorted“on“a“speci c“attribute.‘The“ gureŽ”’ö+rshows–Äonly“the“essential“parameters“of“the“various“operators,Ž”’ö+rnot–€the“additional“parameters.‘n}Wó—³īĶ msam10ÅŽ’ö+rŸœR‰ff^ŚYŸ J=‘ ;ĮŸż-:ó ¹AaØcmr6Ė1ŽŽŽ‘fhŌAlgorithms–"„may“have“ó7LméV ptmri7tātuning“parameters“Ōwhich“are“not“parameters“ofŽŸ €the–operators“they“implement.ŽŽŽŽŽŽŒ‹e —ßż żGš šep żżŚ…ŸöŸ¾t¦‘ņs ŸÜgщ€Éį¤™˜¤fh„ff‘Ÿż™˜ó8B®vö ptmb7tćOperator‘õ&”„ffŽ‘;ĄDescription‘Ÿfh„ffŽ’ŌŽAdditional‘ĄParameters‘Ÿfh„ffŽ’Ņx÷AlgorithmŽŽ’c{Ÿfh„ffŽŽŸęh‰€Éį”Ÿfh„ffŸÅ°‘ó3& ptmr7tŽJOIN(“SŸó†›Zcmr5°1Ž–ē Ž,‘Ą“SŸ°2Ž“Ž)ŽŽŽ‘4óH„ffŽŸJŽ‘;ĄJoin–Ąstreams““SŸ°1Ž‘ē Ž,““SŸ°2ŽŽŽŽ‘{n(Ÿfh„ffŽ’ŌŽŽtuplek„‰ff›Ž‘…order‘*óŚŸfh„ffŽ’Ņx÷Nestedk„‰ff›Ž‘…loops(“SŸ°1Ž–ē Ž,‘Ą“SŸ°2Ž“Ž)ŽŽ’c{Ÿfh„ffŽŽ¤ĢĪ’Ģx÷„ffKPźŽŽ©32Ÿfh„ff‘4óH„ffŽ‘{n(Ÿfh„ffŽ’ŌŽjoink„‰ff›Ž‘…predicate‘#,žŸfh„ffŽ’Ņx÷MerßĮgek„‰ff›Ž‘…join(“SŸ°1Ž–ē Ž,‘Ą“SŸ°2Ž“Ž)ŽŽ’c{Ÿfh„ffŽŽ”‰ffÉįŸ^•ŸŽ•„ =*ffŸMƒ‘RET(“F‘ŽŽ)ŽŽŽ‘4óH„ =*ffŽŸĮF‘;ĄRetrieve–Ą le““FŽŽŽ‘{n(ŸŽ•„ =*ffŽ’ŌŽŽtuplek„‰ff›Ž‘…order‘*óŚŸŽ•„ =*ffŽŸ”k’Ņx÷Filek„‰ff›Ž‘…scan(“F‘ŽŽ)ŽŽŽŽ’c{ŸŽ•„ =*ffŽŽŸx-Ÿfh„ff‘4óH„ffŽ‘{n(Ÿfh„ffŽ’ŌŽselectionk„‰ff›Ž‘…predicate‘.ŪŸfh„ffŽŸžs3’Ģx÷„ffJź„ŽŽŽŽŽ’c{Ÿfh„ffŽŽŸ&hŸfh„&hff‘4óH„&hffŽ‘{n(Ÿfh„&hffŽ’ŌŽprojectedk„‰ff›Ž‘…attributes‘Ÿ?Ÿfh„&hffŽŸ’‰’Ņx÷Indexk„‰ff›Ž‘…scan(“F‘ŽŽ)ŽŽŽŽ’c{Ÿfh„&hffŽŽ”‰ffÉįŸ™˜Ÿfh„ffŸÅ°‘SOR”{T(“SŸ°1Ž‘ē Ž)ŽŽŽ‘4óH„ffŽŸJ­‘;ĄSort–Ąstream““SŸ°1ŽŽŽŽ‘{n(Ÿfh„ffŽŸC’ŌŽŽtuplek„‰ff›Ž‘…orderŽŽŽ’Ģ‘Ÿfh„ffŽ’Ņx÷MerßĮgek„‰ff›Ž‘…sort(“SŸ°1Ž‘ē Ž)ŽŽ’c{Ÿfh„ffŽŽ”’Ģx÷„ffKPźŽŽ¦Ÿfh„ff‘4óH„ffŽ‘{n(Ÿfh„ffŽ’Ģ‘Ÿfh„ffŽ’Ņx÷Null(“SŸ°1Ž‘ē Ž)ŽŽ’c{Ÿfh„ffŽŽŸęh‰€ÉįŽŽŽŸ3bk‘ņs ¹T‘’LŠable–B³1:‘5ŅOperators“and“algorithms“in“a“centralized“query“optimizer“andŽŸ ‘ņs their–€additional“parametersŽŽŸĀ&p’*\ܟŌ›‰€·”¤™˜¤fh„ff‘Ÿż™˜ćPrßĮoperty‘!ģ ”„ffŽ‘IkDescription‘K3‰Ÿfh„ffŽŽŸęh‰€·””¤fh„ff‘Ÿż™˜Žjoink„‰ff›Ž‘…predicate‘æ”„ffŽ‘Ikjoin–Ąpredicate“for“JOIN“operator‘cŸfh„ffŽŽ©ĢĪ‰ff·””¤fh„ff‘Ÿż™˜selectionk„‰ff›Ž‘…predicate‘œ”„ffŽ‘Ikselection–Ąpredicate“for“RET“operator‘œŸfh„ffŽŽ¦‰ff·””Ÿfh„ffŸžŪ‘tuplek„‰ff›Ž‘…orderŽŽŽ‘BžÄ„ffŽ‘Iktuple–Ąorder“of“resulting“stream,‘LŸfh„ffŽŽŸŸfh„ff‘BžÄ„ffŽ‘IkDONTk„‰ff›Ž‘…CARE–Ąif“none‘/Ėӟfh„ffŽŽ¦‰ff·””¤fh„ff‘Ÿż™˜numk„‰ff›Ž‘…records‘ ±”„ffŽ‘Iknumber–Ąof“tuples“of“resulting“stream‘ ʟfh„ffŽŽ¦‰ff·””¤fh„ff‘Ÿż™˜tuplek„‰ff›Ž‘…size‘!72”„ffŽ‘Iksize–Ąof“individual“tuple“in“stream‘ŲŸfh„ffŽŽ¦‰ff·””¤fh„ff–Ÿż™˜projectedk„‰ff›Ž‘…attributes“”„ffŽ‘Ikprojected–Ąattributes“for“RET“operator‘Ÿfh„ffŽŽ¦‰ff·””¤fh„ff‘Ÿż™˜attributes‘"‘”„ffŽ‘Iklist–Ąof“attributes‘AŻŸfh„ffŽŽ¦‰ff·””¤fh„ff‘Ÿż™˜cost‘1Wē”„ffŽ‘Ikestimated–Ącost“of“algorithm‘!eŽŸfh„ffŽŽŸęh‰€·”ŽŽŽŸ;°”’*\ܹT‘’LŠable– a2:‘)Properties“of“nodes“in“an“operator“treeŽŽŽŽ %{ ž©ÕŸŻ×ŸĻ_A‘óS¶ŸÅyĉfféaxŸhĄ•„hĄ•ffŸŃŧŸŅy荟õU‘›˜ó5& ptmr7tąSOR³3T–@(JOIN“(RET“(óO Ś\cmmi5³RŸ€°1Ž›ē ą),“RET“(³RŸ€°2Ž˜ą)))ŽŽŽŽŽŸŻŪSŸ«Ų‘5ī$ļ{ps: tx@Dict begin tx@NodeDict begin { } /TheNodesort 16 { .5 3.39499 0.05246 false .5 12.4799 InitRnode } NewNode end endSOR³3TŽŽŽŽŽŽŸé<āŸ«Ų‘6ĮXļ{ps: tx@Dict begin tx@NodeDict begin { } /TheNodejoin 16 { .5 3.39499 0.05246 false .5 10.8299 InitRnode } NewNode end endJOINŽŽŽŽŽŽ‘0Źļżps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNodesort /TheNodejoin InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endŸōžqŸ«…‘ūG ļups: tx@Dict begin tx@NodeDict begin { } /TheNoderetr1 16 { .5 3.34 0.0 false .5 9.44495 InitRnode } NewNode end endRETŽŽŽŽŽŽŸōžqŸ«…‘ *ļups: tx@Dict begin tx@NodeDict begin { } /TheNoderetr2 16 { .5 3.34 0.0 false .5 9.44495 InitRnode } NewNode end endRETŽŽŽŽŽŽļžps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNodejoin /TheNoderetr1 InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endļžps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNodejoin /TheNoderetr2 InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endŸõU‘ūyCļups: tx@Dict begin tx@NodeDict begin { } /TheNoder1 16 { .5 3.41667 1.5 false .5 9.05264 InitRnode } NewNode end end³RŸ€°1ŽŽŽŽŽŽŽŸõU‘’ö+rŚ2.2Ž’+rPrairie–optimization“paradigmŽŸ卒ö+r¹Prairie–niadmits“two“rather“di erent“means“of“optimization:Ž”’ö+rtop-down–µ²and“bottom-up.‘õA‘µ¤top-down“query“optimizer“op-Ž”’õ×timizes–9źthe“parents“of“a“node“prior“to“optimizing“the“node“it-Ž”’õr†self.‘!PA‘ę_bottom-up–ę†optimizer“optimizes“the“children“of“a“nodeŽ”’ö+rprior–āto“optimizing“the“node.‘z…The“earliest“optimizers“(Sys-Ž”’ö+rtem–€R“[1”G1]“and“RŸü^’ó O!ā…cmsy7·Ž‘ä¹[3])“employed“the“bottom-up“approach.Ž© ĆC’3Our–hresearch“concentrates“on“a“top-down“optimization“ofŽ”’ö+roperator–?/trees.‘’W‘’37e“have“chosen“this“approach“because“weŽ”’ö+rintend–õ(to“translate“Prairie“rules“into“the“format“required“byŽ”’ö+rthe–}³V‘žµĒolcano“query“optimizer“generator“[7]“which“is“basedŽ”’ö+ron–ŗÓa“top-down“strategy‘’Y .‘šGiven“an“appropriate“search“en-Ž”’ö+rgine,‘rPrairie–éõcan“potentially“also“be“used“with“a“bottom-upŽ”’öĖoptimization–sstrategy;‘wWhowever™Ÿ,‘uœwe“will“not“discuss“this“ap-Ž”’ö+rproach–€in“this“paper‘’s8.Ž¦’’ņvIn–P“query“optimization,‘Z*there“are“certain“annotations“(suchŽ”’ö+ras–‰Žadditional“parameters)“that“are“known“before“any“opti-Ž”’õbµmization–Łeis“begun.‘šThese“annotations“can“be“computed“at“theŽ”’ö time–aŹthat“the“operator“tree“is“initialized,‘gÕand“will“not“changeŽ”’õ½Uwith–$œapplication“of“rules.‘6Our“following“discussions“assumeŽ”’ö+roperator–€trees“are“initialized.Ž¦’+sThere–'Ģare“two“types“of“algebraic“transformations“(orŽ”’ö+rŗr”Gewrite–ż rules¹)“in“Prairie:‘N’T‘’-rules“(\transformation“rules")Ž”’ö+rand–Ę]I-rules“(\implementation“rules").‘'Each“rule“transformsŽ”’ö+ran–*]expression“into“another“based“on“additional“conditions;Ž”’ö+rthe– qtransformation“also“results“in“a“mapping“of“descriptorsŽ”’õ_ between–Ölexpressions.‘ņW‘’37e“de ne“T‘’-rules“and“I-rules“preciselyŽ”’ö(in–\the“following“sections“and“illustrate“them“with“examples.Ž”’ö+rOur–!Ėexamples“are“chosen“from“rules“that“would“be“usedŽ”’ö+rin–ŌEa“centralized“relational“query“optimizer;‘~gthe“operators,Ž”’ö+ralgorithms,‘Ciand–Tproperties“are“subsets“of“those“in“T‘’LŠables“1Ž”’ö+rand‘€2.ŽŽŽŽŽŽŽŒ‹73 —ßż żGš šep ž“[ŸŻ×Ÿ_’‘ņĘŸŠÅų‰ffź|® åt„åtffŸÅųŸĢ£ŸČ‘€“Ešb}±(“xŸ°1Ž‘ē “;–]”:“:“:Ž‘ –„;‘]”xŸ³nŽ‘ēl±)–F·:“ęDŸē1ŽŽ‘½g±=‘ž¢_·)““E˜Ÿü{ró °Ü0ncmsy5¶0Ž‘š±(“xŸ°1Ž‘ē “;–]”:“:“:Ž‘ –„;‘]”xŸ³nŽ‘ēl±)“:“ęDŸē2ŽŽ‘7­Ž(1)ŽŽ¤‘€·ffŽ”‘*@Žpre-test‘ĄstatementsŽŽ”‘€·ggŽ”‘€ŽtestŽ”‘€·ffŽ”‘*@Žpost-test‘ĄstatementsŽŽ”‘€·ggŽŽŽŽŸ.–‘H;]Ō(a)–General“form“of“a“T‘’C™-ruleŽŽŽŽŽ‘€Ÿ’v‰ffŽÆāŸg@Ÿ¢‘ ŽJOINŽ‘)n±(ŽJOINŽ‘)n±(“SŸ°1Ž–ē “;›]”SŸ°2Ž“±)–F·:“ęDŸē4ŽŽ‘ v°“;˜SŸ°3Ž‘ē ±)“:“ęDŸē5ŽŽ‘`|wŽ(2)ŽŽŸ ‘±=‘ž¢_·)‘F·ŽJOINŽ‘p%±(“SŸ°1Ž–ē “;‘]”ŽJOINŽ‘‡±(“SŸ°2Ž““;‘]”SŸ°3Ž“±)–F·:“ęDŸē6ŽŽ‘ v°±)“:“ęDŸē7ŽŽŽŽŽŸ ‘ ·ffŽ¤‘$ĄęDŸē6ŽŽ‘/ļł“:ŽattributesŽ‘Ti±=‘F·ŽunionŽ‘ųß±(ęDŸē2ŽŽ‘ /ł“:ŽattributesŽ– ²“;‘]”ęDŸē3ŽŽ‘ š“:ŽattributesŽ“±)‘Ą;ŽŽ”‘ ·ggŽ”‘ Žisk„‰ff›Ž‘…associativeŽ‘2§±(ęDŸē6ŽŽ‘ /ł“:Žjoink„‰ff›Ž‘…predicateŽ›'“;‘]”ęDŸē6ŽŽ– š“:ŽattributesŽ‘ ²“;‘]”ęDŸē5ŽŽ““:Žjoink„‰ff›Ž‘…predicateŽ˜±)Ž”‘ ·ffŽ”‘$ĄęDŸē7ŽŽ‘26°±=‘F·ęDŸē5ŽŽ‘6°±;ŽŽ”‘$ĄęDŸē7ŽŽ‘/ļł“:Žjoink„‰ff›Ž‘…predicateŽ‘)W¼±=‘F·ęDŸē4ŽŽ‘ v°“:Žjoink„‰ff›Ž‘…predicateŽ‘(ѱ;ŽŽ”‘$ĄęDŸē6ŽŽ‘/ļł“:Žtuplek„‰ff›Ž‘…sizeŽ‘®I±=‘F·ęDŸē2ŽŽ‘ v°“:Žtuplek„‰ff›Ž‘…sizeŽ‘9¾±+‘Ņ,ęDŸē3ŽŽ‘ %“:Žtuplek„‰ff›Ž‘…sizeŽ‘'’±;ŽŽ”‘$ĄęDŸē6ŽŽ‘/ļł“:Žnumk„‰ff›Ž‘…recordsŽ‘%׏±=‘F·ŽcardinalityŽ‘!öś±(ęDŸē2ŽŽ‘ /ł“;‘]”ęDŸē3ŽŽ‘ š±)‘Ą;ŽŽ”‘ ·ggŽŽŽŽŸ.–‘NŌ(b)–Join“associativityŽŽŽŽŽŽŽŽŽŽ’éÆā„åtffŽžff‰ffź|®ŽŽŽŽ’Ż–Ÿr n„ę@Ü33ŽŽŸr n‘ōʉ33ź|®ŽŽŽŸ‘Ih¹Figure‘€2:‘TxT‘’-ruleŽŽŽŸŹm‘ņs Ś2.3Ž‘ s T‘’¬ransformation‘rulesŽŸ]•‘ņs ¹T¦gransformation–ö rules,›SŒor“T‘’-rules“for“short,˜de ne“equiva-Ž¤ ‘ņs lences–Źamong“pairs“of“expressions;‘othey“de ne“mappingsŽ”‘ņs from–ęOone“operator“tree“to“another‘’s8.‘‡eLet“µE‘yܹand“µE‘“Ÿü^’·0Ž‘H¹be“ex-Ž”‘ņs pressions–†€that“involve“only“abstract“operators.‘gųEquation“(1)Ž”‘ņs (shown–åin“Figure“2(a))“shows“the“general“form“of“a“T‘’-rule.Ž”‘ņs The–ńactions“of“a“T‘’-rule“de ne“the“equivalences“between“theŽ”‘ņQżdescriptors–d‘of“nodes“of“the“original“operator“tree“µE‘ų¹with“theŽ”‘ņs nodes–kfof“the“output“tree“µE‘“Ÿü^’·0Ž‘aĘ¹;‘įthese“actions“consist“of“a“se-Ž”‘ņs ries–NÆof“(C‘Nyor“C++)“assignmentŸü^’±2ŽŽ‘Ė"¹statements.‘Ą„The“left-handŽ”‘ņs sides–of“these“statements“refer“to“descriptors“of“expressionsŽ”‘ņs on–½āthe“right-hand“side“of“the“T‘’-rule;‘ÜŌthe“right-hand“sides“ofŽ”‘ń”$the–ŃŹstatements“can“refer“to“any“descriptor“in“the“T‘’-rule.‘gFunc-Ž”‘ņs tion–s*(called“ŗhelper‘zŃ¹functions)“calls“can“also“appear“on“theŽ”‘ńĘiright–š¹side“of“the“assignment“statements.‘$¶Thus,‘ adescriptors“onŽ”‘ņMƒthe–`Śŗleft-hand“side“¹of“a“T‘’-rule“are“ŗnever‘h¹changed“in“the“rule'‘’s8sŽ”‘ņ7actions.‘CŻA‘N"ŗtest‘gĘ¹is–N.needed“to“determine“if“the“transformationsŽ”‘ņs of–€the“T‘’-rule“are“in“fact“applicable.ŽŸ e7‘ūļ‘Purely–ąas“an“optimization,‘(“it“is“usually“the“case“that“not“allŽ”‘ńĪstatements–÷in“a“T‘’-rule'‘’s8s“actions“need“to“be“executed“prior“to“aŽ”‘ņ?ŸT›’-rule'‘’s8s–URtest.‘F>For“this“reason,‘]Ūthe“actions“of“a“T˜-rule“are“splitŽ”‘ņs into–Ŗtwo“groups;‘æ those“that“need“to“be“executed“prior“to“theŽ”‘ń¢XT‘’-rule'‘’s8s–ŅŹtest,‘õoand“those“that“can“be“executed“after“a“successfulŽ”‘ņV*test.‘L{These–hgroups“of“statements“comprise,–lÓrespectively‘’Y ,“theŽ‘ņs Ÿ$/‰ff^ŚYŸ J=‘ ;ĮŸż-:Ė2ŽŽŽ‘fhŌThe–³actions“can“be“non-assignment“statements“(like“function“calls),‘šöbutŽ¤ €in–ĘÜthis“case,‘ų“the“P2V‘Ę©pre-processor“(described“in“Section“3)“needs“someŽ”hints–ĒTabout“the“properties“that“are“changed“by“the“statement“in“order“to“cor× -Ž”rectly–½įcategorize“each“property›’zę.‘“šFor“simplicity˜,›Ėin“this“paper®,˜we“assume“allŽ”actions–consist“of“assignment“statements.ŽŽŽ žuų°ŸŻ×Ÿ›åh’ö~‚Ÿ™KĶ‰ffź|® Čhe„ČheffŸžKĪŸŁ‹ĶŸČ‘€“Eb}±(“xŸ°1Ž›ē “;–]”:“:“:Ž‘ –„;‘]”xŸ³nŽ‘ēl±)–F·:“ęDŸē1ŽŽ‘½g±=‘ž¢_·)““A±(“xŸ°1Ž˜“;–]”:“:“:Ž‘ –„;‘]”xŸ³nŽ‘ēl±)“:“ęDŸē2ŽŽ‘:żŽ(3)ŽŽ¤‘€testŽ”‘€·ffŽ”‘*@Žpre-opt‘ĄstatementsŽŽ”‘€·ggŽ”‘€ffŽ”‘*@Žpost-opt‘ĄstatementsŽŽ”‘€·ggŽŽŽŽŸ.–‘FłÖŌ(a)–General“form“of“an“I-ruleŽŽŽŽŽ‘€Ÿ’v‰ffŽÆāŸK@Ÿ¾‘ ŽSOR”{TŽ‘xĢ±(“SŸ°1Ž›ē ±)–F·:“ęDŸē2ŽŽ‘½g±=‘ž¢_·)“ŽMerßĮgek„‰ff›Ž‘…sortŽ‘!p±(“SŸ°1Ž˜±)“:“ęDŸē3ŽŽ‘M+ŌŽ(4)ŽŽŸ ‘ ±(ęDŸē2ŽŽ‘ /ł“:Žtuplek„‰ff›Ž‘…orderŽ‘! )±!‘ =‘F·ŽDONTk„‰ff›Ž‘…CAREŽ‘*ēl±)Ž¤‘ ·ffŽ”‘$ĄęDŸē3ŽŽ‘26°±=‘F·ęDŸē2ŽŽ‘6°±;ŽŽ”‘ ·ggŽ”‘ ffŽ”‘$ĄęDŸē3ŽŽ‘/ļł“:ŽcostŽ‘ ”±=‘F·ęDŸē1ŽŽ‘ v°“:ŽcostŽŽŽ”‘H¤Ŗ±+(ęDŸē3ŽŽ› /ł“:Žnumk„‰ff›Ž‘…recordsŽ‘#‘±)–Ņ,·“±logŽ‘ *.(ęDŸē3ŽŽ˜“:Žnumk„‰ff›Ž‘…recordsŽ‘#‘±)‘Ą;ŽŽ”‘ ·ggŽŽŽŽŸ.–‘@lŒŌ(b)–MerŪ&ge-sort“sort“algorithmŽŽŽŽŽŽŽŽŽŽ’éÆā„ČheffŽžff‰ffź|®ŽŽŽŽ’ąĒżŸd˜„É5133ŽŽŸd˜’ų~‚‰33ź|®ŽŽŽŸ’MÅę¹Figure‘€3:‘TxI-ruleŽŽŽŸ“½’ö+rŗpr”Ge-test–™˜¹and›€ŗpost-test“¹statements˜of˜the˜T‘’-rule.Ÿü^’±3ŽŽŽŸ6’ö+räExample‘€4.ŽŽ’<ė¹The–ąÜassociativity“of“JOINs“is“expressed“byŽ¤ ’ö+rT‘’-rule–€(2)“in“Figure“2(b).’‚”3ÅŽŸ~’ö+rŚ2.4Ž’+rImplementation‘rulesŽŸc¦’ö+r¹Implementation–\rules,›d3or“I-rules“for“short,˜de ne“equiva-Ž”’ö+rlences–į¦between“expressions“and“their“implementing“algo-Ž”’ö+rrithms.‘ šLet–½ µE‘P˜¹be“an“expression“and“µA“¹be“an“algorithm“thatŽ”’ö+rimplements–hQµE‘“¹.‘ kThe“general“form“of“an“I-rule“is“given“byŽ”’ö+rEquation–€(3)“(shown“in“Figure“3(a)).Ž© Z^’+sThe––’actions“associated“with“an“I-rule“are“de ned“in“threeŽ”’ö+rparts.‘b·The–Ś rst“part,›ššor“ŗtest¹,˜is“a“boolean“expression“whoseŽ”’ö+rvalue–€determines“whether“or“not“the“rule“can“be“applied.Ž¦’’ĮŚThe–(\second“part,›9ćor“ŗpr”Ge-opt“statements¹,˜is“a“set“of“descrip-Ž”’ö+rtor–å=assignment“statements“that“are“executed“only“if“the“testŽ”’ö+ris–ütrue“and“ŗbefor”Ge“¹any“of“the“inputs“µxŸ’“iŽ‘P[¹of“µE‘œ¹are“optimized.Ž”’ö+rAdditional–鎍’š2±(ŽJOINŽ‘©n?opk„‰ff›Ž‘…arßĮg7Ž–-N±(?1›€(ŽJOINŽ‘©n?opk„‰ff›Ž‘…arßĮg6Ž“±(?2˜?3))))ŽŽŽŽ”’ö+r¹The–łLimportant“point“to“note“is“the“use“of“ŗoperator“ar”Ggu-Ž¤ ’ö+rments–’ž¹(denoted“by“\op‘™˜‰ffŽ‘™šaršŃšg"“in“rules);‘›ģthese“ar˜guments“con-Ž”’ö+rtain–¤Ęproperties“used“in“the“rule'‘’s8s“actions,‘­ųbut“unlike“Prairie,Ž”’ö+rthey–āƒdo“not“contain“ŗall“¹the“properties“of“an“operator“treeŽ”’ö¼node.‘NwThere–mūare“other“property“classes,‘q–like“algorithm“arŃšgu-Ž”’ö+rment,–C:logical›.property‘’Y ,“system˜property‘’Y ,“physical˜property‘’Y ,Ž”’ö+rand–/Žcost.‘dThus,‘[Õwhile“Prairie“uses“a“uniform“descriptor“toŽ’ö+rŸ:p‰ff^ŚYŸ J=‘ ;ĮŸż-:Ė4ŽŽŽ‘fhŌThere– jare“conditions“and“actions“associated“with“V‘ž÷Óolcano“rules“that“areŽŸ €not–shown“here.ŽŽŽŽŽŽŒ‹‡© —ßż żGš šep ž…¾…Ÿ­×Ÿś™š‘ō9› ’ZŃʉffē•­ Ø.:„Ø.:ffŸż‘8@¤÷vÕņ" tx@Dict begin STP newpath 2.6 SLW 0. setgray [ 17.07164 128.0373 119.50148 128.0373 119.50148 25.60745 17.07164 25.60745 /Lineto /lineto load def false Polygon gsave 2.6 SLW 0. setgray 0 setlinecap stroke grestore gsave 1.0 SLW 1. setgray stroke grestore endņ" tx@Dict begin STP newpath 0.8 SLW 0. setgray [ 34.14328 153.64476 102.42984 153.64476 102.42984 136.57312 34.14328 136.57312 /Lineto /lineto load def false Polygon gsave 1. setgray fill grestore gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore end ’n䍍ŸVū‘.ļŠ" tx@Dict begin STP newpath 0.0 SLW 1. setgray 0. true 3.0 neg 3.07344 neg 47.33029 7.75298 .5 Frame gsave 1. setgray fill grestore endŽPrairie–ĄRule“SetŽŽŽŽŽŽŽņ›" tx@Dict begin STP newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { /ArrowBc [ 6 2 roll ] cvx def ArrowBc BeginArrow false 0.4 1.4 2.0 3. Arrow EndArrow } def [ 68.28656 119.50148 68.28656 136.57312 /Lineto /lineto load def false Line gsave 2.0 2 mul CLW add SLW 1. setgray stroke grestore gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore gsave ArrowBc ArrowB pop pop pop pop grestore endņ " tx@Dict begin STP newpath 2.6 SLW 0. setgray [ 34.14328 119.50148 102.42984 119.50148 102.42984 102.42984 34.14328 102.42984 /Lineto /lineto load def false Polygon gsave 2.6 SLW 0. setgray 0 setlinecap stroke grestore gsave 1.0 SLW 1. setgray stroke grestore endŸ‘ĖŸžŚ‘)ņ"P2V‘ĄPre-processorŽŽŽŽŽņ™" tx@Dict begin STP newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { /ArrowBc [ 6 2 roll ] cvx def ArrowBc BeginArrow false 0.4 1.4 2.0 3. Arrow EndArrow } def [ 68.28656 85.3582 68.28656 102.42984 /Lineto /lineto load def false Line gsave 2.0 2 mul CLW add SLW 1. setgray stroke grestore gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore gsave ArrowBc ArrowB pop pop pop pop grestore endļž" tx@Dict begin STP newpath 0.8 SLW 0. setgray [ 34.14328 85.3582 102.42984 85.3582 102.42984 68.28656 34.14328 68.28656 /Lineto /lineto load def false Polygon gsave 0.5 setgray fill grestore gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore endŸ³-yŸVū‘, ŗļ‰" tx@Dict begin STP newpath 0.0 SLW 1. setgray 0. true 3.0 neg 3.07344 neg 51.4815 7.75298 .5 Frame gsave 1. setgray fill grestore endV‘’Ųolcano–ĄRule“SetŽŽŽŽŽŽŽņ™" tx@Dict begin STP newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { /ArrowBc [ 6 2 roll ] cvx def ArrowBc BeginArrow false 0.4 1.4 2.0 3. Arrow EndArrow } def [ 68.28656 51.21492 68.28656 68.28656 /Lineto /lineto load def false Line gsave 2.0 2 mul CLW add SLW 1. setgray stroke grestore gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore gsave ArrowBc ArrowB pop pop pop pop grestore endņ" tx@Dict begin STP newpath 2.6 SLW 0. setgray [ 34.14328 51.21492 102.42984 51.21492 102.42984 34.14328 34.14328 34.14328 /Lineto /lineto load def false Polygon gsave 2.6 SLW 0. setgray 0 setlinecap stroke grestore gsave 1.0 SLW 1. setgray stroke grestore endŸÕR'ŸĄŸūŁ˜‘8įQV‘’ŲolcanoŽŽŸ‘'†OptimizerÜ+-GeneratorŽŽŽŽŽŽŽŽŽņ™" tx@Dict begin STP newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { /ArrowBc [ 6 2 roll ] cvx def ArrowBc BeginArrow false 0.4 1.4 2.0 3. Arrow EndArrow } def [ 68.28656 17.07164 68.28656 34.14328 /Lineto /lineto load def false Line gsave 2.0 2 mul CLW add SLW 1. setgray stroke grestore gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore gsave ArrowBc ArrowB pop pop pop pop grestore endļö" tx@Dict begin STP newpath 0.8 SLW 0. setgray [ 34.14328 17.07164 102.42984 17.07164 102.42984 0.0 34.14328 0.0 /Lineto /lineto load def false Polygon gsave 0.5 setgray fill grestore gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore end”ŸžŚ‘,y ļŠ" tx@Dict begin STP newpath 0.0 SLW 1. setgray 0. true 3.0 neg 4.51193 neg 50.62743 7.75298 .5 Frame gsave 1. setgray fill grestore endQuery‘ĄOptimizerŽŽŽŽŽŽŽ”ŸžŚ‘éŻsOperator‘ĄTĮHreeŽŽŽŽŽņ—" tx@Dict begin STP newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { /ArrowBc [ 6 2 roll ] cvx def ArrowBc BeginArrow false 0.4 1.4 2.0 3. Arrow EndArrow } def [ 34.14328 8.53581 17.07164 8.53581 /Lineto /lineto load def false Line gsave 2.0 2 mul CLW add SLW 1. setgray stroke grestore gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore gsave ArrowBc ArrowB pop pop pop pop grestore endņ™" tx@Dict begin STP newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { /ArrowBc [ 6 2 roll ] cvx def ArrowBc BeginArrow false 0.4 1.4 2.0 3. Arrow EndArrow } def [ 119.50148 8.53581 102.42984 8.53581 /Lineto /lineto load def false Line gsave 2.0 2 mul CLW add SLW 1. setgray stroke grestore gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore gsave ArrowBc ArrowB pop pop pop pop grestore end”ŸVś‘w€aAccess‘ĄPlanŽŽŽŽŽŽŽŽŽŽŽŽ’ęČį„Ø.:ffŽžff‰ffē•­ŽŽŽŽ’ŪœŸff„Øū33ŽŽŸff‘ö9›‰33ē•­ŽŽŽŸ‘ņs ¹Figure–3ū5:‘ ¼mThe“Prairie“optimizerĢŠ-generator“paradigm.Ž¤ ‘ņs Double-boxed–³·modules“represent“software“generators,Ž”‘ņs shaded–fboxes“represent“generated“programs.‘ The“outerĢŠ-Ž”‘ņs most–Wfdouble-boxed“portion“denotes“the“Prairie“optimizerŽ”‘ņs generator‘’s8.ŽŽŸ ½‘ńõgencode–¹properties,‘,”V‘žµĒolcano“partitions“the“properties“into“dif-Ž¤ ‘ńŸferent–Šyclasses.‘öThe“P2V‘ŠLpre-processor“partitions“a“Prairie“de-Ž”‘ņs scriptor–эinto“the“di erent“property“classes“required“by“V‘žµĒol-Ž”‘ņs cano.‘bŅThis–„Éis“a“non-trivial“task,‘…ūsince“it“requires“parsing“theŽ”‘ņs Prairie–€rules“and“their“actions.Ž”‘üs Impl‘™˜‰ffŽ‘™šrules–†Zin“V‘žµĒolcano“defer“most“of“the“actions“associ-Ž”‘ņ9”ated–POwith“the“rules“to“support“functions.‘D’Each“algorithm“hasŽ”‘ńž›four–ĻÆsupport“functions“associated“with“it.‘³A‘ĻƒPrairie“speci ca-Ž”‘ņ^$tion,›ron–n§the“other“hand,˜contains“all“the“actions“in“the“corre-Ž”‘ń–¬sponding–Érule.‘The“P2V‘Čėpre-processor“parses“a“Prairie“I-rule,Ž”‘ņs and–ƒlator™Ÿ,‘Ż2we–“~translated“this“to“V‘žµĒolcano“format“and“optimized“sev-Ž”’ö+reral–ŻCqueries“using“the“resultant“optimizer‘’s8.‘lAFor“comparison,Ž”’õéŪwe–Ihand-coded“the“same“optimizer“directly“in“V‘žµĒolcano.‘BSTheŽ”’õØresults–presented“there“showed“that,‘(Ķusing“Prairie“(comparedŽ”’ö+rto–«directly“using“V‘žµĒolcano)“resulted“in“approximately“50%Ž”’ö+rsavings–7Cin“lines“of“code“with“negligible“(less“than“5%)“in-Ž”’ö+rcrease–ÖŻin“query“optimization“time.‘YHowever™Ÿ,‘ģ”the“optimizerŽ”’ö+rwas––quite“small“in“terms“of“the“number“of“operators,‘#;algo-Ž”’ö+rrithms–€and“rules.Ž”’+sFor–¼Ųa“more“realistic“evaluation“of“Prairie,‘Ģwe“needed“an-Ž”’ö+rswers–€to“the“following“questions:ŽŸŻ’ż«t1.ŽŽŽ’ +tIs–€Prairie“adequate“for“larŃšge-scale“rule“sets?Ž©īȍ’ż«t2.ŽŽŽ’ +tHow–tais“programmer“productivity“enhanced“by“theŽ”’ +thigh-level–€abstractions“of“Prairie?Ž¦’ż«t3.ŽŽŽ’ +tCan–ĢÅPrairie“rule“sets“be“translated“automatically“into“ef-Ž”’ +t cient‘€implementations?ŽŸŻŽ’’ÓW‘’37e–6—addressed“the“ rst“question“by“using“the“T‘’LŠexas“Instru-Ž”’ö+rments–ŽOpen“OODB‘Žquery“optimizer“rule“set,‘‘–which“has“theŽ”’õAwlarŃšgest–½Ļpublicly“available“rule“set.‘¾W‘’37e“describe“this“optimizerŽ”’õéin–Hńthe“next“section,‘Sōand“then“give“our“assessments“to“the“lastŽ”’ö+rtwo–€questions“in“subsequent“sections.ŽŸ‡”’ö+rŚ4.1Ž’+rThe–ĪwT‘žåfexas“Instruments“Open“OODBŽŸ’+rquery‘optimizerŽŸøP’ö+r¹The–”dT‘’LŠexas“Instruments“Open“Object-Oriented“DatabaseŽ”’õž¹Management–ZāSystem“is“an“open,–bNextensible,“object-orientedŽ”’ö+rdatabase–Zsystem“which“provides“users“an“architecturalŽ”’ö+rframework–›that“is“con gurable“in“an“incremental“manner‘’s8.Ž”’ö+rThe–³-query“optimizer“in“the“Open“OODB‘²Ż[2]“is“generatedŽŽŽŽŽŽŒ‹¢“ —ßż żGš šep żˆš‘ņs ¹using–†•V‘žµĒolcano.‘ h6It“is“written“as“a“set“of“trans‘™˜‰ffŽ‘™šrules“andŽ¤ ‘ņs impl‘™˜‰ffŽ‘™šrules–1®that“de ne“the“algebra“of“an“object-orientedŽ”‘ņs database–[õsystem.‘čXCurrently‘’Y ,‘Ņóthere“are“17“transformationŽ”‘ņs rules–.cand“9“implementation“rules“together“with“aboutŽ”‘ņs ²13µ;‘Ŗز000–ŻM¹lines“of“code“for“support“functions;‘ ōthis,‘ō”of“course,Ž”‘ņs can–€be“changed“by“an“Open“OODB“user“for“speci c“needs.ŽŸ$ ‘ņs Ś4.2Ž‘ s Pr•Č¹ogrammer‘pr“oductivityŽŸDU‘ńƟ¹Programmer–ŻĻproductivity“can“be“measured“in“di erent“ways.Ž”‘ņs An–¢admittedly“simplistic“metric“is“the“number“of“lines“ofŽ”‘ņs code–$āthat“must“be“written.‘CBut“there“are“also“less“tangibleŽ”‘ņ \measures,‘;Ósuch–*Ēas“the“amount“of“conceptual“e ort“needed“toŽ”‘ņs understand–ŲDa“particular“programming“task.‘]COur“experienceŽ”‘ņs with–õthe“Open“OODB‘ńquery“optimizer“suggests“that“PrairieŽ”‘ņrtexcels–ƒon“the“latter™Ÿ,‘œwhile“o ering“modest“reductions“in“theŽ”‘ņs volume–€of“code“that“needs“to“be“written.Ž© IŚ‘ūŚW‘’37e–converted“by“hand“the“Open“OODB‘īquery“optimizer^ø'‘’s8sŽ”‘ńūłV‘žµĒolcano–.speci cations“to“Prairie.‘3‡This“was“a“non-trivial“taskŽ”‘ņs because–rļof“the“relatively“larŃšge“size“of“the“rule“set“and“theŽ”‘ņs complexity–©mof“the“support“functions.‘Š¾This“was“where“weŽ”‘ņs found–grPrairie“helped“in“conceptually“simplifying“the“rulesŽ”‘ń‚ and–ø actions.‘ŅW‘’37e“then“used“our“P2V‘·Śpre-processor“to“reconsti-Ž”‘ń‚Ätute–ø”these“Prairie“speci cations“as“V‘žµĒolcano“speci cations.‘’AsŽ”‘ņXjdescribed–ięin“Section“3,‘nQthis“process“involved“a“considerableŽ”‘ņs level–•of“complexity‘’Y ,‘šßpartly“because“the“Prairie“speci cationŽ”‘ņ¦had–!ä22“T‘’-rules“and“1”G1“I-rules“compared“to“17“trans‘™˜‰ffŽ‘™šrules“andŽ”‘ņs 9–öimpl‘™˜‰ffŽ‘™šrules“in“the“V‘žµĒolcano“speci cation;‘1the“reconstitutedŽ”‘ņs V‘žµĒolcano–”óspeci cation“had“the“same“number“of“trans‘™˜‰ffŽ‘™šrulesŽ”‘ņs and–€impl‘™˜‰ffŽ‘™šrules“as“the“original“hand-coded“speci cation.Ž¦‘ū›PConverting–Ģóthe“Open“OODB‘ĢÅoptimizer“rule“set“into“PrairieŽ”‘ņs format–‡Øactually“simpli ed“its“speci cation“as“the“complexi-Ž”‘ņs ties–×vof“the“V‘žµĒolcano“model“were“removed.‘ZŁThe“reduction“inŽ”‘ń±jlines–ßLof“code“was“modest“|“there“was“about“a“10%“savings.Ÿü^’±5ŽŽŽ”‘ņs ¹However™Ÿ,›+ as–Ömentioned“above,˜savings“in“lines“of“code“doŽ”‘ņs not–kįadequately“re ect“increases“in“programmer“productiv-Ž”‘ņs ity‘’Y .‘–"W‘’37e–ė9found“the“encapsulated“speci cations“of“Prairie“|Ž”‘ńį>namely‘’Y ,‘2the–żuse“of“a“single“descriptor“and“fewer“explicit“sup-Ž”‘ņs port–€functions“|“made“rule“programming“ŗmuch“¹easier‘’s8.ŽŸ$ ‘ņs Ś4.3Ž‘ s Performance– —®rČ¹esults“using“the“OpenŽŸ‘ s OODB‘optimizerŽŸDU‘üĮ¹The–:ßacid“test“of“Prairie“was“whether“Prairie“speci cationsŽ”‘ńŽwcould–°be“translated“into“ecient“optimizer“implementations.Ž”‘ņs Our– pexperiments“using“the“Open“OODB‘ Lconsisted“of“opti-Ž”‘ņs mizing–k&8“di erent“queries“using“the“two“query“optimizersŽ”‘ņqgenerated,– respectively‘’Y ,“using–~ŠPrairie“and“using“V‘žµĒolcano“di-Ž”‘ņėrectly–'ģ(in“the“remainder“of“this“section,‘9Šwe“will“use“\Prairie"Ž”‘ņAand–-.\V‘žµĒolcano"“to“denote“these“two“approaches).‘8ŻThere“wereŽ‘ņs Ÿ ¶½‰ff^ŚYŸ J=‘ ;ĮŸż-:Ė5ŽŽŽ‘fhŌThe–ØŖoriginal“V‘ž÷Óolcano“speci cation“had“ó|{Ycmr8Ź13ó!×2cmmi8Ģ;‘j¬Ź400“Ōlines,‘ŗ"the“Prairie“speci-Ž¤ € cation–hähad“Ź12Ģ;‘j¬Ź100“Ōlines,‘‡and“the“P2V‘’C™-generated“V‘ž÷Óolcano“speci cation“hadŽ”Ź15Ģ;‘j¬Ź800‘Ōlines.ŽŽŽ żˆš’õõć¹4–SŒdistinct“expressions“that“were“used“to“generate“the“queriesŽ¤ ’ö+rused–•įin“the“experiments;‘ Ņthese“are“shown“in“Figure“6.‘–EachŽ”’ö+rexpression–€represents“an“µN›¹-way“join“query“for“varying“µN˜¹.Ž© #>’+sThe–E˜ rst“expression“E1“is“a“simple“retrieval“and“join“ofŽ”’ö+rbase–¤3classes.‘ĮThe“second,–­?E2,“is–¤3also“a“join“of“base“classes;Ž”’õ¦ćhowever™Ÿ,›'żafter–üeach“class“retrieval,˜an“attribute“has“to“be“ma-Ž”’ö Įterialized–d (i.e.,‘i¢brought“into“view)“before“the“join.‘K&The“thirdŽ”’ö$Fand–z fourth“expressions“(E3“and“E4)“are“the“same“as“the“ rstŽ”’ö+rand–éŁsecond“(E1“and“E2)“respectively‘’Y ,‘Pexcept“that“there“is“aŽ”’ö+rselection–ā‰of“attributes“(the“select“operator“is“the“root“of“theŽ”’ö+rexpressions).Ÿü^’±6ŽŽŽ¦’+s¹The– 5algebra“that“was“used“in“the“Prairie“and“V‘žµĒolcano“op-Ž”’ö+rtimizers–ŗ…for“our“experiments“consisted“of“5“relational“operĢŠ-Ž”’ö+rators–VHSELECT›’B,“PROJECT˜,“JOIN,“RET›Vand“UNNEST˜(forŽ”’öõset-valued–]‘attributes)“and“an“object-oriented“operator“calledŽ”’õoMA–žć×T‘ćŪ(for›äMA“T‘’LŠerialize;‘it˜is˜fundamentally˜a˜pointerĢŠ-chasingŽ”’ö+roperator–€for“attributes“of“a“class).‘TxThere“were“8“algorithms.Ž¦’’3ÄThere–²oare“many“parameters“that“can“be“varied“when“bench-Ž”’ö+rmarking–¤a“query“optimizer‘’s8.‘ĄSince“our“objective“was“to“verĢŠ-Ž”’ö"ßify–xāthat“the“Prairie“approach“did“not“sacri ce“eciency‘’Y ,‘zNourŽ”’ö+rcriteria–: for“the“queries“was“that“they“test“a“majority“of“theŽ”’õ1Ōrules,‘ŚDwith–°Ōvarying“properties“of“the“base“classes.‘jT‘’LŠo“this“end,Ž”’ö+rwe–›Œtested“our“optimizer“(and“the“V‘žµĒolcano“optimizer)“with“8Ž”’ö+rdi erent–Śóqueries“(shown“in“T‘’LŠable“3).‘eRThe“eight“queries“Q1Ž”’ö+rthrough–°–Q8“are“derived“from“the“4“expressions“in“Figure“6.Ž”’õŸõEach– ;expression“E1“through“E4“is“used“to“obtain“two“queriesŽ”’ö+rfor–Šća“ xed“number“µN‘”ž¹of“JOINs“in“the“expression.‘u The“onlyŽ”’õ‹ūdi erence–ū§between“the“two“queries“obtained“from“an“expres-Ž”’ö'sion–kis“that“the“ rst“one“does“not“contain“any“indices“on“anyŽ”’ö+rclasses,‘ņwhereas–ŪIthe“second“one“contains“a“single“index“onŽ”’ö+reach–øHbase“class“occurring“in“the“expression.‘żQIn“expressionsŽ”’õĻswhere–3¦a“SELECT‘3’is“present“(E3“and“E4),‘Bėthe“selection“pred-Ž”’ö+ricate–‰³is“a“conjunction“of“equality“predicates“ŗbcŽ‘ śSŸ’“iŽ‘6.²==‘ēŗconstŽ‘¦Ÿ’“iŽ‘Wņ¹,Ž”’õčcwhere‘HYŗbcŽ‘ øłŸ’“iŽ‘Už¹is–HYan“attribute“of“class“ŗCŽ‘óŁŸ’“iŽ‘ H%¹,‘Szand“ŗconstŽ‘dpŸ’“iŽ‘¹is“a“constantŽ”’ö+r(we–ŃÄarbitrarily“set“this“to“µi¹,‘ę5because“its“value“doesn'Ńšt“a ectŽ”’õ+ėthe–«ģcorrectness“or“performance“of“the“optimizer).‘ ĒIn“addition,Ž”’õåfor–Fqueries“with“a“SELECT‘Eņand“whose“base“classes“have“in-Ž”’õÆudices–(Q6“and“Q8“in“T‘’LŠable“3),‘-­the“(single)“index“of“each“baseŽ”’ö+rclass–œ"was“chosen“to“be“the“attribute“referenced“in“the“selec-Ž”’ö+rtion–Vpredicate.‘ÖĖFor“example,‘‹£class“ŗCŽ‘ œŸ’“iŽ‘¬¹was“chosen“to“haveŽ”’õš•an–O%index“on“attribute“ŗbcŽ‘ æş’“iŽ‘¹.‘D/The“join“predicates“for“each“JOINŽ”’õPųwere–Ź­chosen“at“random,‘īńand“were“always“equality“predicates.Ž”’õ˜FThe–Ūchoice“of“JOIN‘¼predicates“was“such“that“the“queries“corĢŠ-Ž”’ö+rresponded–ćto“linear“query“graphs.‘‡!In“the“future,‘•we“will“ex-Ž”’ö+rperiment–€with“non-linear“(e.g.,“star)“query“graphs.Ž¦’+sT‘’LŠable–^3“also“shows“the“number“of“trans‘™˜‰ffŽ‘™šrules“andŽ’ö+rŸ ;‰ff^ŚYŸ J=‘ ;ĮŸż-:Ė6ŽŽŽ‘fhŌThe–most“complex“expression“E4“consists“of“all“operators“in“the“alge-Ž¤ €bra,‘ŽWexcept–±ąPROJECT›±²and“UNNEST‘’hs.“PROJECT˜was“not“considered“be-Ž”cause–ĖČit“appeared“in“only“one“implzą‰fffhŽ›įHrule“and“no“transzą‰fffhŽ˜rules,›Ö:and“thus,˜wouldŽ”not–ˆa ect“the“size“of“the“search“space“of“abstract“expressions.‘AśUNNESTŽ”was–d•not“considered“because“it“appeared“in“exactly“one“transzą‰fffhŽ‘įHrule“and“oneŽ”implzą‰fffhŽ‘įHrule;‘Dżincluding–-žit“in“our“queries“would“have“increased“the“number“ofŽ”parameters–ķŁthat“could“a ect“our“run-times.‘£ķW‘’\,e“preferred“to“concentrate“onŽ”simple–JOIN“expressions.ŽŽŽŽŽŽŒ‹Ķy —ßż żGš šep ž#DŸöŸē׍ŸŁ/ ‘ņs Ÿ®¶¦‰ff~mŸu³Ō„u³ŌffŸŪ•†Ÿéė‘¦"ļups: tx@Dict begin tx@NodeDict begin { } /TheNodecl1 16 { .5 3.32748 1.5 false .5 7.2378 InitRnode } NewNode end endó6LméV ptmri7tįCŽ‘UĄŸ€°1ŽŽŽŽŽŽŽŸōžqŸ«…‘‹žļvps: tx@Dict begin tx@NodeDict begin { } /TheNodegetcl1 16 { .5 3.34 0.0 false .5 9.44495 InitRnode } NewNode end endąRETŽŽŽŽŽŽ‘ D’ļžps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNodecl1 /TheNodegetcl1 InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endŸéė‘$®ļups: tx@Dict begin tx@NodeDict begin { } /TheNodecl2 16 { .5 3.32748 1.5 false .5 7.2378 InitRnode } NewNode end endįCŽ‘UĄŸ€°2ŽŽŽŽŽŽŽŸōžqŸ«…‘ *ļvps: tx@Dict begin tx@NodeDict begin { } /TheNodegetcl2 16 { .5 3.34 0.0 false .5 9.44495 InitRnode } NewNode end endąRETŽŽŽŽŽŽļžps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNodecl2 /TheNodegetcl2 InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endŸé<āŸ«Ų‘÷Uļ‡ps: tx@Dict begin tx@NodeDict begin { } /TheNodejoingetcl1getcl2 16 { .5 3.39499 0.05246 false .5 10.8299 InitRnode } NewNode end endJOINŽŽŽŽŽŽņ ps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNodejoingetcl1getcl2 /TheNodegetcl1 InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endņ ps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNodejoingetcl1getcl2 /TheNodegetcl2 InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endŸŻŪS‘Ćļps: tx@Dict begin 45. Rot endžN9‘ūUėļwps: tx@Dict begin tx@NodeDict begin { } /TheNodedots 16 { .5 0.61111 0.0 false .5 9.32877 InitRnode } NewNode end end³:–::“:ŽŽŽŽŽļ"ps: tx@Dict begin 45. neg Rot endŽŽŽņ ps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNodejoingetcl1getcl2 /TheNodedots InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endŸŻŪSŸ«…‘(ĶHļvps: tx@Dict begin tx@NodeDict begin { } /TheNodegetcln 16 { .5 3.34 0.0 false .5 9.44495 InitRnode } NewNode end endąRETŽŽŽŽŽŽŸé<āŸ)ė‘)g¦ļzps: tx@Dict begin tx@NodeDict begin { } /TheNodecln 16 { .5 3.32748 0.99998 false .5 8.23895 InitRnode } NewNode end endįCŽ‘UĄŸ’’³nŽŽŽŽŽŽŽļžps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNodecln /TheNodegetcln InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endŸŅy荟«Ų‘ŗsļ{ps: tx@Dict begin tx@NodeDict begin { } /TheNoderoot 16 { .5 3.39499 0.05246 false .5 10.8299 InitRnode } NewNode end endąJOINŽŽŽŽŽŽļżps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNoderoot /TheNodedots InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endļ’ps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNoderoot /TheNodegetcln InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endŽŽŽŽŽŽŽŸ‘%fŌ(a)‘E1ŽŽŽ‘BśZŸ!jz„o³ŌffŸŽ•†Ÿéė‘&"ļups: tx@Dict begin tx@NodeDict begin { } /TheNodecl1 16 { .5 3.32748 1.5 false .5 7.2378 InitRnode } NewNode end endįCŽ‘UĄŸ€°1ŽŽŽŽŽŽŽŸōžqŸ«…‘ žļvps: tx@Dict begin tx@NodeDict begin { } /TheNodegetcl1 16 { .5 3.34 0.0 false .5 9.44495 InitRnode } NewNode end endąRETŽŽŽŽŽŽ‘Ēļžps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNodecl1 /TheNodegetcl1 InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endŸéė‘$®ļups: tx@Dict begin tx@NodeDict begin { } /TheNodecl2 16 { .5 3.32748 1.5 false .5 7.2378 InitRnode } NewNode end endįCŽ‘UĄŸ€°2ŽŽŽŽŽŽŽŸōžqŸ«…‘ *ļvps: tx@Dict begin tx@NodeDict begin { } /TheNodegetcl2 16 { .5 3.34 0.0 false .5 9.44495 InitRnode } NewNode end endąRETŽŽŽŽŽŽļžps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNodecl2 /TheNodegetcl2 InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endŸé<āŸ²‘śøųļ}ps: tx@Dict begin tx@NodeDict begin { } /TheNodematgetcl1 16 { .5 3.39499 0.0 false .5 10.55492 InitRnode } NewNode end endMA‘’qėTŽŽŽŽŽŽņps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNodegetcl1 /TheNodematgetcl1 InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endŸé<āŸ²‘|ļ}ps: tx@Dict begin tx@NodeDict begin { } /TheNodematgetcl2 16 { .5 3.39499 0.0 false .5 10.55492 InitRnode } NewNode end endMA‘’qėTŽŽŽŽŽŽņps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNodegetcl2 /TheNodematgetcl2 InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endŸŻŪSŸ«Ų‘÷Uļps: tx@Dict begin tx@NodeDict begin { } /TheNodejoinmatgetcl1matgetcl2 16 { .5 3.39499 0.05246 false .5 10.8299 InitRnode } NewNode end endJOINŽŽŽŽŽŽņps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNodejoinmatgetcl1matgetcl2 /TheNodematgetcl1 InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endņps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNodejoinmatgetcl1matgetcl2 /TheNodematgetcl2 InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endŸŅyč‘Ćļps: tx@Dict begin 45. Rot endžN9‘ūUėļwps: tx@Dict begin tx@NodeDict begin { } /TheNodedots 16 { .5 0.61111 0.0 false .5 9.32877 InitRnode } NewNode end end³:–::“:ŽŽŽŽŽļ"ps: tx@Dict begin 45. neg Rot endŽŽŽņps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNodejoinmatgetcl1matgetcl2 /TheNodedots InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endŸŻŪSŸ«…‘(ĶHļvps: tx@Dict begin tx@NodeDict begin { } /TheNodegetcln 16 { .5 3.34 0.0 false .5 9.44495 InitRnode } NewNode end endąRETŽŽŽŽŽŽŸé<āŸ)ė‘)g¦ļzps: tx@Dict begin tx@NodeDict begin { } /TheNodecln 16 { .5 3.32748 0.99998 false .5 8.23895 InitRnode } NewNode end endįCŽ‘UĄŸ’’³nŽŽŽŽŽŽŽļžps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNodecln /TheNodegetcln InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endŸŅy荟²‘(?4ļ}ps: tx@Dict begin tx@NodeDict begin { } /TheNodematgetcln 16 { .5 3.39499 0.0 false .5 10.55492 InitRnode } NewNode end endąMA‘’qėTŽŽŽŽŽŽņps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNodematgetcln /TheNodegetcln InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endŸĒ5Ÿ«Ų‘ŗsļ{ps: tx@Dict begin tx@NodeDict begin { } /TheNoderoot 16 { .5 3.39499 0.05246 false .5 10.8299 InitRnode } NewNode end endJOINŽŽŽŽŽŽļżps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNoderoot /TheNodedots InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endņps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNoderoot /TheNodematgetcln InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endŽŽŽŽŽŽŽŸ‘l Ō(b)‘E2ŽŽŽ–=zZ„o³ŌffŸŽ•†Ÿéė‘&"ļups: tx@Dict begin tx@NodeDict begin { } /TheNodecl1 16 { .5 3.32748 1.5 false .5 7.2378 InitRnode } NewNode end endįCŽ‘UĄŸ€°1ŽŽŽŽŽŽŽŸōžqŸ«…‘ žļvps: tx@Dict begin tx@NodeDict begin { } /TheNodegetcl1 16 { .5 3.34 0.0 false .5 9.44495 InitRnode } NewNode end endąRETŽŽŽŽŽŽ‘Ēļžps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNodecl1 /TheNodegetcl1 InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endŸéė‘$®ļups: tx@Dict begin tx@NodeDict begin { } /TheNodecl2 16 { .5 3.32748 1.5 false .5 7.2378 InitRnode } NewNode end endįCŽ‘UĄŸ€°2ŽŽŽŽŽŽŽŸōžqŸ«…‘ *ļvps: tx@Dict begin tx@NodeDict begin { } /TheNodegetcl2 16 { .5 3.34 0.0 false .5 9.44495 InitRnode } NewNode end endąRETŽŽŽŽŽŽļžps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNodecl2 /TheNodegetcl2 InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endŸé<āŸ«Ų‘÷Uļ‡ps: tx@Dict begin tx@NodeDict begin { } /TheNodejoingetcl1getcl2 16 { .5 3.39499 0.05246 false .5 10.8299 InitRnode } NewNode end endJOINŽŽŽŽŽŽņ ps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNodejoingetcl1getcl2 /TheNodegetcl1 InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endņ ps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNodejoingetcl1getcl2 /TheNodegetcl2 InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endŸŻŪS‘Ćļps: tx@Dict begin 45. Rot endžN9‘ūUėļwps: tx@Dict begin tx@NodeDict begin { } /TheNodedots 16 { .5 0.61111 0.0 false .5 9.32877 InitRnode } NewNode end end³:–::“:ŽŽŽŽŽļ"ps: tx@Dict begin 45. neg Rot endŽŽŽņ ps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNodejoingetcl1getcl2 /TheNodedots InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endŸŻŪSŸ«…‘(ĶHļvps: tx@Dict begin tx@NodeDict begin { } /TheNodegetcln 16 { .5 3.34 0.0 false .5 9.44495 InitRnode } NewNode end endąRETŽŽŽŽŽŽŸé<āŸ)ė‘)g¦ļzps: tx@Dict begin tx@NodeDict begin { } /TheNodecln 16 { .5 3.32748 0.99998 false .5 8.23895 InitRnode } NewNode end endįCŽ‘UĄŸ’’³nŽŽŽŽŽŽŽļžps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNodecln /TheNodegetcln InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endŸŅy荟«Ų‘ŗsļ{ps: tx@Dict begin tx@NodeDict begin { } /TheNoderoot 16 { .5 3.39499 0.05246 false .5 10.8299 InitRnode } NewNode end endąJOINŽŽŽŽŽŽļżps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNoderoot /TheNodedots InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endļ’ps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNoderoot /TheNodegetcln InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endŸĒ5Ÿ«Ų‘łĻļ}ps: tx@Dict begin tx@NodeDict begin { } /TheNodeselect 16 { .5 3.39499 0.05246 false .5 18.3349 InitRnode } NewNode end endSELECTŽŽŽŽŽŽļ’ps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNodeselect /TheNoderoot InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endŽŽŽŽŽŽŽŸ‘„fŌ(c)‘E3ŽŽŽ“„o³ŌffŸŽ•†Ÿéė‘&"ļups: tx@Dict begin tx@NodeDict begin { } /TheNodecl1 16 { .5 3.32748 1.5 false .5 7.2378 InitRnode } NewNode end endįCŽ‘UĄŸ€°1ŽŽŽŽŽŽŽŸōžqŸ«…‘ žļvps: tx@Dict begin tx@NodeDict begin { } /TheNodegetcl1 16 { .5 3.34 0.0 false .5 9.44495 InitRnode } NewNode end endąRETŽŽŽŽŽŽ‘Ēļžps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNodecl1 /TheNodegetcl1 InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endŸéė‘$®ļups: tx@Dict begin tx@NodeDict begin { } /TheNodecl2 16 { .5 3.32748 1.5 false .5 7.2378 InitRnode } NewNode end endįCŽ‘UĄŸ€°2ŽŽŽŽŽŽŽŸōžqŸ«…‘ *ļvps: tx@Dict begin tx@NodeDict begin { } /TheNodegetcl2 16 { .5 3.34 0.0 false .5 9.44495 InitRnode } NewNode end endąRETŽŽŽŽŽŽļžps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNodecl2 /TheNodegetcl2 InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endŸé<āŸ²‘śøųļ}ps: tx@Dict begin tx@NodeDict begin { } /TheNodematgetcl1 16 { .5 3.39499 0.0 false .5 10.55492 InitRnode } NewNode end endMA‘’qėTŽŽŽŽŽŽņps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNodegetcl1 /TheNodematgetcl1 InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endŸé<āŸ²‘|ļ}ps: tx@Dict begin tx@NodeDict begin { } /TheNodematgetcl2 16 { .5 3.39499 0.0 false .5 10.55492 InitRnode } NewNode end endMA‘’qėTŽŽŽŽŽŽņps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNodegetcl2 /TheNodematgetcl2 InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endŸŻŪSŸ«Ų‘÷Uļps: tx@Dict begin tx@NodeDict begin { } /TheNodejoinmatgetcl1matgetcl2 16 { .5 3.39499 0.05246 false .5 10.8299 InitRnode } NewNode end endJOINŽŽŽŽŽŽņps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNodejoinmatgetcl1matgetcl2 /TheNodematgetcl1 InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endņps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNodejoinmatgetcl1matgetcl2 /TheNodematgetcl2 InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endŸŅyč‘Ćļps: tx@Dict begin 45. Rot endžN9‘ūUėļwps: tx@Dict begin tx@NodeDict begin { } /TheNodedots 16 { .5 0.61111 0.0 false .5 9.32877 InitRnode } NewNode end end³:–::“:ŽŽŽŽŽļ"ps: tx@Dict begin 45. neg Rot endŽŽŽņps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNodejoinmatgetcl1matgetcl2 /TheNodedots InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endŸŻŪSŸ«…‘(ĶHļvps: tx@Dict begin tx@NodeDict begin { } /TheNodegetcln 16 { .5 3.34 0.0 false .5 9.44495 InitRnode } NewNode end endąRETŽŽŽŽŽŽŸé<āŸ)ė‘)g¦ļzps: tx@Dict begin tx@NodeDict begin { } /TheNodecln 16 { .5 3.32748 0.99998 false .5 8.23895 InitRnode } NewNode end endįCŽ‘UĄŸ’’³nŽŽŽŽŽŽŽļžps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNodecln /TheNodegetcln InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endŸŅy荟²‘(?4ļ}ps: tx@Dict begin tx@NodeDict begin { } /TheNodematgetcln 16 { .5 3.39499 0.0 false .5 10.55492 InitRnode } NewNode end endąMA‘’qėTŽŽŽŽŽŽņps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNodematgetcln /TheNodegetcln InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endŸĒ5Ÿ«Ų‘ŗsļ{ps: tx@Dict begin tx@NodeDict begin { } /TheNoderoot 16 { .5 3.39499 0.05246 false .5 10.8299 InitRnode } NewNode end endJOINŽŽŽŽŽŽļżps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNoderoot /TheNodedots InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endņps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNoderoot /TheNodematgetcln InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endŸ»¶¦Ÿ«Ų‘łĻļ}ps: tx@Dict begin tx@NodeDict begin { } /TheNodeselect 16 { .5 3.39499 0.05246 false .5 18.3349 InitRnode } NewNode end endSELECTŽŽŽŽŽŽļ’ps: tx@Dict begin gsave STV newpath 0.8 SLW 0. setgray /ArrowA { moveto } def /ArrowB { } def tx@NodeDict begin 0.0 0.0 neg 1.0 1.0 /TheNodeselect /TheNoderoot InitNC { NCLine } if end gsave 0.8 SLW 0. setgray 0 setlinecap stroke grestore grestore endŽŽŽŽŽŽŽŸ‘l Ō(d)‘E4ŽŽŽŽŽŽŽŽ’’±”„u³ŌffŽžff‰ff~mŽŽŽŽ’ņ¾EŸ&Šą„v€ 33ŽŽŸ&Šą‘ōs ‰33~mŽŽŽŸ‘ņs ¹Figure–@F6:‘4›Expressions“used“in“generating“queries“for“experimentsŽŽŸĀó<’"čŸŌęg‰€Åū%¤™˜Ÿfh„ffŸ®ś‘ćQueryŽŽŽ‘ ńffŽŸĆ©‘%Ś‘Indices?ŽŽŽ‘D¾ŃŸfh„ffŽŸb‘K%7ExprßĮessionŽŽŽ‘rxŸfh„ffŽ’…ö˜Rules‘Ąmatched‘{ŗŸfh„ffŽŽ©ĢĪ‘rzŽ„ffS€GŽŽŸ32Ÿfh„ff‘ ńffŽ‘D¾ŃŸfh„ffŽ‘rxŸfh„ffŽ‘xzŽŽtransk„‰ff›Ž‘…rules‘Ÿfh„ffŽ’¢‘implk„‰ff›Ž‘…rules‘Ÿfh„ffŽŽŸęh‰€Åū%”¤fh„ff– ?śŸż™˜Q1“”„ffŽ‘.ÉNo‘+8Ÿfh„ffŽŸĘŹ‘W¹cE1ŽŽŽ‘rxŸfh„ffŽŸ½c’…™3ŽŽŽ’œ7,Ÿfh„ffŽŸ½c’ÆY(3ŽŽŽ’Å”æŸfh„ffŽŽ¦„ffE%7ŽŽŸ32¤fh„ff– ?śŸż™˜Q2“”„ffŽ‘-5Y‘’LĢes‘ ZwŸfh„ffŽ‘rxŸfh„ffŽ’œ7+Ÿfh„ffŽ’Å”æŸfh„ffŽŽ¦‰ffÅū%”¤fh„ff– ?śŸż™˜Q3“”„ffŽ‘.ÉNo‘+8Ÿfh„ffŽŸĘŹ‘W¹cE2ŽŽŽ‘rxŸfh„ffŽŸ½c’…™8ŽŽŽ’œ7,Ÿfh„ffŽŸĘŹ’ÆY(4ŽŽŽ’Å”æŸfh„ffŽŽ¦„ffE%7ŽŽŸ32¤fh„ff– ?śŸż™˜Q4“”„ffŽ‘-5Y‘’LĢes‘ ZwŸfh„ffŽ‘rxŸfh„ffŽ’œ7+Ÿfh„ffŽ’Å”æŸfh„ffŽŽ¦‰ffÅū%”¤fh„ff– ?śŸż™˜Q5“”„ffŽ‘.ÉNo‘+8Ÿfh„ffŽŸ½c‘W¹cE3ŽŽŽ‘rxŸfh„ffŽŸ³’…™9ŽŽŽ’œ7,Ÿfh„ffŽŸÅr’ÆY(5ŽŽŽ’Å”æŸfh„ffŽŽ¦„ffE%7ŽŽŸ32¤fh„ff– ?śŸż™˜Q6“”„ffŽ‘-5Y‘’LĢes‘ ZwŸfh„ffŽ‘rxŸfh„ffŽ’œ7+Ÿfh„ffŽ’Å”æŸfh„ffŽŽ¦‰ffÅū%”¤fh„ff– ?śŸż™˜Q7“”„ffŽ‘.ÉNo‘+8Ÿfh„ffŽŸĘŹ‘W¹cE4ŽŽŽ‘rxŸfh„ffŽŸ½c’ƒŁ16ŽŽŽ’œ7,Ÿfh„ffŽŸ³‰’ÆY(7ŽŽŽ’Å”æŸfh„ffŽŽ¦„ffE%7ŽŽŸ32¤fh„ff– ?śŸż™˜Q8“”„ffŽ‘-5Y‘’LĢes‘ ZwŸfh„ffŽ‘rxŸfh„ffŽ’œ7+Ÿfh„ffŽ’Å”æŸfh„ffŽŽŸęh‰€Åū%ŽŽŽŸ:ćՍ’5;¹T‘’LŠable–€3:‘TxQueries“used“in“experimentsŽŽŽŽŽ Ü»į žAD‘ņs impl‘™˜‰ffŽ‘™šrules–˜³that“are“matched“by“each“expression.‘ ž‘TheseŽ¤ ‘ņs are–ž®the“rules“whose“left“hand“sides“match“a“sub-expression.Ž”‘ņs However™Ÿ,‘·7not–¬,all“the“rules“were“necessarily“applicable.‘ŲūForŽ”‘ņs instance,‘4Żan–±impl‘™˜‰ffŽ‘™šrule“with“an“index“scan“would“not“applyŽ”‘ņs to–€Q3,“although“it“might“apply“to“Q4.Ž© slightly“worse“due“to“the“larŃšger“number“of“źmallocŽ”’ö+r¹calls–Źžthat“the“P2V‘Ź‹translator“introduces.‘4SAlso,‘ŻFnote“that“weŽ”’ö;could–s`only“go“up“to“3-way“joins“before“virtual“memory“wasŽ”’ö+rexhausted.‘1As–½čthe“available“memory“decreases,‘Ķcthere“is“in-Ž”’õ vcreased– ¦thrashing“(as“shown“by“the“sharp“changes“in“slope“inŽ”’ö+rthe–€plots)“resulting“in“a“much“slower“optimization“process.Ž¦’+sIn–Ėall“four“sets“of“plots,‘ŻŌwe“can“see“that“Prairie“performsŽ”’ö+rwith–» almost“(less“than“²5%“¹variation)“the“same“eciency“asŽ”’ö+rV‘žµĒolcano.‘±üIn–Ÿ,extreme“cases,›¦÷when“memory“is“scarce,˜PrairieŽ”’õʟruns–,Rmore“slowly“(about“²15%¹)“(e.g.,›=Figure“7(f)),˜but“we“be-Ž”’ö+rlieve–athat“this“situation“already“represents“a“serious“bottle-Ž”’ö+rneck–€for“both“V‘žµĒolcano“and“Prairie.Ž¦’’_ The–Ö[results“presented“in“this“section“show“that“Prairie“opti-Ž”’õ©mizers–žµneed“not“sacri ce“eciency“for“clarity‘’Y ,‘‘even“for“larŃšgeŽ”’õƒtrule–ō“sets.‘%’More“research“and“validation“is“necessary“to“verifyŽ”’ö+rthat–€Prairie“is“an“ecient“tool“for“optimizer“speci cation.ŽŸ$īx’ö+rŁ5Ž’ Å Related‘™™r•½«esear“chŽŸmĻ’õį¹The–BFSystem“R‘B7optimizer“[1”G1]“was“the“most“important“devel-Ž”’ö+ropment–›in“query“optimization“research.‘§NIt“was“a“cost-basedŽ”’ö+rcentralized–Ś„relational“query“optimizer“and“introduced“a“va-Ž”’ö+rriety–/sof“key“concepts“like“\interesting"“expressions,‘[Ocardi-Ž”’ö Enality–v¹estimation“using“selectivity“factors“and“dynamic“pro-Ž”’ö+rgramming–Ćwith“pruning“of“search“space.‘±These“conceptsŽ”’ö+rcontinue–€to“be“important“in“query“optimizer“research.Ž¦’+sThe–®query“optimizer“in“RŸü^’·Ž‘G¹[3]“works“in“essentially“theŽ”’õžsame– ™way“as“that“of“System“R,“except“that“RŸü^’·Ž‘£}¹is“a“distributedŽ”’ö+rdatabase–łsystem“which“introduces“some“subtle“complica-ŽŽŽŽŽŽŽŒ‹ ģ| —ßż żGš šep ’jŗĻŸŻ× ’!„X‘ó†é ’ź¾‰ffčū ½*„„½*„ff ’#ź¾ ’r¾‘ż¶ļQPSfile="runtime_Q1.ps" llx=50.1875 lly=50.1875 urx=501.875 ury=376.40625 rwi=850 ŽŽŽŽŽŸn–‘,;ūŌ(a)–Query“1ŽŽŽŽ’TŁļQPSfile="runtime_Q2.ps" llx=50.1875 lly=50.1875 urx=501.875 ury=376.40625 rwi=850 ŽŽŽŽŽŸn–’™YÄ(b)–Query“2ŽŽŽŽŽ‘¤U‰ffŚ®F©Sd‘ ż¶ļQPSfile="runtime_Q3.ps" llx=50.1875 lly=50.1875 urx=501.875 ury=376.40625 rwi=850 ŽŽŽŽŽŸn–‘$;ū(c)–Query“3ŽŽŽŽ‘yTŁļQPSfile="runtime_Q4.ps" llx=50.1875 lly=50.1875 urx=501.875 ury=376.40625 rwi=850 ŽŽŽŽŽŸn–’‘YÄ(d)–Query“4ŽŽŽŽŽ”‰ffŚ®F¦‘ ż¶ļQPSfile="runtime_Q5.ps" llx=50.1875 lly=50.1875 urx=501.875 ury=376.40625 rwi=850 ŽŽŽŽŽŸ‘$;ū(e)–Query“5ŽŽŽŽ‘yTŁļQPSfile="runtime_Q6.ps" llx=50.1875 lly=50.1875 urx=501.875 ury=376.40625 rwi=850 ŽŽŽŽŽŸn–’’Ē(f)–Query“6ŽŽŽŽŽŸ”æ‰ffŚ®F¦‘ ż¶ļQPSfile="runtime_Q7.ps" llx=50.1875 lly=50.1875 urx=501.875 ury=376.40625 rwi=850 ŽŽŽŽŽŸn–‘$”(g)–Query“7ŽŽŽŽ‘yTŁļQPSfile="runtime_Q8.ps" llx=50.1875 lly=50.1875 urx=501.875 ury=376.40625 rwi=850 ŽŽŽŽŽŸn–’‘YÄ(h)–Query“8ŽŽŽŽŽŽŽŽŽŽ’č.F„½*„ffŽžff‰ffčūŽŽŽŽ’ÜNČ Ž{؄½÷P33ŽŽ Ž{؍‘õ†é‰33čūŽŽŽŸ‘ūq„¹Figure–€7:‘TxQuery“optimization“times“for“Q1“through“Q8ŽŽŽŸ.!‘ņs tions–€in“its“query“optimizer‘’s8.ŽŸ ‘üs The–õnStarburst“query“optimizer“[10]“uses“rules“for“all“de-Ž¤ ‘ņs cisions–T:that“need“to“be“taken“by“the“query“optimizer‘’s8.‘Ń&TheŽ”‘ņŽrules–.…are“functional“in“nature“and“transform“a“given“operatorŽ”‘ņs tree–…into“another‘’s8.‘e The“rules“are“commonly“those“that“re ectŽ”‘ņs relational–e­calculus“facts.‘€In“Starburst,‘Ÿthe“query“rewritingŽ”‘ņs phase–¼¤is“di erent“from“the“optimization“phase.‘ cThe“rewrit-Ž”‘ń¬/ing–Śōphase“transforms“the“query“itself“into“equivalent“operatorŽ”‘ņs trees–›Ÿbased“on“relational“calculus“rules.‘§TThe“plan“optimiza-Ž”‘ņ=Ątion–SÅphase“selects“algorithms“for“each“operator“in“the“opera-Ž”‘ņ:rtor–Qtree“that“is“obtained“after“rewriting.‘DŠThe“disadvantage“ofŽ”‘ņs separating–Åøthe“query“rewrite“and“the“optimization“phases“isŽŽŽ żˆš’õ×dthat–:=pruning“of“the“search“space“is“not“possible“during“queryŽ¤ ’ö+rrewrite,–€since“the“rewrite“phase“is“non-cost-based.Ž© Ņ’+sFreytag–ŚH[6]“describes“a“rule-based“query“optimizer“simi-Ž”’ö+rlar–’Ńto“Starburst.‘ŒėThe“rules“are“based“on“LISP-like“represen-Ž”’õÆ¢tations–>of“access“plans.‘28The“rules“themselves“are“recursivelyŽ”’ö+rde ned–Ton“smaller“expressions“(operator“trees).‘ŠĖAlthoughŽ”’ö+rseveral–Ńmexpressions“can“contain“a“common“sub-expression,Ž”’ö&Freytag–{doesn'Ńšt“consider“the“possibility“of“sharing.‘RżExpres-Ž”’ö+rsions–ŸŚare“evaluated“each“time“they“are“encountered.‘“This“isŽ”’õĒobviously–,©inecient.‘8±In“addition,›=Tas“in“Starburst,˜he“doesn'ŃštŽ”’ö+rconsider–¢0the“cost“transformations“inherent“in“any“query“op-Ž”’ö+rtimizer;–€rules“are“syntactic“transformation“rules.Ž¦’+sEXODUS‘…[9]–provides“an“optimizer“generator“which“ac-Ž”’ö+rcepts–ķya“rule-based“speci cation“of“the“data“model“as“input.Ž”’öäThe–`optimizer“generator“compiles“these“rules,‘fgtogether“withŽ”’õš0pre-de ned–NŅrules,‘XØto“generate“an“optimizer“for“the“particularŽ”’ö+rdata–#Ymodel“and“set“of“operators.‘>ƒUnlike“Freytag,‘L/the“opti-Ž”’ömizer–`generator“for“EXODUS›`allows“for“C˜code“along“withŽ”’õVŖde nitions–Ļgof“new“rules.‘›This“allows“the“database“implemen-Ž”’õ™Ćtor–the“freedom“to“associate“any“action“with“a“particular“rule.Ž”’õŲwOperator–;!trees“in“EXODUS‘;are“constructed“bottom-up“fromŽ”’ö+rpreviously–€constructed“trees.Ž¦’’ƒThe–ō§V‘žµĒolcano“optimizer“generator“project“[7]“evolved“fromŽ”’ö+rthe–²‡EXODUS‘²zproject.‘ģIt“is“di erent“from“all“the“above“op-Ž”’ö+rtimizers–ž.in“one“signi cant“way:‘PŌit“is“a“top-down“optimizerŽ”’õõ“compared–SJwith“the“bottom-up“strategy“of“the“others.‘E‘Opera-Ž”’õČætor–.trees“are“optimized“starting“from“the“root“while“sub-treesŽ”’õā{are–Cqnot“yet“optimized.‘@IThis“leads“to“a“constraint-driven“gen-Ž”’ö+reration–õ¼of“the“search“space.‘µ¬While“this“method“results“in“aŽ”’õ³)tight–+control“of“the“search“space,‘0#it“is“unconventional“and“re-Ž”’ö+rquires–careful“attention“on“the“part“of“the“optimizer“imple-Ž”’ö#Mmentor–y>to“ensure“that“legal“operator“trees“are“not“accidentlyŽ”’ö+rleft–åout“of“the“search“space.‘(W‘’37e“have“used“V‘žµĒolcano“as“ourŽ”’ö+rback-end–€search“engine.ŽŸ'-m’ö+rŁ6Ž’ Å Conclusion–™™and“futur½«e“workŽŸ4½’ö+r¹Current– rule-based“query“optimizers“do“not“provide“a“veryŽ”’ö+rintuitive–•³and“conceptually“streamlined“framework“to“de neŽ”’ö+rrules–<”and“actions.‘ŠZOur“experiences“with“the“V‘žµĒolcano“opti-Ž”’ö+rmizer–žńgenerator“suggest“that“its“model“of“rules“and“the“ex-Ž”’ö+rpression–SŽof“these“rules“is“much“more“complicated“and“tooŽ”’ö›low-level–]Fthan“it“needs“to“be.‘HåAs“a“consequence,‘d8rule“sets“inŽ”’öV‘žµĒolcano–oare“fragile,›r€hard“to“write,˜and“debug.‘NŲSimilar“prob-Ž”’ö+rlems––may“exist“in“other“contemporary“rule-based“query“op-Ž”’ö+rtimizers.Ž¦’¾W‘’37e–iÖbelieve“that“rule-based“query“optimizers“will“be“stan-Ž”’ö+rdard–Ź·tools“of“future“database“systems.‘4The“pragmatic“di-Ž”’ö+rculties–„Ķof“using“existing“rule-based“optimizers“led“us“to“de-Ž”’ö+rvelop–“Prairie,‘—Ēan“extensible“and“structured“algebraic“frame-Ž”’ö+rwork–ß for“specifying“rules.‘sYPrairie“is“similar“to“existing“op-Ž”’ö+rtimizers–Äin“that“it“supports“both“transformation“rules“andŽŽŽŽŽŽŒ‹ O/ —ßż żGš šep żˆš‘ņs ¹implementation–źrules.‘’¼However™Ÿ,‘œPrairie“makes“several“im-Ž¤ ‘ņs provements:ŽŸˆ¤‘łó 1.ŽŽŽ‘s it–ÆPo ers“a“conceptually“more“streamlined“model“for“ruleŽ”‘s speci cation;Ž©¶0‘łó 2.ŽŽŽ‘s rules–Aare“encapsulated,‘M¦there“are“no“\hidden"“operatorsŽ”‘s or–€\hidden"“algorithms;Ž¦‘łó 3.ŽŽŽ‘s implementation–”hints“(e.g.,‘©aenforcers)“are“deduced“au-Ž”‘s tomatically;Ž¦‘łó 4.ŽŽŽ‘s and–€it“has“ecient“implementations.ŽŸˆ¤‘üs W‘’37e–Żhave“explained“how“the“ rst“three“points“are“imporĢŠ-Ž”‘ņ`¤tant–pŗfor“simplifying“rule“speci cations“and“making“rule“setsŽ”‘ņs less–H1brittle“for“extensibility‘’Y .‘­ A‘Gżconsequence“is“that“PrairieŽ”‘ņs rules–are“simpler“and“more“robust“than“rules“of“existing“op-Ž”‘ņs timizers– (e.g.,‘0ōV‘žµĒolcano).‘ż)W‘’37e“addressed“the“fourth“point“byŽ”‘ņs building–?>a“P2V‘? pre-processor“which“uses“sophisticated“al-Ž”‘ņs gorithms–7„to“compose“and“compact“a“Prairie“rule“set“into“aŽ”‘ņs V‘žµĒolcano–ōrule“set.‘²&T‘’LŠo“demonstrate“the“scalability“of“our“ap-Ž”‘ņrÅproach,‘Ńwe–Årewrote“the“TI“Open“OODB“rule“set“as“a“PrairieŽ”‘ņUirule–ghset,›lSgenerated“its“V‘žµĒolcano“counterpart,˜and“showed“thatŽ”‘ņg&the–v performance“of“the“synthesized“V‘žµĒolcano“rule“set“closelyŽ”‘ņs matches–€the“hand-crafted“V‘žµĒolcano“rule“set.ŽŸ -Œ‘üs Our–2Įfuture“work“will“concentrate“on“developing“higherĢŠ-Ž”‘ń•·level–ČOabstractions“using“Prairie,‘ķ including“automatically“gen-Ž”‘ņerating–1’Prairie“rule“sets,‘A™and“combining“multiple“Prairie“ruleŽ”‘ņs sets–€to“automatically“generate“ecient“optimizers.Ž©"§©‘ņs ŁAcknowledgmentsŽŸ¤+‘ņs ¹W‘’37e–„Üwish“to“thank“T‘’LŠexas“Instruments,‘ļTInc.“for“making“theŽ”‘ńŖQOpen–ŁhOODB‘Ł>source“code“available“to“us.‘ńComments“by“Jos‘ŽžńģŽeŽ”‘ņs Blakeley‘’Y ,–Anne›ó3Ngu,“V‘’fgivek˜Singhal,“Thomas˜W‘’37oo˜and˜theŽ”‘ņranonymous–8referees“greatly“improved“the“quality“of“the“pa-Ž”‘ņs per‘’s8.Ž¦‘ņs ŁRefer½«encesŽŸ¤+‘÷s ¹[1]ŽŽ‘ūD.–Ž`S.“Batory‘’Y .‘o„Building“blocks“of“database“managementŽ”‘ūsystems.‘-T‘’LŠechnical–EeReport“TR{87{23,‘QThe“UniversityŽ”‘ūof–€T‘’LŠexas“at“Austin,“February“1988.Ž©¶0‘÷s [2]ŽŽ‘ūJos‘ŽžńģŽe–röA.“Blakeley‘’Y ,›ļ“W™Ÿilliam“J.“McKenna,˜and“GoetzŽ”‘ūGraefe.‘×KExperiences–æŲbuilding“the“Open“OODB‘æĒqueryŽ”‘ūoptimizer‘’s8.‘^ŁIn–`!ŗPr”Goceedings“1993“ACM–`SIGMOD“InterĢŠ-Ž”‘ūnational–{ĻConfer”Gence“on“Management“of“Data¹,‘ŗĆpagesŽ”‘ū287{296,–€W‘’37ashington,“May“1993.Ž¦‘÷s [3]ŽŽ‘ūDean–:Daniels,›yHPatricia“Selinger™Ÿ,˜Laura“Haas,˜BruceŽ”‘ūLindsay‘’Y ,–6gC.›ģMohan,“Adrian˜W‘’37alker™Ÿ,“and˜Paul˜W™Ÿilms.Ž”‘ūAn–¬Jintroduction“to“distributed“query“compilation“in“RŸü^’·Ž‘˜ä¹.ŽŽŽ żˆš’ ŌbIn–ĢøŗPrš”Goceedings“2nd“International“Confer˜ence“on“Dis-Ž¤ ’ Ōbtributed–tVDatabases¹,›±kpages“291{309,˜Berlin,˜Septem-Ž”’ Ōbber‘€1982.Ž©’ū+r[4]ŽŽ’ ŌbDinesh–˜ŸDas“and“Don“Batory‘’Y .‘ Prairie:‘…¶An“algebraicŽ”’ Ōbframework–ęĄfor“rule“speci cation“in“query“optimiz-Ž”’ Ōbers.‘ 8LIn–ŗPr”Goceedings“of“the“W‘’orkshop“on“DatabaseŽ”’ ŌbQuery–ćOptimizer“Generators“and“Rule-Based“Optimiz-Ž”’ Ōbers¹,–€pages“139{154,“Dallas,“September“1993.Ž¦’ū+r[5]ŽŽ’ ŌbDinesh–}~Das“and“Don“Batory‘’Y .‘‡Prairie:‘OtA‘}=rule“speci-Ž”’ Ōb cation– Ūframework“for“query“optimizers.‘ 6ūT‘’LŠechnicalŽ”’ ŌbReport–ĒŸTR‘ĒŒ94{16,‘Ł‡The“University“of“T‘’LŠexas“at“Austin,Ž”’ ŌbMay‘€1994.Ž¦’ū+r[6]ŽŽ’ ŌbJohann–GChristoph“Freytag.‘ĻTA‘+rule-based“view“of“queryŽ”’ Ōboptimization.‘ ńIn–Ę=ŗPr”Goceedings“1987“ACM‘ÅéSIGMODŽ”’ ŌbInternational–åCConfer”Gence“on“Management“of“Data¹,Ž”’ Ōbpages–€173{180,“San“Francisco,“May“1987.Ž¦’ū+r[7]ŽŽ’ ŌbGoetz–ĮGraefe.‘ †£V‘žµĒolcano,‘}±an“extensible“and“parallelŽ”’ Ōbquery–fevaluation“system.‘mT‘’LŠechnical“Report“CU{CS{Ž”’ Ōb481{90,›"ÕUniversity– Šof“Colorado“at“Boulder™Ÿ,˜July“1990.Ž¦’ū+r[8]ŽŽ’ ŌbGoetz–żņGraefe.‘ RQuery“evaluation“techniques“for“larŃšgeŽ”’ Ōbdatabases.‘ ŗACM‘gįComputing‘hSurveys¹,‘¢$25(2):73{170,Ž”’ ŌbJune‘€1993.Ž¦’ū+r[9]ŽŽ’ ŌbGoetz–¬•Graefe“and“David“J.“DeW™Ÿitt.‘ qVThe“EXODUSŽ”’ Ōboptimizer–×3generator‘’s8.‘K„In“ŗPr”Goceedings“1987“ACM‘×SIG-Ž”’ ŌbMOD‘ÖóInternational–׎Confer”Gence“on“Management“ofŽ”’ ŌbData¹,–€pages“387{394,“San“Francisco,“May“1987.Ž¦’ö+r[10]ŽŽ’ ŌbL.–Ł~M.“Haas,›ļŻJ.“C.“Freytag,˜G.“M.“Lohman,˜and“H.“Pi-Ž”’ Ōbrahesh.›ü÷Extensible–“ųquery“processing“in“Starburst.˜Re-Ž”’ Ōbsearch–’LReport“RJ–’H6610,‘–ßIBM“Almaden–’LResearch“Cen-Ž”’ Ōbter™Ÿ,–€December“1988.Ž¦’öŠ+[1”G1]ŽŽ’ ŌbP‘žć×.–¤G.“Selinger™Ÿ,›cMM.“M.“Astrahan,˜D.“D.“Chamberlin,Ž”’ ŌbR.–uA.“Lorie,‘²Aand“T‘’B.“G.“Price.‘\ÅAccess“path“selectionŽ”’ Ōbin–ļÆa“relational“database“management“system.‘Å\In“ŗPr”Go-Ž”’ Ōbceedings–yT1979“ACM–ySIGMOD“International‘yTConferĢŠ-Ž”’ Ōbence–NĮon“Management“of“Data¹,›‚rpages“23{34,˜Boston,Ž”’ ŌbMay‘€1979.Ž¦’ö+r[12]ŽŽ’ ŌbMichael–ÖStonebraker“and“Lawrence“A.“Rowe.‘ ?uTheŽ”’ Ōbdesign–=of“Postgres.‘F©In“ŗPr”Goceedings“1986“ACM‘<ģSIG-Ž”’ ŌbMOD‘ÖóInternational–׎Confer”Gence“on“Management“ofŽ”’ ŌbData¹,–€pages“340{355,“W‘’37ashington,“May“1986.ŽŽŽŽŽŽŒųefƒ’Ą;č—ßżćN>" ó?Ė»X« pcrr7tó<«-Œhcmbx5ó;f$Ųcmbx7ó:ņ"V cmbx10ó9 $S ptmrc7tó8B®vö ptmb7tó7LméV ptmri7tó6LméV ptmri7tó5& ptmr7tó3& ptmr7tó0B®vö ptmb7tó/B®vö ptmb7tó.B®vöff ptmb7tó,Ė»X« pcrr7tó)& ptmr7tó$q”% cmsy6ó!×2cmmi8ó ¹AaØcmr6ó|{Ycmr8ó& ptmr7tó—³īĶ msam10ó!",š cmsy10óB®vöG® ptmb7tóLméV ptmri7tó& ptmr7tó !",š cmsy10ó O!ā…cmsy7ó °Ü0ncmsy5ó  b> cmmi10ó 0e—rcmmi7óO Ś\cmmi5óKń`y cmr10óŁ“ Rcmr7ó†›Zcmr5łzZßßßß