MAX_JOIN_SIZE error

This is a discussion on MAX_JOIN_SIZE error within the MySQL Database forums, part of the Database Forums category; Michael Austin wrote: > Schemer wrote: >>> Unfortunately, I have no control over the table structure. >>&...


Go Back   Usenet Forums > Database Forums > MySQL Database

FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #11 (permalink)  
Old 05-14-2008
Michael Austin
 
Posts: n/a
Default Re: MAX_JOIN_SIZE error

Michael Austin wrote:
> Schemer wrote:
>>> Unfortunately, I have no control over the table structure.
>>> When this query is used, the error quoted in the original message is
>>> thrown.
>>> What might a query with explicit JOINs look like?

>>
>> More detail on table structure and content (subset of data):
>> f_id sub_id field_name field_val
>> 1 1 First John
>> 2 1 Last Jones
>> 3 1 Team Boys
>> 4 1 DOB 01/01/1990
>> 5 2 First Molly
>> 6 2 Last Malloy
>> 7 2 Team Girls
>> 8 2 DOB 02/02/1990
>>
>> For each sub_id, select all field_vals, if the "Team" field_name for
>> that sub_id has the field_val "Boys".
>> Regarding the JOINs, I thought they were for querying more than one
>> table.
>>
>>
>>
>>

>
> Ahhh.. someone created a sideways database where you have a column in a
> row that describes the next column in the row. Whoever created this
> mess should be shot. There are very few reasons to create a database in
> this manner.
>
> What you need is something along the lines of
> mysql> select sid, first, last, team, dob from
> -> (select a.sid,
> -> case a.fname when 'First' then a.fval end as First,
> -> case b.fname when 'Last' then b.fval end as Last,
> -> case c.fname when 'Team' then c.fval end as Team,
> -> case d.fname when 'DOB ' then d.fval end as DOB
> -> from aaa a right outer join aaa b on a.sid=b.sid
> -> right outer join aaa c on a.sid=c.sid
> -> right outer join aaa d on a.sid=d.sid) e
> -> where sid is not null
> -> and First is not null
> -> and Last is not null
> -> and Team is not null
> -> and DOB is not null;
> +------+-------+--------+-------+------------+
> | sid | first | last | team | dob |
> +------+-------+--------+-------+------------+
> | 1 | John | Jones | Boys | 01/01/1990 |
> | 2 | Molly | Malloy | Girls | 02/02/1990 |
> +------+-------+--------+-------+------------+



hit the send button too soon...

Also this method makes it very difficult to do date arithmetic or date
range searches. It can be done, you will first need to force the date
formats you have chosen into something the database can use - you just
need to be aware that it is not currently in a form for doing date
range searches.

You can create a set of views to make extraction of the data a bit
easier - although due to the fact that MySQL is not yet a real database
engine (at least not the 5.0.22-Debian_0ubuntu6.06-log version I have),
you cannot use the previous select statement in a view, you must do
multiple views like:

mysql> create view subtable as
-> select a.sid,
-> case a.fname when 'First' then a.fval end as First,
-> case b.fname when 'Last' then b.fval end as Last,
-> case c.fname when 'Team' then c.fval end as Team,
-> case d.fname when 'DOB ' then d.fval end as DOB
-> from aaa a left outer join aaa b on a.sid=b.sid
-> left outer join aaa c on a.sid=c.sid
-> left outer join aaa d on a.sid=d.sid
-> ;
Query OK, 0 rows affected (0.01 sec)

mysql> create view masterview as
-> select sid, first, last, team, dob from subtable
-> where First is not null
-> and Last is not null
-> and Team is not null
-> and DOB is not null;
Query OK, 0 rows affected (0.02 sec)

mysql> select * from masterview;
+------+-------+--------+-------+------------+
| sid | first | last | team | dob |
+------+-------+--------+-------+------------+
| 1 | John | Jones | Boys | 01/01/1990 |
| 2 | Molly | Malloy | Girls | 02/02/1990 |
+------+-------+--------+-------+------------+
2 rows in set (0.00 sec)
Reply With Quote
  #12 (permalink)  
Old 05-15-2008
Captain Paralytic
 
Posts: n/a
Default Re: MAX_JOIN_SIZE error

On 14 May, 22:25, Michael Austin <maus...@firstdbasource.com> wrote:
> Michael Austin wrote:
> > Schemer wrote:
> >>> Unfortunately, I have no control over the table structure.
> >>> When this query is used, the error quoted in the original message is
> >>> thrown.
> >>> What might a query with explicit JOINs look like?

>
> >> More detail on table structure and content (subset of data):
> >> f_id sub_id field_name field_val
> >> 1 1 First John
> >> 2 1 Last Jones
> >> 3 1 Team Boys
> >> 4 1 DOB 01/01/1990
> >> 5 2 First Molly
> >> 6 2 Last Malloy
> >> 7 2 Team Girls
> >> 8 2 DOB 02/02/1990

>
> >> For each sub_id, select all field_vals, if the "Team" field_name for
> >> that sub_id has the field_val "Boys".
> >> Regarding the JOINs, I thought they were for querying more than one
> >> table.

>
> > Ahhh.. someone created a sideways database where you have a column in a
> > row that describes the next column in the row. Whoever created this
> > mess should be shot. There are very few reasons to create a database in
> > this manner.

>
> > What you need is something along the lines of
> > mysql> select sid, first, last, team, dob from
> > -> (select a.sid,
> > -> case a.fname when 'First' then a.fval end as First,
> > -> case b.fname when 'Last' then b.fval end as Last,
> > -> case c.fname when 'Team' then c.fval end as Team,
> > -> case d.fname when 'DOB ' then d.fval end as DOB
> > -> from aaa a right outer join aaa b on a.sid=b.sid
> > -> right outer join aaa c on a.sid=c.sid
> > -> right outer join aaa d on a.sid=d.sid) e
> > -> where sid is not null
> > -> and First is not null
> > -> and Last is not null
> > -> and Team is not null
> > -> and DOB is not null;
> > +------+-------+--------+-------+------------+
> > | sid | first | last | team | dob |
> > +------+-------+--------+-------+------------+
> > | 1 | John | Jones | Boys | 01/01/1990 |
> > | 2 | Molly | Malloy | Girls | 02/02/1990 |
> > +------+-------+--------+-------+------------+

>
> hit the send button too soon...
>
> Also this method makes it very difficult to do date arithmetic or date
> range searches. It can be done, you will first need to force the date
> formats you have chosen into something the database can use - you just
> need to be aware that it is not currently in a form for doing date
> range searches.
>
> You can create a set of views to make extraction of the data a bit
> easier - although due to the fact that MySQL is not yet a real database
> engine (at least not the 5.0.22-Debian_0ubuntu6.06-log version I have),
> you cannot use the previous select statement in a view, you must do
> multiple views like:
>
> mysql> create view subtable as
> -> select a.sid,
> -> case a.fname when 'First' then a.fval end as First,
> -> case b.fname when 'Last' then b.fval end as Last,
> -> case c.fname when 'Team' then c.fval end as Team,
> -> case d.fname when 'DOB ' then d.fval end as DOB
> -> from aaa a left outer join aaa b on a.sid=b.sid
> -> left outer join aaa c on a.sid=c.sid
> -> left outer join aaa d on a.sid=d.sid
> -> ;
> Query OK, 0 rows affected (0.01 sec)
>
> mysql> create view masterview as
> -> select sid, first, last, team, dob from subtable
> -> where First is not null
> -> and Last is not null
> -> and Team is not null
> -> and DOB is not null;
> Query OK, 0 rows affected (0.02 sec)
>
> mysql> select * from masterview;
> +------+-------+--------+-------+------------+
> | sid | first | last | team | dob |
> +------+-------+--------+-------+------------+
> | 1 | John | Jones | Boys | 01/01/1990 |
> | 2 | Molly | Malloy | Girls | 02/02/1990 |
> +------+-------+--------+-------+------------+
> 2 rows in set (0.00 sec)


You don't actually require all the case statements. Just code the
criteria on the JOIN condition thus:

CREATE VIEW subtable AS
SELECT
aa.sid,
a.fval First,
b.fval Last,
c.fval Team,
d.fval DOB
FROM aaa aa
LEFT JOIN aaa a ON aa.sid = a.sid AND a.fname = 'First'
LEFT JOIN aaa b ON aa.sid = b.sid AND b.fname = 'Last'
LEFT JOIN aaa c ON aa.sid = c.sid AND c.fname = 'Team'
LEFT JOIN aaa d ON aa.sid = d.sid AND d.fname = 'DOB'
;
Reply With Quote
  #13 (permalink)  
Old 05-15-2008
Michael Austin
 
Posts: n/a
Default Re: MAX_JOIN_SIZE error

Captain Paralytic wrote:
> On 14 May, 22:25, Michael Austin <maus...@firstdbasource.com> wrote:
>> Michael Austin wrote:
>>> Schemer wrote:
>>>>> Unfortunately, I have no control over the table structure.
>>>>> When this query is used, the error quoted in the original message is
>>>>> thrown.
>>>>> What might a query with explicit JOINs look like?
>>>> More detail on table structure and content (subset of data):
>>>> f_id sub_id field_name field_val
>>>> 1 1 First John
>>>> 2 1 Last Jones
>>>> 3 1 Team Boys
>>>> 4 1 DOB 01/01/1990
>>>> 5 2 First Molly
>>>> 6 2 Last Malloy
>>>> 7 2 Team Girls
>>>> 8 2 DOB 02/02/1990
>>>> For each sub_id, select all field_vals, if the "Team" field_name for
>>>> that sub_id has the field_val "Boys".
>>>> Regarding the JOINs, I thought they were for querying more than one
>>>> table.
>>> Ahhh.. someone created a sideways database where you have a column in a
>>> row that describes the next column in the row. Whoever created this
>>> mess should be shot. There are very few reasons to create a database in
>>> this manner.
>>> What you need is something along the lines of
>>> mysql> select sid, first, last, team, dob from
>>> -> (select a.sid,
>>> -> case a.fname when 'First' then a.fval end as First,
>>> -> case b.fname when 'Last' then b.fval end as Last,
>>> -> case c.fname when 'Team' then c.fval end as Team,
>>> -> case d.fname when 'DOB ' then d.fval end as DOB
>>> -> from aaa a right outer join aaa b on a.sid=b.sid
>>> -> right outer join aaa c on a.sid=c.sid
>>> -> right outer join aaa d on a.sid=d.sid) e
>>> -> where sid is not null
>>> -> and First is not null
>>> -> and Last is not null
>>> -> and Team is not null
>>> -> and DOB is not null;
>>> +------+-------+--------+-------+------------+
>>> | sid | first | last | team | dob |
>>> +------+-------+--------+-------+------------+
>>> | 1 | John | Jones | Boys | 01/01/1990 |
>>> | 2 | Molly | Malloy | Girls | 02/02/1990 |
>>> +------+-------+--------+-------+------------+

>> hit the send button too soon...
>>
>> Also this method makes it very difficult to do date arithmetic or date
>> range searches. It can be done, you will first need to force the date
>> formats you have chosen into something the database can use - you just
>> need to be aware that it is not currently in a form for doing date
>> range searches.
>>
>> You can create a set of views to make extraction of the data a bit
>> easier - although due to the fact that MySQL is not yet a real database
>> engine (at least not the 5.0.22-Debian_0ubuntu6.06-log version I have),
>> you cannot use the previous select statement in a view, you must do
>> multiple views like:
>>
>> mysql> create view subtable as
>> -> select a.sid,
>> -> case a.fname when 'First' then a.fval end as First,
>> -> case b.fname when 'Last' then b.fval end as Last,
>> -> case c.fname when 'Team' then c.fval end as Team,
>> -> case d.fname when 'DOB ' then d.fval end as DOB
>> -> from aaa a left outer join aaa b on a.sid=b.sid
>> -> left outer join aaa c on a.sid=c.sid
>> -> left outer join aaa d on a.sid=d.sid
>> -> ;
>> Query OK, 0 rows affected (0.01 sec)
>>
>> mysql> create view masterview as
>> -> select sid, first, last, team, dob from subtable
>> -> where First is not null
>> -> and Last is not null
>> -> and Team is not null
>> -> and DOB is not null;
>> Query OK, 0 rows affected (0.02 sec)
>>
>> mysql> select * from masterview;
>> +------+-------+--------+-------+------------+
>> | sid | first | last | team | dob |
>> +------+-------+--------+-------+------------+
>> | 1 | John | Jones | Boys | 01/01/1990 |
>> | 2 | Molly | Malloy | Girls | 02/02/1990 |
>> +------+-------+--------+-------+------------+
>> 2 rows in set (0.00 sec)

>
> You don't actually require all the case statements. Just code the
> criteria on the JOIN condition thus:
>
> CREATE VIEW subtable AS
> SELECT
> aa.sid,
> a.fval First,
> b.fval Last,
> c.fval Team,
> d.fval DOB
> FROM aaa aa
> LEFT JOIN aaa a ON aa.sid = a.sid AND a.fname = 'First'
> LEFT JOIN aaa b ON aa.sid = b.sid AND b.fname = 'Last'
> LEFT JOIN aaa c ON aa.sid = c.sid AND c.fname = 'Team'
> LEFT JOIN aaa d ON aa.sid = d.sid AND d.fname = 'DOB'
> ;


I will reiterate, that creating a DB such as this, while can be
"flexible", it breaks every rule of normalization. This information
should be stored in a single row. Joining this information with another
table will always be problematic. There is also no really good way to
index this beast either. You would almost need to index every single
field_name and field_value. What this means to your system is that it
will require 2-5 times the amount of space. So, you better hope it
doesn't grow too big... As to performance, without good indexing do not
expect performance on very large data set to be stellar.

Thanks for the catch CP... The good thing about SQL is there are many
many ways to achieve the same goal. The BAD thing about SQL is there
are many mnay ways to achieve the same goal. Yes, a lot cleaner, but
would just need to add "select distinct". Without it, you get as many
results for each sid as you have columns (in this case without distinct
would return 4 of each), however - upon reflection, my original query
creates basically a Cartesian product of all rows for each sid with lots
of null values - not an ideal query especially if there are thousands of
records...


mysql> select aa.sid,
-> a.fval First,
-> b.fval Last,
-> c.fval Team,
-> d.fval DOB
-> FROM aaa aa
-> LEFT outer JOIN aaa a ON aa.sid = a.sid AND a.fname = 'First'
-> LEFT outer JOIN aaa b ON aa.sid = b.sid AND b.fname = 'Last'
-> LEFT outer JOIN aaa c ON aa.sid = c.sid AND c.fname = 'Team'
-> LEFT outer JOIN aaa d ON aa.sid = d.sid AND d.fname = 'DOB';
+------+-------+--------+-------+------------+
| sid | First | Last | Team | DOB |
+------+-------+--------+-------+------------+
| 1 | John | Jones | Boys | 01/01/1990 |
| 1 | John | Jones | Boys | 01/01/1990 |
| 1 | John | Jones | Boys | 01/01/1990 |
| 1 | John | Jones | Boys | 01/01/1990 |
| 2 | Molly | Malloy | Girls | 02/02/1990 |
| 2 | Molly | Malloy | Girls | 02/02/1990 |
| 2 | Molly | Malloy | Girls | 02/02/1990 |
| 2 | Molly | Malloy | Girls | 02/02/1990 |
+------+-------+--------+-------+------------+
8 rows in set (0.01 sec)


mysql> SELECT DISTINCT
-> aa.sid,
-> a.fval First,
-> b.fval Last,
-> c.fval Team,
-> d.fval DOB
-> FROM aaa aa
-> LEFT JOIN aaa a ON aa.sid = a.sid AND a.fname = 'First'
-> LEFT JOIN aaa b ON aa.sid = b.sid AND b.fname = 'Last'
-> LEFT JOIN aaa c ON aa.sid = c.sid AND c.fname = 'Team'
-> LEFT JOIN aaa d ON aa.sid = d.sid AND d.fname = 'DOB'
-> ;
+------+-------+--------+-------+------------+
| sid | First | Last | Team | DOB |
+------+-------+--------+-------+------------+
| 1 | John | Jones | Boys | 01/01/1990 |
| 2 | Molly | Malloy | Girls | 02/02/1990 |
+------+-------+--------+-------+------------+

Reply With Quote
  #14 (permalink)  
Old 05-15-2008
Captain Paralytic
 
Posts: n/a
Default Re: MAX_JOIN_SIZE error

On 15 May, 15:25, Michael Austin <maus...@firstdbasource.com> wrote:
> I will reiterate, that creating a DB such as this, while can be
> "flexible", it breaks every rule of normalization. This information
> should be stored in a single row. Joining this information with another
> table will always be problematic. There is also no really good way to
> index this beast either. You would almost need to index every single
> field_name and field_value. What this means to your system is that it
> will require 2-5 times the amount of space. So, you better hope it
> doesn't grow too big... As to performance, without good indexing do not
> expect performance on very large data set to be stellar.


I had to do a very similar thing with a table. There was a good reason
for the table to be like it was, but it had been "abused". I had to
extract so many fields, that I needed to create a temporary table to
hold an interim result set since I ran up to the JOIN limit. However
the user didn't have CREATE TEMP... privileges at their host, so I had
to do it with table locks.

Once I had done it, it took 30 seconds to run. Adding correct indexes
brought that run time down to under a second.
Reply With Quote
Reply


Thread Tools
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

vB 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 08:47 AM.


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