﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-活在JAVA岛的快乐日子-文章分类-DATABASE</title><link>http://www.blogjava.net/hmily1211/category/19536.html</link><description /><language>zh-cn</language><lastBuildDate>Tue, 27 Feb 2007 12:33:25 GMT</lastBuildDate><pubDate>Tue, 27 Feb 2007 12:33:25 GMT</pubDate><ttl>60</ttl><item><title>IN OR  EXISTS  IT IS A QUESTTION. (QUOTE)</title><link>http://www.blogjava.net/hmily1211/articles/96154.html</link><dc:creator>活在JAVA岛的日子</dc:creator><author>活在JAVA岛的日子</author><pubDate>Fri, 26 Jan 2007 06:55:00 GMT</pubDate><guid>http://www.blogjava.net/hmily1211/articles/96154.html</guid><wfw:comment>http://www.blogjava.net/hmily1211/comments/96154.html</wfw:comment><comments>http://www.blogjava.net/hmily1211/articles/96154.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hmily1211/comments/commentRss/96154.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hmily1211/services/trackbacks/96154.html</trackback:ping><description><![CDATA[IN和EXISTS 
<p>有时候会将一列和一系列值相比较。最简单的办法就是在where子句中使用子查询。在where子句中可以使用两种格式的子查询。 </p><p>第一种格式是使用IN操作符： </p><p>... where column in(select * from ... where ...); </p><p>第二种格式是使用EXIST操作符： </p><p>... where exists (select 'X' from ...where ...); </p><p>我相信绝大多数人会使用第一种格式，因为它比较容易编写，而实际上第二种格式要远比第一种格式的效率高。在Oracle中可以几乎将所有的IN操作符子查询改写为使用EXISTS的子查询。 </p><p>第二种格式中，子查询以‘select 'X'开始。运用EXISTS子句不管子查询从表中抽取什么数据它只查看where子句。这样优化器就不必遍历整个表而仅根据索引就可完成工作（这里假定在where语句中使用的列存在索引）。相对于IN子句来说，EXISTS使用相连子查询，构造起来要比IN子查询困难一些。 </p><p>通过使用EXIST，Oracle系统会首先检查主查询，然后运行子查询直到它找到第一个匹配项，这就节省了时间。Oracle系统在执行IN子查询时，首先执行子查询，并将获得的结果列表存放在在一个加了索引的临时表中。在执行子查询之前，系统先将主查询挂起，待子查询执行完毕，存放在临时表中以后再执行主查询。这也就是使用EXISTS比使用IN通常查询速度快的原因。 </p><p>同时应尽可能使用NOT EXISTS来代替NOT IN，尽管二者都使用了NOT（不能使用索引而降低速度），NOT EXISTS要比NOT IN查询效率更高。<br /><br />EXISTS检查是否有结果，判断是否有记录，返回的是一个布尔型（TRUE/FALSE）。<br />IN是对结果值进行比较，判断一个字段是否存在于几个值的范围中，所以 EXISTS 比 IN 快。</p><p><br />主要区别是:<br />exists主要用于片面的,有满足一个条件的即可,<br />in主要用于具体的集合操作,有多少满足条件. </p><p>exists是判断是否存在这样的记录，<br />in是判断某个字段是否在指定的某个范围内。<br />exists快一些吧 。</p><p><br /></p><p>in适合内外表都很大的情况，exists适合外表结果集很小的情况。</p><p><br />在ASKTOM的讲解：<br />Well, the two are processed very very differently.</p><p>Select * from T1 where x in ( select y from T2 )</p><p>is typically processed as:</p><p>select * <br />from t1, ( select distinct y from t2 ) t2<br />where t1.x = t2.y;</p><p>The subquery is evaluated, distinct'ed, indexed (or hashed or sorted) and then <br />joined to the original table -- typically.</p><p><br />As opposed to </p><p>select * from t1 where exists ( select null from t2 where y = x )</p><p>That is processed more like:</p><p><br />for x in ( select * from t1 )<br />loop<br />if ( exists ( select null from t2 where y = x.x )<br />then <br />OUTPUT THE RECORD<br />end if<br />end loop</p><p>It always results in a full scan of T1 whereas the first query can make use of <br />an index on T1(x).</p><p><br />So, when is where exists appropriate and in appropriate?</p><p>Lets say the result of the subquery<br />( select y from T2 )</p><p>is "huge" and takes a long time. But the table T1 is relatively small and <br />executing ( select null from t2 where y = x.x ) is very very fast (nice index on <br />t2(y)). Then the exists will be faster as the time to full scan T1 and do the <br />index probe into T2 could be less then the time to simply full scan T2 to build <br />the subquery we need to distinct on.</p><p><br />Lets say the result of the subquery is small -- then IN is typicaly more <br />appropriate.</p><p><br />If both the subquery and the outer table are huge -- either might work as well <br />as the other -- depends on the indexes and other factors.</p><img src ="http://www.blogjava.net/hmily1211/aggbug/96154.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hmily1211/" target="_blank">活在JAVA岛的日子</a> 2007-01-26 14:55 <a href="http://www.blogjava.net/hmily1211/articles/96154.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>EXISTS and NOT EXISTS</title><link>http://www.blogjava.net/hmily1211/articles/96153.html</link><dc:creator>活在JAVA岛的日子</dc:creator><author>活在JAVA岛的日子</author><pubDate>Fri, 26 Jan 2007 06:45:00 GMT</pubDate><guid>http://www.blogjava.net/hmily1211/articles/96153.html</guid><wfw:comment>http://www.blogjava.net/hmily1211/comments/96153.html</wfw:comment><comments>http://www.blogjava.net/hmily1211/articles/96153.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hmily1211/comments/commentRss/96153.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hmily1211/services/trackbacks/96153.html</trackback:ping><description><![CDATA[
		<h4>
				<code>EXISTS</code> and <code>NOT EXISTS</code></h4>
		<p>If a subquery returns any values at all, then <code>EXISTS &lt;subquery&gt;</code> is <code>TRUE</code>, and <code>NOT EXISTS &lt;subquery&gt;</code> is <code>FALSE</code>. For example:</p>
		<pre>SELECT column1 FROM t1 WHERE EXISTS (SELECT * FROM t2);
</pre>
		<p>Traditionally an <code>EXISTS</code> subquery starts with <code>SELECT *</code> but it could begin with <code>SELECT 5</code> or <code>SELECT column1</code> or anything at all -- MySQL ignores the <code>SELECT</code> list in such a subquery, so it doesn't matter.</p>
		<p>For the above example, if <code>t2</code> contains any rows, even rows with nothing but <code>NULL</code> values, then the <code>EXISTS</code> condition is <code>TRUE</code>. This is actually an unlikely example, since almost always a <code>[NOT] EXISTS</code> subquery will contain correlations. Here are some more realistic examples.</p>
		<p>Example: What kind of store is present in one or more cities? </p>
		<pre>SELECT DISTINCT store_type FROM Stores
  WHERE EXISTS (SELECT * FROM Cities_Stores
                WHERE Cities_Stores.store_type = Stores.store_type);
</pre>
		<p>Example: What kind of store is present in no cities? </p>
		<pre>SELECT DISTINCT store_type FROM Stores
  WHERE NOT EXISTS (SELECT * FROM Cities_Stores
                    WHERE Cities_Stores.store_type = Stores.store_type);
</pre>
		<p>Example: What kind of store is present in all cities? </p>
		<pre>SELECT DISTINCT store_type FROM Stores S1
  WHERE NOT EXISTS (
    SELECT * FROM Cities WHERE NOT EXISTS (
      SELECT * FROM Cities_Stores
       WHERE Cities_Stores.city = Cities.city
       AND Cities_Stores.store_type = Stores.store_type));
</pre>
		<p>The last example is a double-nested <code>NOT EXISTS</code> query -- it has a <code>NOT EXISTS</code> clause within a <code>NOT EXISTS</code> clause. Formally, it answers the question ``does a city exist with a store which is not in Stores?''. But it's easier to say that a nested <code>NOT EXISTS</code> answers the question ``is x TRUE for all y?''.</p>
<img src ="http://www.blogjava.net/hmily1211/aggbug/96153.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hmily1211/" target="_blank">活在JAVA岛的日子</a> 2007-01-26 14:45 <a href="http://www.blogjava.net/hmily1211/articles/96153.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>