If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below.

 
Go Back  dBforums > Database Server Software > MySQL > One JOIN: OK, Two JOIN: DISASTER

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
  #1 (permalink)  
Old 12-04-08, 06:16
mortensi mortensi is offline
Registered User
 
Join Date: Dec 2008
Posts: 4
One JOIN: OK, Two JOIN: DISASTER

Let me show you something:

# Query_time: 1 Lock_time: 0 Rows_sent: 1 Rows_examined: 150000
SELECT COUNT(DISTINCT(u.unit_id))
FROM unit u
RIGHT JOIN
(SELECT up1.unit_id
FROM unit_param up1
WHERE up1.unit_type_param_id = 24
AND up1.value = ‘ServiceA’
) nmp0
ON u.unit_id = nmp0.unit_id;

This query is fine. No problem. Now, I have to make another selection from the unit_param table, for which I need to do another JOIN in addition to the previous query. The first section of the query is exactly the same as the previous query. Beware:

# Query_time: 1138 Lock_time: 0 Rows_sent: 0 Rows_examined: 2271979789
SELECT COUNT(DISTINCT(u.unit_id))
FROM unit u
RIGHT JOIN
(SELECT up1.unit_id
FROM unit_param up1
WHERE up1.unit_type_param_id = 24
AND up1.value = ‘ServiceA’
) nmp0
ON u.unit_id = nmp0.unit_id
RIGHT JOIN
(SELECT up1.unit_id
FROM unit_param up1
WHERE up1.unit_type_param_id = 23
AND up1.value = ‘Bigland’
) nmp1
ON u.unit_id = nmp1.unit_id;

This query never responded, I had to cancel it (but not before it had run for 20min!! running on 100% CPU) However, the number of rows with “Bigland” was just 75K rows compared to rows with “ServiceA” which was 50K rows. The initial table (unit) was 100K rows. Each row record is approx. 500B. So adding ONE JOIN extra, with an additional 75K rows to JOIN, the query went from OK to a DISASTER!!!!

The number of rows involved went from 150K rows to 2.2G rows!!!!! How on earth could this happen? Has the JOIN thing gone completely crazy??? What can I do about this? I have tried adjusting the join_buffer_size (128M and 16M) but to no avail.

I must admit I am getting desperate now.

Sincerly grateful for any input here!

Morten Simonsen
Reply With Quote
  #2 (permalink)  
Old 12-04-08, 06:46
gvee gvee is offline
www.gvee.co.uk
 
Join Date: Jan 2007
Location: UK
Posts: 10,156
Can you let us know a little more about what you're actually trying to achieve?

Looks to me like your query could be simplified somewhat...
__________________
George
Twitter | Blog
Reply With Quote
  #3 (permalink)  
Old 12-04-08, 06:59
mortensi mortensi is offline
Registered User
 
Join Date: Dec 2008
Posts: 4
Ok...here goes:

I have a list of "units" in one table. These units can have many "properties". We have made unit_param table to hold these properties. Each row in unit_param holds exactly one property for one unit.

Now, if I want to list all units with property A = Foo and property B = Bar, then I think I have to do it this way.

Thanks for your interest

Morten Simonsen
Reply With Quote
  #4 (permalink)  
Old 12-04-08, 07:04
gvee gvee is offline
www.gvee.co.uk
 
Join Date: Jan 2007
Location: UK
Posts: 10,156
If you want those units with BOTH properties, then you should be using two INNER joins.
__________________
George
Twitter | Blog
Reply With Quote
  #5 (permalink)  
Old 12-04-08, 07:16
mortensi mortensi is offline
Registered User
 
Join Date: Dec 2008
Posts: 4
Smile

Hi there

I rewrote the SQL to:

SELECT COUNT(tmp.unit_id)
FROM
(SELECT u.unit_id
FROM unit u,
unit_param up
WHERE u.unit_id = up.unit_id
AND up.value = 'ServiceA'
) tmp,
unit_param up1
WHERE tmp.unit_id = up1.unit_id
AND up1.value = 'Bigland';

It took only 5 sec now!!! Very good. I am grateful. Was this the way you intended?

Still, there must be a serious bug in MySQL. My previous SQL worked fine on Oracle.

Thanks a lot!!!!!

Morten Simonsen
Reply With Quote
  #6 (permalink)  
Old 12-04-08, 07:19
mortensi mortensi is offline
Registered User
 
Join Date: Dec 2008
Posts: 4
Actually, I forgot a couple of things in my SQL:

SELECT COUNT(tmp.unit_id)
FROM
(SELECT u.unit_id
FROM unit u,
unit_param up
WHERE u.unit_id = up.unit_id
AND up.unit_type_param_id = 24
AND up.value = 'ServiceA'
) tmp,
unit_param up1
WHERE tmp.unit_id = up1.unit_id
AND up1.unit_type_param_id = 23
AND up1.value = 'Bigland';


now it responds in 1 sec.



Morten Simonsen
Reply With Quote
  #7 (permalink)  
Old 12-04-08, 08:44
r937 r937 is offline
SQL Consultant
 
Join Date: Apr 2002
Location: Toronto, Canada
Posts: 19,534
Quote:
Originally Posted by georgev
If you want those units with BOTH properties, then you should be using two INNER joins.
and if three, then three, and so on

the problem is, this gets ugly

the alternative (and i'm sure you've seen it before georgie), is simply to count them

Code:
SELECT COUNT(*)
  FROM (
       SELECT unit_id
         FROM unit u
       INNER
         JOIN unit_param up
           ON up.unit_id = u.unit_id 
        WHERE ( 
              up.unit_type_param_id = 24
          AND up.value = 'ServiceA'
              )
           OR (
              up.unit_type_param_id = 23
          AND up.value = 'Bigland'
              )
       GROUP
           BY unit_id
       HAVING COUNT(*) = 2
       ) AS d
why is counting better? because then you can do queries such as "must have at least three of"

example:
Code:
SELECT candidate_name
  FROM applications
 WHERE job_skill IN ( 'CSS','HTML','ASP','PHP','SQL')
GROUP
    BY candidate_name
HAVING COUNT(*) >= 3
__________________
r937.com | rudy.ca
please visit Simply SQL and buy my book
Reply With Quote
  #8 (permalink)  
Old 12-04-08, 09:07
gvee gvee is offline
www.gvee.co.uk
 
Join Date: Jan 2007
Location: UK
Posts: 10,156
Quote:
Originally Posted by r937
i'm sure you've seen it before georgie
Absolutely! It's another favourite that I learned from none other than my ledherhosen-sporting peer
__________________
George
Twitter | Blog
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 On
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On