List:Commits« Previous MessageNext Message »
From:Martin Hansson Date:September 28 2010 8:41am
Subject:bzr commit into mysql-5.5-bugfixing branch (martin.hansson:3204) Bug#37333
View as plain text  
#At file:///data0/martin/bzr/bug37333/5.5bf/ based on revid:mats.kindahl@stripped

 3204 Martin Hansson	2010-09-28
      Bug#37333: Optimizer uses wrong index for the right table in 
      LEFT JOIN
            
      The range optimizer assumed that an index can't be used on an IS NULL
      predicate on the outer table in an outer join, and refrained from calculating
      the cost for it. Since range access estimates are reused for ref type access,
      this lead to a wrong (too low) cost value for the latter access type.
            
      Fixed by removing the bespoke assumption and thus calculating a cost for the
      range scan anyway.

    modified:
      mysql-test/r/range.result
      mysql-test/t/range.test
      sql/opt_range.cc
=== modified file 'mysql-test/r/range.result'
--- a/mysql-test/r/range.result	2010-08-26 12:35:38 +0000
+++ b/mysql-test/r/range.result	2010-09-28 08:41:24 +0000
@@ -1667,3 +1667,36 @@ c_key	c_notkey
 3	3
 DROP TABLE t1;
 End of 5.1 tests
+#
+# Bug#37333: Optimizer uses wrong index for the right table in LEFT JOIN
+#
+CREATE TABLE t1 ( a INT UNIQUE );
+CREATE TABLE t2 ( a INT, b INT DEFAULT NULL, KEY ( a ), KEY ( b ) );
+INSERT INTO t1 VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
+INSERT INTO t1 VALUES (1000);
+INSERT INTO t2( a ) VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
+INSERT INTO t2( a ) SELECT a + 10  FROM t2;
+INSERT INTO t2( a ) SELECT a + 20  FROM t2;
+INSERT INTO t2( a ) SELECT a + 40  FROM t2;
+INSERT INTO t2( a ) SELECT a + 80  FROM t2;
+INSERT INTO t2( a ) SELECT a + 160 FROM t2;
+INSERT INTO t2( a ) VALUES (1000),(1000),(1000),(1000),(1000),
+(1000),(1000),(1000),(1000),(1000),
+(1000);
+EXPLAIN
+SELECT COUNT(*) 
+FROM t1 LEFT JOIN t2 USING ( a )
+WHERE t2.b IS NULL AND t2.a = 1000;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	const	a	a	5	const	1	Using index
+1	SIMPLE	t2	ref	a,b	a	5	const	15	Using where
+FLUSH STATUS;
+SELECT COUNT(*) 
+FROM t1 LEFT JOIN t2 USING ( a )
+WHERE t2.b IS NULL AND t2.a = 1000;
+COUNT(*)
+11
+SHOW STATUS LIKE 'Handler_read_next';
+Variable_name	Value
+Handler_read_next	11
+DROP TABLE t1, t2;

=== modified file 'mysql-test/t/range.test'
--- a/mysql-test/t/range.test	2010-08-24 15:51:32 +0000
+++ b/mysql-test/t/range.test	2010-09-28 08:41:24 +0000
@@ -1326,3 +1326,38 @@ SELECT * FROM t1 WHERE 2 NOT BETWEEN c_n
 DROP TABLE t1;
 
 --echo End of 5.1 tests
+--echo #
+--echo # Bug#37333: Optimizer uses wrong index for the right table in LEFT JOIN
+--echo #
+CREATE TABLE t1 ( a INT UNIQUE ); 
+CREATE TABLE t2 ( a INT, b INT DEFAULT NULL, KEY ( a ), KEY ( b ) );
+
+INSERT INTO t1 VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
+
+INSERT INTO t1 VALUES (1000);
+
+INSERT INTO t2( a ) VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
+INSERT INTO t2( a ) SELECT a + 10  FROM t2;
+INSERT INTO t2( a ) SELECT a + 20  FROM t2;
+INSERT INTO t2( a ) SELECT a + 40  FROM t2;
+INSERT INTO t2( a ) SELECT a + 80  FROM t2;
+INSERT INTO t2( a ) SELECT a + 160 FROM t2;
+
+INSERT INTO t2( a ) VALUES (1000),(1000),(1000),(1000),(1000),
+                           (1000),(1000),(1000),(1000),(1000),
+                           (1000);
+
+EXPLAIN
+SELECT COUNT(*) 
+FROM t1 LEFT JOIN t2 USING ( a )
+WHERE t2.b IS NULL AND t2.a = 1000;
+
+FLUSH STATUS;
+
+SELECT COUNT(*) 
+FROM t1 LEFT JOIN t2 USING ( a )
+WHERE t2.b IS NULL AND t2.a = 1000;
+
+SHOW STATUS LIKE 'Handler_read_next';
+
+DROP TABLE t1, t2;

=== modified file 'sql/opt_range.cc'
--- a/sql/opt_range.cc	2010-08-26 12:35:38 +0000
+++ b/sql/opt_range.cc	2010-09-28 08:41:24 +0000
@@ -5765,8 +5765,6 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND
   param->thd->mem_root= param->old_root;
   if (!value)					// IS NULL or IS NOT NULL
   {
-    if (field->table->maybe_null)		// Can't use a key on this
-      goto end;
     if (!maybe_null)				// Not null field
     {
       if (type == Item_func::ISNULL_FUNC)


Attachment: [text/bzr-bundle] bzr/martin.hansson@oracle.com-20100928084124-8qjjs2c1w6t5o688.bundle
Thread
bzr commit into mysql-5.5-bugfixing branch (martin.hansson:3204) Bug#37333Martin Hansson28 Sep