Bug #17859 | Left outer Join of two views causes server crash | ||
---|---|---|---|
Submitted: | 2 Mar 2006 12:50 | Modified: | 10 Apr 2006 16:56 |
Reporter: | Charlie Farrow | Email Updates: | |
Status: | Can't repeat | Impact on me: | |
Category: | MySQL Server | Severity: | S1 (Critical) |
Version: | 5.0.18 | OS: | Windows (WIN XP SP2) |
Assigned to: | CPU Architecture: | Any |
[2 Mar 2006 12:50]
Charlie Farrow
[2 Mar 2006 14:15]
Valeriy Kravchuk
Thank you for a problem report. Please, take a look at EXPLAIN results I've got on your test case: mysql> explain select * from vretro_stock_val as A -> left outer join Vstock_val as B -> on A.stock_id=B.stock_id \G *************************** 1. row *************************** id: 1 select_type: PRIMARY table: component_list type: ALL possible_keys: PRIMARY key: NULL key_len: NULL ref: NULL rows: 354 Extra: *************************** 2. row *************************** id: 1 select_type: PRIMARY table: stock type: ref possible_keys: COMPONENT_ID key: COMPONENT_ID key_len: 4 ref: wellandpowerdb.component_list.COMPONENT_ID rows: 8 Extra: Using where *************************** 3. row *************************** id: 1 select_type: PRIMARY table: set_list type: eq_ref possible_keys: PRIMARY key: PRIMARY key_len: 4 ref: wellandpowerdb.stock.SET_ID rows: 1 Extra: Using index *************************** 4. row *************************** id: 1 select_type: PRIMARY table: dispatch_body type: ref possible_keys: set_id key: set_id key_len: 4 ref: wellandpowerdb.set_list.SET_ID rows: 1 Extra: *************************** 5. row *************************** id: 1 select_type: PRIMARY table: dispatch_headers type: eq_ref possible_keys: PRIMARY key: PRIMARY key_len: 4 ref: wellandpowerdb.dispatch_body.DISPATCH_ID rows: 1 Extra: *************************** 6. row *************************** id: 1 select_type: PRIMARY table: component_list type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 354 Extra: *************************** 7. row *************************** id: 1 select_type: PRIMARY table: stock type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 1428 Extra: *************************** 8. row *************************** id: 1 select_type: PRIMARY table: set_list type: eq_ref possible_keys: PRIMARY key: PRIMARY key_len: 4 ref: wellandpowerdb.stock.SET_ID rows: 1 Extra: 8 rows in set (0.05 sec) They mean that: mysql> select 324*8*354*1428; +----------------+ | 324*8*354*1428 | +----------------+ | 1310287104 | +----------------+ 1 row in set (0.00 sec) ^^^^ this many rows should be returned by that query. Surely, it will work for ages. It is not a bug - you just asked to do it.
[2 Mar 2006 15:05]
Charlie Farrow
OK... I can see the explain and the results show this number of rows should be returned, however, surly this is incorrect if you look at the two views. One each view has a list of stock items, with a primary key of STOCK_ID. In each of these views, there are < 800 rows, most of which are duplicates in the other. Therefore, doing a left outer join on these two views should surly produce a maximum number of rows in the first view, because there is never a duplicated key of course. Isn't this the case? Should these views not perform as if they were two temporary tables in memory? Charlie
[2 Mar 2006 15:26]
Charlie Farrow
Also, looking at using an inner join (this is not the result I want by the way i do need left outer syntax) the rows returned are 675. Now by doing a simple select from each view again you can see the fact as commented below the keys match, therefore, because we are joining in the key there should never be more rows than in the first table using this query? do you agree that? So using the inner join we get 675 rows. Now using the left outer join syntax I want to return the rows in A that match B, so I can do a comparrison. I could for example select non-matching rows using where B.STOCK_ID is NULL. The query should therefore formed like this: select * from vstock_val as A left outer join vretro_stock_val as B on A.stock_id=B.stock_id where B.stock_id is null. Now given that there are 675 mathing rows in A inner on B and there are 1370 rows in B (and because the keys are unique, the maximum matches per row is one), the maximum number of rows returned is still 675! Actually I guess it would make more sence joined the other way round, with B joined to A, that way the maximum number of rows should be 1370 and if you include the where clause the result will have 1370 as a maximum, less one for each sucessfully matched row. This still crashes the server.
[2 Mar 2006 15:45]
Hartmut Holzgraefe
it does actually terminate, just takes a long time: 1370 rows in set (16 min 59.84 sec) (on a laptop running at 600mhz right now)
[2 Mar 2006 15:50]
Charlie Farrow
LOL! ok, so we know it takes a long time and its not crashing the server, that looks like a good thing! However, don't you think you could perform this query faster by hand? Want me to have a go and tell you how long it takes me? The server is clearly going about it the wrong way dont you think? It takes virtually no time to select from the view... (o.0070secs or less for each on my very low spec server) and if these were tables, it would take a similar amount of time to join them i think?? So surely this is a bug, all be it possibly not the bug i thought it was?
[10 Apr 2006 16:56]
Valeriy Kravchuk
We have some internal discussion on this issue. Maybe, it was helpful. I've tried to reproduce your test case on today's 5.0.21-BK build on Linux, and got a different plan: mysql> select count(*) from vstock_val; +----------+ | count(*) | +----------+ | 697 | +----------+ 1 row in set (0.03 sec) mysql> select count(*) from vretro_stock_val; +----------+ | count(*) | +----------+ | 1370 | +----------+ 1 row in set (0.02 sec) mysql> select 1370*697; +----------+ | 1370*697 | +----------+ | 954890 | +----------+ 1 row in set (0.00 sec) mysql> explain select * from vretro_stock_val as A -> left outer join vstock_val as B -> on A.stock_id=B.stock_id \G *************************** 1. row *************************** id: 1 select_type: PRIMARY table: stock type: ALL possible_keys: COMPONENT_ID key: NULL key_len: NULL ref: NULL rows: 1428 Extra: Using where *************************** 2. row *************************** id: 1 select_type: PRIMARY table: stock type: eq_ref possible_keys: PRIMARY,COMPONENT_ID key: PRIMARY key_len: 4 ref: wellandpowerdb.stock.STOCK_ID rows: 1 Extra: *************************** 3. row *************************** id: 1 select_type: PRIMARY table: component_list type: eq_ref possible_keys: PRIMARY key: PRIMARY key_len: 4 ref: wellandpowerdb.stock.COMPONENT_ID rows: 1 Extra: *************************** 4. row *************************** id: 1 select_type: PRIMARY table: set_list type: eq_ref possible_keys: PRIMARY key: PRIMARY key_len: 4 ref: wellandpowerdb.stock.SET_ID rows: 1 Extra: *************************** 5. row *************************** id: 1 select_type: PRIMARY table: set_list type: eq_ref possible_keys: PRIMARY key: PRIMARY key_len: 4 ref: wellandpowerdb.stock.SET_ID rows: 1 Extra: Using index *************************** 6. row *************************** id: 1 select_type: PRIMARY table: component_list type: eq_ref possible_keys: PRIMARY key: PRIMARY key_len: 4 ref: wellandpowerdb.stock.COMPONENT_ID rows: 1 Extra: Using where *************************** 7. row *************************** id: 1 select_type: PRIMARY table: dispatch_body type: ref possible_keys: set_id key: set_id key_len: 4 ref: wellandpowerdb.set_list.SET_ID rows: 1 Extra: *************************** 8. row *************************** id: 1 select_type: PRIMARY table: dispatch_headers type: eq_ref possible_keys: PRIMARY key: PRIMARY key_len: 4 ref: wellandpowerdb.dispatch_body.DISPATCH_ID rows: 1 Extra: 8 rows in set (0.01 sec) mysql> select * from vretro_stock_val as A left outer join vstock_val as B on A.stock_id=B.stock_id\G ... *************************** 1369. row *************************** STOCK_ID: 1727 COMPONENT_ID: 1221 COMPONENT_NAME: Perkins 2306C-E14TAG3/ECO40-1S STOCK_VALUE: 465 STOCK_IN: 1140604551 STOCK_OUT: NULL STOCK_ID: 1727 COMPONENT_ID: 1221 COMPONENT_NAME: Perkins 2306C-E14TAG3/ECO40-1S STOCK_VALUE: 465 *************************** 1370. row *************************** STOCK_ID: 1726 COMPONENT_ID: 1221 COMPONENT_NAME: Perkins 2306C-E14TAG3/ECO40-1S STOCK_VALUE: 465 STOCK_IN: 1140516253 STOCK_OUT: NULL STOCK_ID: 1726 COMPONENT_ID: 1221 COMPONENT_NAME: Perkins 2306C-E14TAG3/ECO40-1S STOCK_VALUE: 465 1370 rows in set (0.08 sec) mysql> select version(); +-----------+ | version() | +-----------+ | 5.0.21 | +-----------+ 1 row in set (0.00 sec) So, please, check the newer version, 5.0.20 (it will appear soon), and reopen this report in case of similar problems.