<?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>MySQL How 2 &#187; where</title>
	<atom:link href="http://www.mysqlhow2.com/tag/where/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.mysqlhow2.com</link>
	<description>MySQL DBA information and helpful tips and tricks to make life easier.</description>
	<lastBuildDate>Wed, 01 Sep 2010 18:15:36 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Having is not a replacement for a where clause!</title>
		<link>http://www.mysqlhow2.com/2010/02/having-is-not-a-replacement-for-a-where-clause/</link>
		<comments>http://www.mysqlhow2.com/2010/02/having-is-not-a-replacement-for-a-where-clause/#comments</comments>
		<pubDate>Sat, 06 Feb 2010 10:00:34 +0000</pubDate>
		<dc:creator>Lee Thompson</dc:creator>
				<category><![CDATA[Formulas]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[having]]></category>
		<category><![CDATA[query]]></category>
		<category><![CDATA[where]]></category>

		<guid isPermaLink="false">http://www.mysqlhow2.com/?p=229</guid>
		<description><![CDATA[Even a query that is checking against an good index will result in a table scan if it is poorly written.Â  It seems some people think that HAVING can be a substitute for WHERE.Â  For example: SELECT word_id FROM forum.wordmatch GROUP BY word_id HAVING COUNT( word_id ) =53805; This seems pretty straightforward; the query is [...]]]></description>
			<content:encoded><![CDATA[<!-- wp-jquery-lightbox, a WordPress plugin by ulfben --> <div class="KonaBody"><p>Even a query that is checking against an good index will result in a table scan if it is poorly written.Â  It seems some people think that HAVING can be a substitute for WHERE.Â  For example:</p>
<pre class="brush: sql;">
SELECT word_id
FROM forum.wordmatch
GROUP BY word_id
HAVING COUNT( word_id ) =53805;
</pre>
<p>This seems pretty straightforward; the query is trying to display how many entries have a word_id (indexed) greater than 53805.Â  But an explain shows that this is a table scan:</p>
<pre class="brush: plain;">
| table | type | possible_keys | key | key_len | ref | rows | Extra |
| wordmatch | index | NULL | word_id | 3 | NULL | 6374529 | Using index |
</pre>
<p>The problem is there is no WHERE clause, and HAVING just controls output.Â  So rewriting the query like so improves the performance by a factor of 10:</p>
<pre class="brush: sql;">
SELECT count( word_id )
FROM forum.wordmatch
WHERE word_id =53805;
</pre>
<pre class="brush: plain;">
| table | type | possible_keys | key | key_len | ref | rows | Extra |
| wordmatch | range | word_id | word_id | 3 | NULL | 641340 | Using where; Using index |
</pre>
<p>To quote mysql.com:</p>
<p>&#8220;Do not use HAVING for items that should be in the WHERE clause&#8221;. For example, do not write the following:</p>
<pre class="brush: sql;">
SELECT col_name FROM tbl_name HAVING col_name = 0;
</pre>
<p>Write this instead:</p>
<pre class="brush: sql;">
SELECT col_name FROM tbl_name WHERE col_name = 0;
</pre>
<p>The HAVING clause can refer to aggregate functions, which the WHERE clause cannot:</p>
<pre class="brush: sql;">
SELECT user, MAX(salary) FROM users
GROUP BY user HAVING MAX(salary) ;
</pre>
<pre class="brush: sql;">
SELECT DISTINCT ac2.category, ac0.name
FROM snaggy.a2_category ac1, snaggy.a2_category ac2, snaggy.a2_catalog ac0
WHERE ac1.category = 'GAME'
AND ac2.vendor_code = ac1.vendor_code
AND ac2.item_id = ac1.item_id
AND ac0.category = ac2.category
ORDER BY ac0.name
</pre>
<pre class="brush: plain;">
| table | type | possible_keys | key | key_len | ref | rows | Extra |
| ac0 | ALL | NULL | NULL | NULL | NULL | 145 |
| ac1 | ALL | category | NULL | NULL | NULL | 2886 | Using where; Using temporary; Using filesort
| ac2 | ALL | category | NULL | NULL | NULL |2886 | Using where |
</pre>
<pre class="brush: sql;">
CREATE TABLE `a2_category` (
`vendor_code` varchar(4) default NULL,
`item_id` int(5) default NULL,
`category` varchar(8) default NULL,
FULLTEXT KEY `category` (`category`)
) TYPE=MyISAM
</pre>
<p>Just adding an index helps makes the same query complete in a realistic timeframe:</p>
<pre class="brush: sql;">
ALTER TABLE a2_category ADD INDEX (item_id);
</pre>
<pre class="brush: plain;">
| table | type | possible_keys | key | key_len | ref | rows | Extra |
| ac0 | ALL | NULL | NULL | NULL | NULL | 145 | Using where |
| ac1 | ALL | item_id,category | NULL | NULL | NULL | 2886 | Using where; Using temporary; Using filesort |
| ac2 | ref | item_id,category | item_id | 5 | ac1.item_id | 3 | Using where |
</pre>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.mysqlhow2.com/2010/02/having-is-not-a-replacement-for-a-where-clause/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
