Bluehost.com Web Hosting $6.95

JOIN performance and subqueries

This is a discussion on JOIN performance and subqueries within the MySQL Database forums, part of the Database Forums category; Suppose I have a table called items, and I have queries Q1, Q2, and Q3 that reduce the number of ...


Go Back   Usenet Forums > Database Forums > MySQL Database

FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 03-11-2007
kggroups
 
Posts: n/a
Default JOIN performance and subqueries

Suppose I have a table called items, and I have queries Q1, Q2, and Q3
that reduce the number of records I am going to look at by a
significant amount. Each of these queries just returns item_id--their
sole purpose is to filter the records I look at in the items table.
In this example, I use the trivial queries:
SELECT item_id FROM items WHERE item_id < 1000;
SELECT item_id FROM items WHERE item_id < 2000;
SELECT item_id FROM items WHERE item_id < 3000;
but you can imagine each Qn is something more complicated than this.

I have played with 2 different ways of applying Q1, Q2, and Q3 to try
to figure out which is better.

First, I just ran Q1, Q2, and Q3 as sub queries and JOINed them as
temporary tables to items.

Next, I split the WHERE clauses off of Q1, Q2, and Q3 and added them
to the JOIN clauses so I had something that did not require any sub
queries.

With the queries I include here, the second method is much faster,
and the explain output looks much better. However, when I used some
more complicated queries for Q1, Q2, and Q3 that involved JOINs on
other tables, the first method was faster, even though the explain
output was uglier. My question is this:




Was that an anomaly or a result of me only having a few thousand
records in my test table, or are there some cases where it is better
to JOIN on temporary tables even if it can be avoided?




Here are the queries and explain outputs:
<pre>
SELECT items.item_id
FROM items
JOIN (SELECT item_id FROM items WHERE item_id < 1000) AS temp1 ON
items.item_id = temp1.item_id
JOIN (SELECT item_id FROM items WHERE item_id < 2000) AS temp2 ON
items.item_id = temp2.item_id
JOIN (SELECT item_id FROM items WHERE item_id < 3000) AS temp3 ON
items.item_id = temp3.item_id
GROUP BY items.item_id;

mysql> explain SELECT items.item_id FROM items JOIN (SELECT item_id
FROM items WHERE item_id < 1000) AS temp1 ON items.item_id =
temp1.item_id JOIN (SELECT item_id FROM items WHERE item_id < 2000) AS
temp2 ON items.item_id = temp2.item_id JOIN (SELECT item_id FROM items
WHERE item_id < 3000) AS temp3 ON items.item_id = temp3.item_id GROUP
BY items.item_id;
+----+-------------+------------+--------+---------------+---------
+---------+---------------+------+---------------------------------+
| id | select_type | table | type | possible_keys | key |
key_len | ref | rows | Extra |
+----+-------------+------------+--------+---------------+---------
+---------+---------------+------+---------------------------------+
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL |
NULL | NULL | 817 | Using temporary; Using filesort |
| 1 | PRIMARY | <derived3> | ALL | NULL | NULL |
NULL | NULL | 860 | Using where |
| 1 | PRIMARY | <derived4> | ALL | NULL | NULL |
NULL | NULL | 863 | Using where |
| 1 | PRIMARY | items | eq_ref | PRIMARY | PRIMARY |
4 | temp3.item_id | 1 | Using where; Using index |
| 4 | DERIVED | items | range | PRIMARY | PRIMARY |
4 | NULL | 926 | Using where; Using index |
| 3 | DERIVED | items | range | PRIMARY | PRIMARY |
4 | NULL | 922 | Using where; Using index |
| 2 | DERIVED | items | range | PRIMARY | PRIMARY |
4 | NULL | 873 | Using where; Using index |
+----+-------------+------------+--------+---------------+---------
+---------+---------------+------+---------------------------------+


select items.item_id
FROM items
JOIN items AS i1 ON items.item_id = i1.item_id AND i1.item_id < 1000
JOIN items AS i2 ON items.item_id = i2.item_id AND i2.item_id < 2000
JOIN items AS i3 ON items.item_id = i3.item_id AND i3.item_id < 3000
GROUP BY items.item_id;

mysql> explain select items.item_id FROM items JOIN items AS i1 ON
items.item_id = i1.item_id AND i1.item_id < 1000 JOIN items AS i2 ON
items.item_id = i2.item_id AND i2.item_id < 2000 JOIN items AS i3 ON
items.item_id = i3.item_id AND i3.item_id < 3000 GROUP BY
items.item_id;
+----+-------------+-------+--------+---------------+---------
+---------+--------------------------+------+--------------------------
+
| id | select_type | table | type | possible_keys | key |
key_len | ref | rows | Extra |
+----+-------------+-------+--------+---------------+---------
+---------+--------------------------+------+--------------------------
+
| 1 | SIMPLE | items | range | PRIMARY | PRIMARY |
4 | NULL | 873 | Using where; Using index
|
| 1 | SIMPLE | i1 | eq_ref | PRIMARY | PRIMARY |
4 | item_stuff.items.item_id | 1 | Using index
|
| 1 | SIMPLE | i2 | eq_ref | PRIMARY | PRIMARY |
4 | item_stuff.i1.item_id | 1 | Using where; Using index
|
| 1 | SIMPLE | i3 | eq_ref | PRIMARY | PRIMARY |
4 | item_stuff.i1.item_id | 1 | Using where; Using index
|
+----+-------------+-------+--------+---------------+---------
+---------+--------------------------+------+--------------------------
+

</pre>

Reply With Quote
Reply
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are Off
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On




All times are GMT +1. The time now is 06:24 AM.


Powered by vBulletin® Version 3.7.3
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO 3.0.0