<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>OS与Oracle &#187; tree</title>
	<atom:link href="http://www.os2ora.com/tag/tree/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.os2ora.com</link>
	<description>专注于现实世界Oracle数据库的高性能，高可扩展性与新一代数据库Exadata架构</description>
	<lastBuildDate>Fri, 16 Jul 2010 02:55:51 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>connect by的性能分析</title>
		<link>http://www.os2ora.com/connect-by-performance-tunning/</link>
		<comments>http://www.os2ora.com/connect-by-performance-tunning/#comments</comments>
		<pubDate>Mon, 23 Mar 2009 11:52:03 +0000</pubDate>
		<dc:creator>Kaya</dc:creator>
				<category><![CDATA[Oracle SQL 扩展]]></category>
		<category><![CDATA[数据库性能调优]]></category>
		<category><![CDATA[connect by]]></category>
		<category><![CDATA[distinct]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[tree]]></category>

		<guid isPermaLink="false">http://www.os2ora.com/connect-by-performance-tunning/</guid>
		<description><![CDATA[对上一篇文章里提到两条语句 
select distinct begin_date, end_date, begin_date + level -1 day  from test connect by begin_date + level -1 <= end_date order by 1,2,3; 
和 
select one_date 
  from (select start_date + level - 1 one_date 
          from (select min(start_date) start_date, max(end_date) end_date 
                  from test) test 
        connect by start_date + level - 1 < = end_date ) all_date, 
       test 
where one_date between start_date and end_date; 

它们都实现相同的功能，即: 当一个表里面有两个列，分别为begin_date和end_date时，如何针对这个表的每一行，用SQL返回begin_date和end_date之间的所有连续日期。 

这两条语句的可扩展性问题是下面是讨论的重点......]]></description>
			<content:encoded><![CDATA[<p>Kaya 发表于 <a href="http://www.os2ora.com">os2ora.com</a></p>
<p>对上一篇文章里提到两条语句<br />
select distinct begin_date, end_date, begin_date + level -1 day  from test connect by begin_date + level -1 &lt;= end_date order by 1,2,3;<br />
和<br />
select one_date<br />
  from (select start_date + level &#8211; 1 one_date<br />
          from (select min(start_date) start_date, max(end_date) end_date<br />
                  from test) test<br />
        connect by start_date + level &#8211; 1 &lt; = end_date ) all_date,<br />
       test<br />
where one_date between start_date and end_date;</p>
<p>它们都实现相同的功能，即: 当一个表里面有两个列，分别为begin_date和end_date时，如何针对这个表的每一行，用SQL返回begin_date和end_date之间的所有连续日期。</p>
<p>首先，我们关注第一条语句在没有distinct的情况下返回的行数。</p>
<p>会使问题简单化，假设对于表里的每行数据，end_date &#8211; begin_date + 1 的值都是一样的，设为 n 。假设test里总共有 m 行(m&gt;1)。<br />
那么，这时返回的行数是 m * ( power(m,n) &#8211; 1 )/( m &#8211; 1 ) 。<br />
(<br />
这是一个等比数列，公式为<br />
1 +  m +  power(m,2) + &#8230;.  power(m,n-1) = ( 1 &#8211; power (m,n)) / (1 &#8211; m),<br />
)<br />
这些行可以用一系列的树加以形象的表示，如下所示：</p>
<p><a href="http://www.os2ora.com/wp-content/uploads/2009/03/connectby.jpg"><img style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" title="connectby" src="http://www.os2ora.com/wp-content/uploads/2009/03/connectby-thumb.jpg" border="0" alt="connectby" width="627" height="181" /></a></p>
<p>当 n 和 m 很大时，会使结果集变得非常之大，为 power(m,n).</p>
<p>因此，下面语句在数据量变大的情况下，性能将急剧下降!<br />
select distinct begin_date, end_date, begin_date + level -1 day  from test connect by begin_date + level -1 &lt;= end_date order by 1,2,3;</p>
<p>对于语句2，我们关注以下子查询所返回的行数:<br />
select start_date + level &#8211; 1 one_date<br />
          from (select min(start_date) start_date, max(end_date) end_date<br />
                  from test) test<br />
        connect by start_date + level &#8211; 1 &lt; = end_date</p>
<p>这时，表实质上只有1行时，存贮的是原来表的最大值和最小值。也就是说，这时 m = 1 。</p>
<p>当m=1时，情况变得不同了。这时，返回的行数刚好就是 n 。<br />
如果以树加以表示的话，这时上面的图形已经退化成一棵只有一个支干的树。</p>
<p><a href="http://www.os2ora.com/wp-content/uploads/2009/03/image4.png"><img style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" title="image" src="http://www.os2ora.com/wp-content/uploads/2009/03/image-thumb4.png" border="0" alt="image" width="251" height="184" /></a></p>
<p>因此，当原来的查询m 和 n都很大时，返回的行数为 将为n。</p>
<p>从上面的表述可清晰地看出，语句2在大数据量的情形下将能体现出良好的性能。</p>
<p>从另一方面看，出现distinct的地方，或许就是性能调整应该关注的地方了。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.os2ora.com/connect-by-performance-tunning/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Oracle的层次结构化查询 &#8212; 基础篇</title>
		<link>http://www.os2ora.com/hierarchical-queries-basic/</link>
		<comments>http://www.os2ora.com/hierarchical-queries-basic/#comments</comments>
		<pubDate>Wed, 18 Mar 2009 09:50:41 +0000</pubDate>
		<dc:creator>Kaya</dc:creator>
				<category><![CDATA[Oracle SQL 扩展]]></category>
		<category><![CDATA[connect by]]></category>
		<category><![CDATA[connect_by_root]]></category>
		<category><![CDATA[Hierarchical Queries]]></category>
		<category><![CDATA[prior]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[start with]]></category>
		<category><![CDATA[tree]]></category>

		<guid isPermaLink="false">http://www.os2ora.com/hierarchical-queries-basic/</guid>
		<description><![CDATA[虽然Oracle不是一个层次型的数据库，不过它却对层次型应有不错的支持。
层次型应用最常见的是一个公司内部的组织结构。
在计算机科学中，或者更具体地说，在数据结构中，层次型结构是由“树”来描述的。节点之间的关系代表着上下两个层次之间节点的关系，即父子关系。这一般是一对多的关系。
一般地，我们会把这一系列的父子关系存贮到数据库里的一个表里面。
而Oracle的任务，就是要重现这棵树，并实现有关层次关系的运算......]]></description>
			<content:encoded><![CDATA[<p>Kaya 发表于 <a href="http://www.os2ora.com">os2ora.com</a></p>
<p>虽然Oracle不是一个层次型的数据库，不过它却对层次型应有不错的支持。</p>
<p>层次型应用最常见的是一个公司内部的组织结构。</p>
<p>在计算机科学中，或者更具体地说，在数据结构中，层次型结构是由“树”来描述的。节点之间的关系代表着上下两个层次之间节点的关系，即父子关系。这一般是一对多的关系。</p>
<p>一般地，我们会把这一系列的父子关系存贮到数据库里的一个表里面。</p>
<p>而Oracle的任务，就是要重现这棵树，并实现有关层次关系的运算。例如，打印出层次结构图，统计层次结构中每个节点对应的直接子节点数，对应的直接子节点和间接子节点数，统计每个节点的所处的层次。</p>
<p>以公司内部组织结构为例，则要求实现对公司组织结构的重现，统计每位经理所直接管理员工的数目，直接和间接管理员工的数目，每位经理所处的级别，还有，每位经理所管理的所有员工的总有工资的总和，等等。</p>
<p>为了实现这些功能，Oracle引入了几个关键词，connect by, prior 和 start with。connect by实现了表中两个直接层次间数据行的连接，而prior则是用来标记哪个是父节点。start with则代表从哪些节点开始遍历。如下图所示:</p>
<p><a href="http://www.os2ora.com/wp-content/uploads/2009/03/image.png"><img style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" title="image" src="http://www.os2ora.com/wp-content/uploads/2009/03/image-thumb.png" border="0" alt="image" width="479" height="231" /></a></p>
<p>下面是Oracle如何处理connect by 和prior的官方描述<br />
Oracle processes hierarchical queries as follows:<br />
    * A join, if present, is evaluated first, whether the join is specified in the FROM clause or with WHERE clause predicates.<br />
    * The CONNECT BY condition is evaluated.<br />
    * Any remaining WHERE clause predicates are evaluated.</p>
<p>更详细地:<br />
   1. Oracle selects the root row(s) of the hierarchy—those rows that satisfy the START WITH condition.<br />
   2. Oracle selects the child rows of each root row (from all the rows in the table). Each child row must satisfy the condition of the CONNECT BY condition with respect to one of the root rows.<br />
   3. Oracle selects successive generations of child rows. Oracle first selects the children of the rows returned in step 2, and then the children of those children, and so on. Oracle always selects children by evaluating the CONNECT BY condition with respect to a current parent row.<br />
   4. If the query contains a WHERE clause without a join, then Oracle eliminates all rows from the hierarchy that do not satisfy the condition of the WHERE clause. Oracle evaluates this condition for each row individually, rather than removing all the children of a row that does not satisfy the condition.<br />
   5. Oracle returns the rows in the order shown in Figure 9-1. In the diagram, children appear below their parents.</p>
<p>Figure 9-1 Hierarchical Queries</p>
<p><a href="http://www.os2ora.com/wp-content/uploads/2009/03/image1.png"><img style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" title="image" src="http://www.os2ora.com/wp-content/uploads/2009/03/image-thumb1.png" border="0" alt="image" width="262" height="204" /></a></p>
<p>关于第5点，这就是大家熟悉的树的中序遍历算法。而前面的4点，应该说是一个层次遍历。我想我们更应该记住的是第5点，谁知道Oracle内部具体实现时是不是按照前4点的描述呢。</p>
<p>以上面这个图为例子。我们可以利用Oracle的查询语句打印出类似目录树的输出。做为对基础知识的一个实践。</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> hierarchy <span style="color: #66cc66;">&#40;</span>id number<span style="color: #66cc66;">,</span> parent_id number<span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> hierarchy<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span><span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> hierarchy<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> hierarchy<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">7</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> hierarchy<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">9</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> hierarchy<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> hierarchy<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">4</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> hierarchy<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">8</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">7</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> hierarchy<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">10</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">9</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> hierarchy<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">12</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">9</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> hierarchy<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">5</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">4</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> hierarchy<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">6</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">4</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> hierarchy<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">11</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">10</span><span style="color: #66cc66;">&#41;</span>;
col tree format a10
col path format a15
<span style="color: #993333; font-weight: bold;">SELECT</span> level<span style="color: #66cc66;">,</span>rpad<span style="color: #66cc66;">&#40;</span>’<span style="color: #66cc66;">-</span><span style="color: #ff0000;">',level,’-'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">||</span> id tree<span style="color: #66cc66;">,</span> sys_connect_by_path<span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">,</span>’<span style="color: #66cc66;">/</span><span style="color: #ff0000;">') Path, connect_by_root id
from hierarchy
start with parent_id is null
connect by parent_id = prior id;</span></pre></div></div>

<p>输出如下所示:</p>
<p><a href="http://www.os2ora.com/wp-content/uploads/2009/03/image2.png"><img style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" title="image" src="http://www.os2ora.com/wp-content/uploads/2009/03/image-thumb2.png" border="0" alt="image" width="804" height="343" /></a></p>
<p>connect by 和connect_by_root 还有许多有趣的扩展应用。后继文章再详细探讨一下。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.os2ora.com/hierarchical-queries-basic/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
