MySQL Forums
Forum List  »  Optimizer & Parser

Double COUNT & Double LEFT JOIN
Posted by: Olexandr Novosad
Date: June 01, 2007 04:56AM

I've faced with one obscure situation and finally ask there for explanation, if somebody can…

I have three tables:
CREATE TABLE `a` (
`Id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`bId` int(10) UNSIGNED NOT NULL,
PRIMARY KEY (`Id`),
KEY `ibid` (`bId`)
);

CREATE TABLE `b` (
`Id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`DataVal` int(10) UNSIGNED NOT NULL,
PRIMARY KEY (`Id`)
);

CREATE TABLE `c` (
`Id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`bId` int(10) UNSIGNED NOT NULL,
PRIMARY KEY (`Id`),
KEY `ibid` (`bId`)
);

And execute this query:
SELECT b.Id, COUNT(DISTINCT a.Id) AS c1, COUNT(DISTINCT c.Id) AS c2
FROM b
LEFT JOIN a ON a.bId = b.Id
LEFT JOIN c ON c.bId = b.Id
GROUP BY b.Id;

And use different conditions:
1)
Table a – 1000 records;
Table b – 1000 records;
Table c – 1000 records;
Result:
1000 rows in set (0.03 sec)
2)
Table a – 10000 records;
Table b – 10000 records;
Table c – 10000 records;
Result:
10000 rows in set (0.27 sec)
3)
Table a – 100000 records;
Table b – 100000 records;
Table c – 100000 records;
Result:
100000 rows in set (3.89 sec)

Fine so far…

4)
Table a – 100000 records;
Table b – 100 records;
Table c – 1000 records;
Result:
100 rows in set (4.63 sec)
5)
Table a – 100000 records;
Table b – 10 records;
Table c – 1000 records;
Result:
10 rows in set (42.86 sec)

Last two situations I misunderstand. How it could be?
EXPLAIN looks pretty fine:
+----+-------------+-------+-------+---------------+---------+---------+--------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+---------+---------+--------------+------+-------------+
| 1 | SIMPLE | b | index | NULL | PRIMARY | 4 | NULL | 10 | Using index |
| 1 | SIMPLE | a | ref | ibid | ibid | 4 | bd.b.Id | 100 | |
| 1 | SIMPLE | c | ref | ibid | ibid | 4 | bd.b.Id | 12 | |
+----+-------------+-------+-------+---------------+---------+---------+--------------+------+-------------+

From bad to worse.. I’ve filled up table a as bellow:
+----+-------+-----+
| Id | c1 | c2 |
+----+-------+-----+
| 1 | 7776 | 95 |
| 2 | 7732 | 107 |
| 3 | 7815 | 96 |
| 4 | 7828 | 108 |
| 5 | 30002 | 98 |
| 6 | 7821 | 85 |
| 7 | 7773 | 101 |
| 8 | 7739 | 107 |
| 9 | 7804 | 99 |
| 10 | 7710 | 104 |
+----+-------+-----+
10 rows in set (43.16 sec)
And have changed query:
SELECT b.Id, COUNT(DISTINCT a.Id) AS c1, COUNT(DISTINCT c.Id) AS c2
FROM b
LEFT JOIN a ON a.bId = b.Id
LEFT JOIN c ON c.bId = b.Id
WHERE b.Id=5
GROUP BY b.Id;
Result:
1 row in set (15.06 sec)

Explain looks perfectly:
+----+-------------+-------+-------+---------------+---------+---------+-------+-------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+---------+---------+-------+-------+-------------+
| 1 | SIMPLE | b | const | PRIMARY | PRIMARY | 4 | const | 1 | Using index |
| 1 | SIMPLE | a | ref | ibid | ibid | 4 | const | 50226 | Using index |
| 1 | SIMPLE | c | ref | ibid | ibid | 4 | const | 98 | Using index |
+----+-------------+-------+-------+---------------+---------+---------+-------+-------+-------------+
but execution time – completely bad.

And there is another one question..
On query without WHERE, EXPLAIN EXTENDED displays 1 warning: Note, 1003, and the same query, but with added database entitle. What does this note mean?

Options: ReplyQuote


Subject
Views
Written By
Posted
Double COUNT & Double LEFT JOIN
16085
June 01, 2007 04:56AM
3359
February 13, 2008 05:14AM


Sorry, you can't reply to this topic. It has been closed.

Content reproduced on this site is the property of the respective copyright holders. It is not reviewed in advance by Oracle and does not necessarily represent the opinion of Oracle or any other party.