Merge ibabaev@bk-internal.mysql.com:/home/bk/mysql-5.0-opt
into rurik.mysql.com:/home/igor/mysql-5.0-opt
This commit is contained in:
commit
75865af64b
@ -2328,9 +2328,9 @@ explain select * from t1 left join t2 on id1 = id2 left join t3 on id1 = id3
|
|||||||
left join t4 on id3 = id4 where id2 = 1 or id4 = 1;
|
left join t4 on id3 = id4 where id2 = 1 or id4 = 1;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t3 system NULL NULL NULL NULL 0 const row not found
|
1 SIMPLE t3 system NULL NULL NULL NULL 0 const row not found
|
||||||
|
1 SIMPLE t4 const id4 NULL NULL NULL 1
|
||||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 2
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 2
|
||||||
1 SIMPLE t2 ALL NULL NULL NULL NULL 1
|
1 SIMPLE t2 ALL NULL NULL NULL NULL 1 Using where
|
||||||
1 SIMPLE t4 ALL id4 NULL NULL NULL 1 Using where
|
|
||||||
select * from t1 left join t2 on id1 = id2 left join t3 on id1 = id3
|
select * from t1 left join t2 on id1 = id2 left join t3 on id1 = id3
|
||||||
left join t4 on id3 = id4 where id2 = 1 or id4 = 1;
|
left join t4 on id3 = id4 where id2 = 1 or id4 = 1;
|
||||||
id1 id2 id3 id4 id44
|
id1 id2 id3 id4 id44
|
||||||
@ -3479,3 +3479,41 @@ Warning 1466 Leading spaces are removed from name ' a '
|
|||||||
execute stmt;
|
execute stmt;
|
||||||
a
|
a
|
||||||
1
|
1
|
||||||
|
CREATE TABLE t1 (a int NOT NULL PRIMARY KEY, b int NOT NULL);
|
||||||
|
INSERT INTO t1 VALUES (1,1), (2,2), (3,3), (4,4);
|
||||||
|
CREATE TABLE t2 (c int NOT NULL, INDEX idx(c));
|
||||||
|
INSERT INTO t2 VALUES
|
||||||
|
(1), (1), (1), (1), (1), (1), (1), (1),
|
||||||
|
(2), (2), (2), (2),
|
||||||
|
(3), (3),
|
||||||
|
(4);
|
||||||
|
EXPLAIN SELECT b FROM t1, t2 WHERE b=c AND a=1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
|
||||||
|
1 SIMPLE t2 ref idx idx 4 const 7 Using index
|
||||||
|
EXPLAIN SELECT b FROM t1, t2 WHERE b=c AND a=4;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
|
||||||
|
1 SIMPLE t2 ref idx idx 4 const 1 Using index
|
||||||
|
DROP TABLE t1, t2;
|
||||||
|
CREATE TABLE t1 (id int NOT NULL PRIMARY KEY, a int);
|
||||||
|
INSERT INTO t1 VALUES (1,2), (2,NULL), (3,2);
|
||||||
|
CREATE TABLE t2 (b int, c INT, INDEX idx1(b));
|
||||||
|
INSERT INTO t2 VALUES (2,1), (3,2);
|
||||||
|
CREATE TABLE t3 (d int, e int, INDEX idx1(d));
|
||||||
|
INSERT INTO t3 VALUES (2,10), (2,20), (1,30), (2,40), (2,50);
|
||||||
|
EXPLAIN
|
||||||
|
SELECT * FROM t1 LEFT JOIN t2 ON t2.b=t1.a INNER JOIN t3 ON t3.d=t1.id
|
||||||
|
WHERE t1.id=2;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
|
||||||
|
1 SIMPLE t2 const idx1 NULL NULL NULL 1
|
||||||
|
1 SIMPLE t3 ref idx1 idx1 5 const 3 Using where
|
||||||
|
SELECT * FROM t1 LEFT JOIN t2 ON t2.b=t1.a INNER JOIN t3 ON t3.d=t1.id
|
||||||
|
WHERE t1.id=2;
|
||||||
|
id a b c d e
|
||||||
|
2 NULL NULL NULL 2 10
|
||||||
|
2 NULL NULL NULL 2 20
|
||||||
|
2 NULL NULL NULL 2 40
|
||||||
|
2 NULL NULL NULL 2 50
|
||||||
|
DROP TABLE t1,t2,t3;
|
||||||
|
@ -2957,3 +2957,44 @@ SELECT 0.9888889889 * 1.011111411911;
|
|||||||
#
|
#
|
||||||
prepare stmt from 'select 1 as " a "';
|
prepare stmt from 'select 1 as " a "';
|
||||||
execute stmt;
|
execute stmt;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #21390: wrong estimate of rows after elimination of const tables
|
||||||
|
#
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a int NOT NULL PRIMARY KEY, b int NOT NULL);
|
||||||
|
INSERT INTO t1 VALUES (1,1), (2,2), (3,3), (4,4);
|
||||||
|
|
||||||
|
CREATE TABLE t2 (c int NOT NULL, INDEX idx(c));
|
||||||
|
INSERT INTO t2 VALUES
|
||||||
|
(1), (1), (1), (1), (1), (1), (1), (1),
|
||||||
|
(2), (2), (2), (2),
|
||||||
|
(3), (3),
|
||||||
|
(4);
|
||||||
|
|
||||||
|
EXPLAIN SELECT b FROM t1, t2 WHERE b=c AND a=1;
|
||||||
|
EXPLAIN SELECT b FROM t1, t2 WHERE b=c AND a=4;
|
||||||
|
|
||||||
|
DROP TABLE t1, t2;
|
||||||
|
|
||||||
|
#
|
||||||
|
# No matches for a join after substitution of a const table
|
||||||
|
#
|
||||||
|
|
||||||
|
CREATE TABLE t1 (id int NOT NULL PRIMARY KEY, a int);
|
||||||
|
INSERT INTO t1 VALUES (1,2), (2,NULL), (3,2);
|
||||||
|
|
||||||
|
CREATE TABLE t2 (b int, c INT, INDEX idx1(b));
|
||||||
|
INSERT INTO t2 VALUES (2,1), (3,2);
|
||||||
|
|
||||||
|
CREATE TABLE t3 (d int, e int, INDEX idx1(d));
|
||||||
|
INSERT INTO t3 VALUES (2,10), (2,20), (1,30), (2,40), (2,50);
|
||||||
|
|
||||||
|
EXPLAIN
|
||||||
|
SELECT * FROM t1 LEFT JOIN t2 ON t2.b=t1.a INNER JOIN t3 ON t3.d=t1.id
|
||||||
|
WHERE t1.id=2;
|
||||||
|
SELECT * FROM t1 LEFT JOIN t2 ON t2.b=t1.a INNER JOIN t3 ON t3.d=t1.id
|
||||||
|
WHERE t1.id=2;
|
||||||
|
|
||||||
|
|
||||||
|
DROP TABLE t1,t2,t3;
|
||||||
|
@ -2205,6 +2205,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
|
|||||||
int ref_changed;
|
int ref_changed;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
more_const_tables_found:
|
||||||
ref_changed = 0;
|
ref_changed = 0;
|
||||||
found_ref=0;
|
found_ref=0;
|
||||||
|
|
||||||
@ -2216,6 +2217,30 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
|
|||||||
for (JOIN_TAB **pos=stat_vector+const_count ; (s= *pos) ; pos++)
|
for (JOIN_TAB **pos=stat_vector+const_count ; (s= *pos) ; pos++)
|
||||||
{
|
{
|
||||||
table=s->table;
|
table=s->table;
|
||||||
|
|
||||||
|
/*
|
||||||
|
If equi-join condition by a key is null rejecting and after a
|
||||||
|
substitution of a const table the key value happens to be null
|
||||||
|
then we can state that there are no matches for this equi-join.
|
||||||
|
*/
|
||||||
|
if ((keyuse= s->keyuse) && *s->on_expr_ref)
|
||||||
|
{
|
||||||
|
while (keyuse->table == table)
|
||||||
|
{
|
||||||
|
if (!(keyuse->val->used_tables() & ~join->const_table_map) &&
|
||||||
|
keyuse->val->is_null() && keyuse->null_rejecting)
|
||||||
|
{
|
||||||
|
s->type= JT_CONST;
|
||||||
|
mark_as_null_row(table);
|
||||||
|
found_const_table_map|= table->map;
|
||||||
|
join->const_table_map|= table->map;
|
||||||
|
set_position(join,const_count++,s,(KEYUSE*) 0);
|
||||||
|
goto more_const_tables_found;
|
||||||
|
}
|
||||||
|
keyuse++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (s->dependent) // If dependent on some table
|
if (s->dependent) // If dependent on some table
|
||||||
{
|
{
|
||||||
// All dep. must be constants
|
// All dep. must be constants
|
||||||
@ -2266,34 +2291,38 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
|
|||||||
} while (keyuse->table == table && keyuse->key == key);
|
} while (keyuse->table == table && keyuse->key == key);
|
||||||
|
|
||||||
if (eq_part.is_prefix(table->key_info[key].key_parts) &&
|
if (eq_part.is_prefix(table->key_info[key].key_parts) &&
|
||||||
((table->key_info[key].flags & (HA_NOSAME | HA_END_SPACE_KEY)) ==
|
|
||||||
HA_NOSAME) &&
|
|
||||||
!table->fulltext_searched &&
|
!table->fulltext_searched &&
|
||||||
!table->pos_in_table_list->embedding)
|
!table->pos_in_table_list->embedding)
|
||||||
{
|
{
|
||||||
if (const_ref == eq_part)
|
if ((table->key_info[key].flags & (HA_NOSAME | HA_END_SPACE_KEY))
|
||||||
{ // Found everything for ref.
|
== HA_NOSAME)
|
||||||
int tmp;
|
{
|
||||||
ref_changed = 1;
|
if (const_ref == eq_part)
|
||||||
s->type= JT_CONST;
|
{ // Found everything for ref.
|
||||||
join->const_table_map|=table->map;
|
int tmp;
|
||||||
set_position(join,const_count++,s,start_keyuse);
|
ref_changed = 1;
|
||||||
if (create_ref_for_key(join, s, start_keyuse,
|
s->type= JT_CONST;
|
||||||
found_const_table_map))
|
join->const_table_map|=table->map;
|
||||||
DBUG_RETURN(1);
|
set_position(join,const_count++,s,start_keyuse);
|
||||||
if ((tmp=join_read_const_table(s,
|
if (create_ref_for_key(join, s, start_keyuse,
|
||||||
join->positions+const_count-1)))
|
found_const_table_map))
|
||||||
{
|
DBUG_RETURN(1);
|
||||||
if (tmp > 0)
|
if ((tmp=join_read_const_table(s,
|
||||||
DBUG_RETURN(1); // Fatal error
|
join->positions+const_count-1)))
|
||||||
|
{
|
||||||
|
if (tmp > 0)
|
||||||
|
DBUG_RETURN(1); // Fatal error
|
||||||
|
}
|
||||||
|
else
|
||||||
|
found_const_table_map|= table->map;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
found_const_table_map|= table->map;
|
found_ref|= refs; // Table is const if all refs are const
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
else
|
else if (const_ref == eq_part)
|
||||||
found_ref|= refs; // Table is const if all refs are const
|
s->const_keys.set_bit(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2696,7 +2725,8 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond,
|
|||||||
We use null_rejecting in add_not_null_conds() to add
|
We use null_rejecting in add_not_null_conds() to add
|
||||||
'othertbl.field IS NOT NULL' to tab->select_cond.
|
'othertbl.field IS NOT NULL' to tab->select_cond.
|
||||||
*/
|
*/
|
||||||
(*key_fields)->null_rejecting= ((cond->functype() == Item_func::EQ_FUNC) &&
|
(*key_fields)->null_rejecting= ((cond->functype() == Item_func::EQ_FUNC ||
|
||||||
|
cond->functype() == Item_func::MULT_EQUAL_FUNC) &&
|
||||||
((*value)->type() == Item::FIELD_ITEM) &&
|
((*value)->type() == Item::FIELD_ITEM) &&
|
||||||
((Item_field*)*value)->field->maybe_null());
|
((Item_field*)*value)->field->maybe_null());
|
||||||
(*key_fields)++;
|
(*key_fields)++;
|
||||||
@ -3461,7 +3491,7 @@ best_access_path(JOIN *join,
|
|||||||
keyuse->used_tables));
|
keyuse->used_tables));
|
||||||
if (tmp < best_prev_record_reads)
|
if (tmp < best_prev_record_reads)
|
||||||
{
|
{
|
||||||
best_part_found_ref= keyuse->used_tables;
|
best_part_found_ref= keyuse->used_tables & ~join->const_table_map;
|
||||||
best_prev_record_reads= tmp;
|
best_prev_record_reads= tmp;
|
||||||
}
|
}
|
||||||
if (rec > keyuse->ref_table_rows)
|
if (rec > keyuse->ref_table_rows)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user