diff options
190 files changed, 5644 insertions, 1976 deletions
diff --git a/include/my_compare.h b/include/my_compare.h index 4387105aff8..0f48771d7a7 100644 --- a/include/my_compare.h +++ b/include/my_compare.h @@ -152,5 +152,6 @@ typedef enum icp_result { } ICP_RESULT; typedef ICP_RESULT (*index_cond_func_t)(void *param); +typedef int (*rowid_filter_func_t)(void *param); #endif /* _my_compare_h */ diff --git a/mysql-test/include/explain_non_select.inc b/mysql-test/include/explain_non_select.inc index 57b96994d20..d22310c9813 100644 --- a/mysql-test/include/explain_non_select.inc +++ b/mysql-test/include/explain_non_select.inc @@ -158,7 +158,7 @@ CREATE TABLE t1 ( a int PRIMARY KEY ); --let $query = DELETE FROM t1 WHERE t1.a > 0 ORDER BY t1.a --let $select = SELECT * FROM t1 WHERE t1.a > 0 ORDER BY t1.a --source include/explain_utils.inc -INSERT INTO t1 VALUES (1), (2), (3); +INSERT INTO t1 VALUES (1), (2), (3), (-1), (-2), (-3); --let $query = DELETE FROM t1 WHERE t1.a > 0 ORDER BY t1.a --let $select = SELECT * FROM t1 WHERE t1.a > 0 ORDER BY t1.a --source include/explain_utils.inc @@ -640,7 +640,7 @@ DROP VIEW v1; --echo #63 CREATE TABLE t1 (a INT, PRIMARY KEY(a)); -INSERT INTO t1 VALUES (1), (2), (3), (4), (5); +INSERT INTO t1 VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9); CREATE VIEW v1 (a) AS SELECT a FROM t1; --let $query = DELETE FROM v1 WHERE a < 4 --let $select = SELECT * FROM v1 WHERE a < 4 diff --git a/mysql-test/include/icp_tests.inc b/mysql-test/include/icp_tests.inc index f29088887d0..f82a5a21b87 100644 --- a/mysql-test/include/icp_tests.inc +++ b/mysql-test/include/icp_tests.inc @@ -633,6 +633,8 @@ CREATE TABLE t2 ( ); INSERT INTO t2 VALUES (4,1); +ANALYZE TABLE t1,t2; + EXPLAIN SELECT t1.d1, t2.pk, t2.i1 FROM t1 STRAIGHT_JOIN t2 ON t2.i1 WHERE t2.pk <> t1.d1 AND t2.pk = 4; @@ -840,6 +842,8 @@ INSERT INTO t2 (g,h) VALUES (3,'e'),(1,'u'),(4,'v'),(9,'u'),(6,'i'),(1,'x'), (7,'f'),(5,'j'),(3,'e'),(1,'u'),(4,'v'),(9,'u'); +ANALYZE TABLE t1,t2; + SET @save_optimize_switch=@@optimizer_switch; SET optimizer_switch='materialization=on'; diff --git a/mysql-test/include/index_merge1.inc b/mysql-test/include/index_merge1.inc index b63b2db78da..f2ef38f72f8 100644 --- a/mysql-test/include/index_merge1.inc +++ b/mysql-test/include/index_merge1.inc @@ -57,12 +57,12 @@ update t0 set key2=key1,key3=key1,key4=key1,key5=key1,key6=key1,key7=key1,key8=1 analyze table t0; # 1. One index -explain select * from t0 where key1 < 3 or key1 > 1020; +explain select * from t0 where key1 < 3 or key1 > 920 and key1 < 924; # 2. Simple cases explain -select * from t0 where key1 < 3 or key2 > 1020; -select * from t0 where key1 < 3 or key2 > 1020; +select * from t0 where key1 < 3 or key2 > 920 and key2 < 924; +select * from t0 where key1 < 3 or key2 > 920 and key2 < 924; select * from t0 where key1=1022; # MDEV-13535 no-key-read select after keyread @@ -115,7 +115,6 @@ select * from t0 where (key1 < 3 or key2 < 6) and (key1 < 7 or key3 < 4); select * from t0 where (key1 < 3 or key2 < 6) and (key1 < 7 or key3 < 4); - explain select * from t0 where (key1 < 3 or key2 < 3) and (key3 < 4 or key4 < 4) and (key5 < 2 or key6 < 2); @@ -146,6 +145,10 @@ select * from t0 where key1 < 7; # tree_or(List<SEL_IMERGE>, List<SEL_IMERGE>). +select count(*) from t0 where + ((key1 < 4 or key2 < 4) and (key3 <5 or key5 < 4)) + or + ((key5 < 5 or key6 < 6) and (key7 <7 or key8 < 4)); explain select * from t0 where ((key1 < 4 or key2 < 4) and (key3 <5 or key5 < 4)) or diff --git a/mysql-test/main/analyze_format_json.result b/mysql-test/main/analyze_format_json.result index 7991379bc55..b98500d4c34 100644 --- a/mysql-test/main/analyze_format_json.result +++ b/mysql-test/main/analyze_format_json.result @@ -315,7 +315,7 @@ ANALYZE "key_length": "4", "used_key_parts": ["pk"], "r_loops": 1, - "rows": 11, + "rows": 10, "r_rows": 10, "r_total_time_ms": "REPLACED", "filtered": 100, @@ -340,7 +340,7 @@ ANALYZE "key": "PRIMARY", "key_length": "4", "used_key_parts": ["pk"], - "rows": 11, + "rows": 10, "r_rows": 10, "r_filtered": 50, "r_total_time_ms": "REPLACED", diff --git a/mysql-test/main/analyze_stmt_orderby.result b/mysql-test/main/analyze_stmt_orderby.result index deb19d4d93a..3f6a4973d0a 100644 --- a/mysql-test/main/analyze_stmt_orderby.result +++ b/mysql-test/main/analyze_stmt_orderby.result @@ -62,7 +62,7 @@ ANALYZE explain update t2 set a=a+1 where a<10; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range a a 5 NULL 8 Using where; Using buffer +1 SIMPLE t2 range a a 5 NULL 9 Using where; Using buffer explain format=json update t2 set a=a+1 where a<10; EXPLAIN @@ -78,7 +78,7 @@ EXPLAIN "key": "a", "key_length": "5", "used_key_parts": ["a"], - "rows": 8, + "rows": 9, "attached_condition": "t2.a < 10" } } @@ -100,7 +100,7 @@ ANALYZE "key": "a", "key_length": "5", "used_key_parts": ["a"], - "rows": 8, + "rows": 9, "r_rows": 10, "r_filtered": 100, "r_total_time_ms": "REPLACED", diff --git a/mysql-test/main/ctype_binary.result b/mysql-test/main/ctype_binary.result index 8059e02611e..758c456754c 100644 --- a/mysql-test/main/ctype_binary.result +++ b/mysql-test/main/ctype_binary.result @@ -2766,11 +2766,11 @@ KEY(date_column)); INSERT INTO t1 VALUES (1,'2010-09-01'),(2,'2010-10-01'); EXPLAIN SELECT * FROM t1 WHERE date_column BETWEEN '2010-09-01' AND '2010-10-01'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range date_column date_column 4 NULL 1 Using index condition +1 SIMPLE t1 range date_column date_column 4 NULL 2 Using index condition ALTER TABLE t1 MODIFY date_column DATETIME DEFAULT NULL; EXPLAIN SELECT * FROM t1 WHERE date_column BETWEEN '2010-09-01' AND '2010-10-01'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range date_column date_column 6 NULL 1 Using index condition +1 SIMPLE t1 range date_column date_column 6 NULL 2 Using index condition DROP TABLE t1; # # Bug #31384 DATE_ADD() and DATE_SUB() return binary data diff --git a/mysql-test/main/ctype_cp1251.result b/mysql-test/main/ctype_cp1251.result index 2da53740619..548335af8ae 100644 --- a/mysql-test/main/ctype_cp1251.result +++ b/mysql-test/main/ctype_cp1251.result @@ -3175,11 +3175,11 @@ KEY(date_column)); INSERT INTO t1 VALUES (1,'2010-09-01'),(2,'2010-10-01'); EXPLAIN SELECT * FROM t1 WHERE date_column BETWEEN '2010-09-01' AND '2010-10-01'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range date_column date_column 4 NULL 1 Using index condition +1 SIMPLE t1 range date_column date_column 4 NULL 2 Using index condition ALTER TABLE t1 MODIFY date_column DATETIME DEFAULT NULL; EXPLAIN SELECT * FROM t1 WHERE date_column BETWEEN '2010-09-01' AND '2010-10-01'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range date_column date_column 6 NULL 1 Using index condition +1 SIMPLE t1 range date_column date_column 6 NULL 2 Using index condition DROP TABLE t1; # # Bug #31384 DATE_ADD() and DATE_SUB() return binary data diff --git a/mysql-test/main/ctype_latin1.result b/mysql-test/main/ctype_latin1.result index 233fd85a2c4..8098a07375a 100644 --- a/mysql-test/main/ctype_latin1.result +++ b/mysql-test/main/ctype_latin1.result @@ -3472,11 +3472,11 @@ KEY(date_column)); INSERT INTO t1 VALUES (1,'2010-09-01'),(2,'2010-10-01'); EXPLAIN SELECT * FROM t1 WHERE date_column BETWEEN '2010-09-01' AND '2010-10-01'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range date_column date_column 4 NULL 1 Using index condition +1 SIMPLE t1 range date_column date_column 4 NULL 2 Using index condition ALTER TABLE t1 MODIFY date_column DATETIME DEFAULT NULL; EXPLAIN SELECT * FROM t1 WHERE date_column BETWEEN '2010-09-01' AND '2010-10-01'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range date_column date_column 6 NULL 1 Using index condition +1 SIMPLE t1 range date_column date_column 6 NULL 2 Using index condition DROP TABLE t1; # # Bug #31384 DATE_ADD() and DATE_SUB() return binary data diff --git a/mysql-test/main/ctype_ucs.result b/mysql-test/main/ctype_ucs.result index 5641726a831..f01b3650ddf 100644 --- a/mysql-test/main/ctype_ucs.result +++ b/mysql-test/main/ctype_ucs.result @@ -256,10 +256,10 @@ t1 CREATE TABLE `t1` ( insert into t1 values ("a"),("abc"),("abcd"),("hello"),("test"); explain select * from t1 where a like 'abc%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 23 NULL 1 Using where; Using index +1 SIMPLE t1 range a a 23 NULL 2 Using where; Using index explain select * from t1 where a like concat('abc','%'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 23 NULL 1 Using where; Using index +1 SIMPLE t1 range a a 23 NULL 2 Using where; Using index select * from t1 where a like "abc%"; a abc @@ -1557,7 +1557,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range a a 23 NULL 1 Using where; Using index EXPLAIN SELECT * FROM t1 WHERE a LIKE 'c%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 23 NULL 30 Using where; Using index +1 SIMPLE t1 index a a 23 NULL 31 Using where; Using index SELECT * FROM t1 WHERE a LIKE 'c%'; a ca @@ -1573,7 +1573,7 @@ ch ALTER TABLE t1 MODIFY a VARCHAR(10) CHARACTER SET ucs2 COLLATE ucs2_croatian_ci; EXPLAIN SELECT * FROM t1 WHERE a LIKE 'd%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 23 NULL 30 Using where; Using index +1 SIMPLE t1 index a a 23 NULL 31 Using where; Using index SELECT hex(concat('d',_ucs2 0x017E,'%')); hex(concat('d',_ucs2 0x017E,'%')) 0064017E0025 @@ -4356,11 +4356,11 @@ KEY(date_column)); INSERT INTO t1 VALUES (1,'2010-09-01'),(2,'2010-10-01'); EXPLAIN SELECT * FROM t1 WHERE date_column BETWEEN '2010-09-01' AND '2010-10-01'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range date_column date_column 4 NULL 1 Using index condition +1 SIMPLE t1 range date_column date_column 4 NULL 2 Using index condition ALTER TABLE t1 MODIFY date_column DATETIME DEFAULT NULL; EXPLAIN SELECT * FROM t1 WHERE date_column BETWEEN '2010-09-01' AND '2010-10-01'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range date_column date_column 6 NULL 1 Using index condition +1 SIMPLE t1 range date_column date_column 6 NULL 2 Using index condition DROP TABLE t1; # # Bug #31384 DATE_ADD() and DATE_SUB() return binary data diff --git a/mysql-test/main/ctype_utf16.result b/mysql-test/main/ctype_utf16.result index a105017b726..784bdae7275 100644 --- a/mysql-test/main/ctype_utf16.result +++ b/mysql-test/main/ctype_utf16.result @@ -133,10 +133,10 @@ t1 CREATE TABLE `t1` ( insert into t1 values ("a"),("abc"),("abcd"),("hello"),("test"); explain select * from t1 where a like 'abc%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 43 NULL 1 Using where; Using index +1 SIMPLE t1 range a a 43 NULL 2 Using where; Using index explain select * from t1 where a like concat('abc','%'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 43 NULL 1 Using where; Using index +1 SIMPLE t1 range a a 43 NULL 2 Using where; Using index select * from t1 where a like "abc%"; a abc diff --git a/mysql-test/main/ctype_utf16_uca.result b/mysql-test/main/ctype_utf16_uca.result index 0cb9c4c74c1..17f52a91c7b 100644 --- a/mysql-test/main/ctype_utf16_uca.result +++ b/mysql-test/main/ctype_utf16_uca.result @@ -3999,7 +3999,7 @@ D801DC28 30D2 𐐨 ALTER TABLE t1 ADD KEY(c); EXPLAIN SELECT hex(c) FROM t1 WHERE c LIKE 'a%' ORDER BY c; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 43 NULL 2 Using where; Using index +1 SIMPLE t1 range c c 43 NULL 3 Using where; Using index SELECT hex(c), hex(weight_string(c)) FROM t1 WHERE c LIKE 'a%' ORDER BY c; hex(c) hex(weight_string(c)) 0061 120F diff --git a/mysql-test/main/ctype_utf16le.result b/mysql-test/main/ctype_utf16le.result index 6d8d7ddca2a..4d1186bd361 100644 --- a/mysql-test/main/ctype_utf16le.result +++ b/mysql-test/main/ctype_utf16le.result @@ -136,10 +136,10 @@ t1 CREATE TABLE `t1` ( insert into t1 values ("a"),("abc"),("abcd"),("hello"),("test"); explain select * from t1 where a like 'abc%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 43 NULL 1 Using where; Using index +1 SIMPLE t1 range a a 43 NULL 2 Using where; Using index explain select * from t1 where a like concat('abc','%'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 43 NULL 1 Using where; Using index +1 SIMPLE t1 range a a 43 NULL 2 Using where; Using index select * from t1 where a like "abc%"; a abc diff --git a/mysql-test/main/ctype_utf32.result b/mysql-test/main/ctype_utf32.result index 28b9caf6ffe..7b3eaa9384a 100644 --- a/mysql-test/main/ctype_utf32.result +++ b/mysql-test/main/ctype_utf32.result @@ -132,10 +132,10 @@ t1 CREATE TABLE `t1` ( insert into t1 values ("a"),("abc"),("abcd"),("hello"),("test"); explain select * from t1 where a like 'abc%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 43 NULL 1 Using where; Using index +1 SIMPLE t1 range a a 43 NULL 2 Using where; Using index explain select * from t1 where a like concat('abc','%'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 43 NULL 1 Using where; Using index +1 SIMPLE t1 range a a 43 NULL 2 Using where; Using index select * from t1 where a like "abc%"; a abc diff --git a/mysql-test/main/ctype_utf32_uca.result b/mysql-test/main/ctype_utf32_uca.result index a112918c0c3..aa8d2002bee 100644 --- a/mysql-test/main/ctype_utf32_uca.result +++ b/mysql-test/main/ctype_utf32_uca.result @@ -4019,7 +4019,7 @@ hex(c) hex(weight_string(c)) c ALTER TABLE t1 ADD KEY(c); EXPLAIN SELECT hex(c) FROM t1 WHERE c LIKE 'a%' ORDER BY c; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 43 NULL 2 Using where; Using index +1 SIMPLE t1 range c c 43 NULL 3 Using where; Using index SELECT hex(c), hex(weight_string(c)) FROM t1 WHERE c LIKE 'a%' ORDER BY c; hex(c) hex(weight_string(c)) 00000061 120F diff --git a/mysql-test/main/ctype_utf8.result b/mysql-test/main/ctype_utf8.result index d696ff78831..a193eba64e3 100644 --- a/mysql-test/main/ctype_utf8.result +++ b/mysql-test/main/ctype_utf8.result @@ -5223,11 +5223,11 @@ KEY(date_column)); INSERT INTO t1 VALUES (1,'2010-09-01'),(2,'2010-10-01'); EXPLAIN SELECT * FROM t1 WHERE date_column BETWEEN '2010-09-01' AND '2010-10-01'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range date_column date_column 4 NULL 1 Using index condition +1 SIMPLE t1 range date_column date_column 4 NULL 2 Using index condition ALTER TABLE t1 MODIFY date_column DATETIME DEFAULT NULL; EXPLAIN SELECT * FROM t1 WHERE date_column BETWEEN '2010-09-01' AND '2010-10-01'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range date_column date_column 6 NULL 1 Using index condition +1 SIMPLE t1 range date_column date_column 6 NULL 2 Using index condition DROP TABLE t1; # # Bug #31384 DATE_ADD() and DATE_SUB() return binary data diff --git a/mysql-test/main/derived_cond_pushdown.result b/mysql-test/main/derived_cond_pushdown.result index dac180301d7..c73fb80d1a4 100644 --- a/mysql-test/main/derived_cond_pushdown.result +++ b/mysql-test/main/derived_cond_pushdown.result @@ -7778,7 +7778,7 @@ EXPLAIN "key": "PRIMARY", "key_length": "4", "used_key_parts": ["pk"], - "rows": 2, + "rows": 1, "filtered": 100, "index_condition": "t.pk > 2" } @@ -14981,7 +14981,7 @@ from t1 join on t1.a=t.a where t1.b <= 5; id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 ALL idx_b NULL NULL NULL 12 75.00 Using where +1 PRIMARY t1 ALL idx_b NULL NULL NULL 12 83.33 Using where 1 PRIMARY <derived2> ref key0 key0 5 test.t1.a 9 100.00 2 DERIVED t2 ALL idx_a NULL NULL NULL 90 100.00 Using temporary; Using filesort Warnings: @@ -15000,7 +15000,7 @@ EXPLAIN "access_type": "ALL", "possible_keys": ["idx_b"], "rows": 12, - "filtered": 75, + "filtered": 83.333, "attached_condition": "t1.b <= 5 and t1.a is not null" }, "table": { @@ -15174,7 +15174,7 @@ from t3 join on t3.a=t.a and t3.c=t.c where t3.b > 15; id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t3 range idx_b idx_b 5 NULL 3 100.00 Using index condition; Using where +1 PRIMARY t3 range idx_b idx_b 5 NULL 2 100.00 Using index condition; Using where 1 PRIMARY <derived2> ref key0 key0 133 test.t3.a,test.t3.c 2 100.00 2 LATERAL DERIVED t4 ref idx idx 133 test.t3.a,test.t3.c 1 100.00 Warnings: @@ -15195,7 +15195,7 @@ EXPLAIN "key": "idx_b", "key_length": "5", "used_key_parts": ["b"], - "rows": 3, + "rows": 2, "filtered": 100, "index_condition": "t3.b > 15", "attached_condition": "t3.a is not null and t3.c is not null" @@ -15252,7 +15252,7 @@ from t3 join on t3.a=t.a and t3.c=t.c where t3.b <= 15; id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t3 ALL idx_b NULL NULL NULL 12 75.00 Using where +1 PRIMARY t3 ALL idx_b NULL NULL NULL 12 83.33 Using where 1 PRIMARY <derived2> ref key0 key0 133 test.t3.a,test.t3.c 4 100.00 2 DERIVED t4 ALL idx NULL NULL NULL 40 100.00 Using temporary; Using filesort Warnings: @@ -15271,7 +15271,7 @@ EXPLAIN "access_type": "ALL", "possible_keys": ["idx_b"], "rows": 12, - "filtered": 75, + "filtered": 83.333, "attached_condition": "t3.b <= 15 and t3.a is not null and t3.c is not null" }, "table": { @@ -15326,7 +15326,7 @@ from t3 join on t3.a=t.a and t3.c=t.c where t3.b > 15; id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t3 range idx_b idx_b 5 NULL 3 100.00 Using index condition; Using where +1 PRIMARY t3 range idx_b idx_b 5 NULL 2 100.00 Using index condition; Using where 1 PRIMARY <derived2> ref key0 key0 133 test.t3.a,test.t3.c 2 100.00 2 LATERAL DERIVED t4 ref idx idx 133 test.t3.a,test.t3.c 1 100.00 Warnings: @@ -15347,7 +15347,7 @@ EXPLAIN "key": "idx_b", "key_length": "5", "used_key_parts": ["b"], - "rows": 3, + "rows": 2, "filtered": 100, "index_condition": "t3.b > 15", "attached_condition": "t3.a is not null and t3.c is not null" @@ -15404,7 +15404,7 @@ from t3 join on t3.a=t.a and t3.c=t.c where t3.b <= 15; id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t3 ALL idx_b NULL NULL NULL 12 75.00 Using where +1 PRIMARY t3 ALL idx_b NULL NULL NULL 12 83.33 Using where 1 PRIMARY <derived2> ref key0 key0 133 test.t3.a,test.t3.c 4 100.00 2 DERIVED t4 ALL idx NULL NULL NULL 40 100.00 Using temporary; Using filesort Warnings: @@ -15423,7 +15423,7 @@ EXPLAIN "access_type": "ALL", "possible_keys": ["idx_b"], "rows": 12, - "filtered": 75, + "filtered": 83.333, "attached_condition": "t3.b <= 15 and t3.a is not null and t3.c is not null" }, "table": { diff --git a/mysql-test/main/derived_opt.result b/mysql-test/main/derived_opt.result index 48ac7e62653..c30f56d9925 100644 --- a/mysql-test/main/derived_opt.result +++ b/mysql-test/main/derived_opt.result @@ -534,7 +534,7 @@ LEFT JOIN ON t2.id=t.id WHERE t2.id < 3; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 3 Using index condition +1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 Using index condition 1 PRIMARY <derived2> ref key0 key0 5 test.t2.id 2 2 DERIVED t1 ALL NULL NULL NULL NULL 8 Using temporary; Using filesort set join_cache_level=default; diff --git a/mysql-test/main/endspace.result b/mysql-test/main/endspace.result index f9619db7e64..a0f53167148 100644 --- a/mysql-test/main/endspace.result +++ b/mysql-test/main/endspace.result @@ -145,8 +145,8 @@ teststring teststring select * from t1 where text1='teststring' or text1 >= 'teststring\t'; text1 -teststring teststring +teststring select * from t1 order by text1; text1 nothing diff --git a/mysql-test/main/explain.result b/mysql-test/main/explain.result index f593e0dfaba..bc3c53d01d3 100644 --- a/mysql-test/main/explain.result +++ b/mysql-test/main/explain.result @@ -13,7 +13,7 @@ id str 3 foo explain select * from t1 where str is null; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref str str 11 const 1 Using index condition +1 SIMPLE t1 ref str str 11 const 2 Using index condition explain select * from t1 where str="foo"; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 const str str 11 const 1 @@ -311,9 +311,15 @@ INSERT INTO t1 VALUES(4, 1, 1, 1); INSERT INTO t1 VALUES(3, 1, 1, 1); INSERT INTO t1 VALUES(2, 1, 1, 1); INSERT INTO t1 VALUES(1, 1, 1, 1); +INSERT INTO t1 VALUES(5, 2, 1, 1); +INSERT INTO t1 VALUES(6, 2, 1, 1); +INSERT INTO t1 VALUES(7, 3, 1, 1); +INSERT INTO t1 VALUES(9, 3, 1, 1); +INSERT INTO t1 VALUES(10, 4, 1, 1); +INSERT INTO t1 VALUES(11, 4, 1, 1); EXPLAIN SELECT c1 FROM t1 WHERE c2 = 1 AND c4 = 1 AND c5 = 1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref c2,c2_2 c2 10 const,const 3 Using where +1 SIMPLE t1 ref c2,c2_2 c2 10 const,const 4 Using where DROP TABLE t1; # # Bug#56814 Explain + subselect + fulltext crashes server diff --git a/mysql-test/main/explain.test b/mysql-test/main/explain.test index d5be354c852..cf9f6be09ed 100644 --- a/mysql-test/main/explain.test +++ b/mysql-test/main/explain.test @@ -238,6 +238,12 @@ INSERT INTO t1 VALUES(4, 1, 1, 1); INSERT INTO t1 VALUES(3, 1, 1, 1); INSERT INTO t1 VALUES(2, 1, 1, 1); INSERT INTO t1 VALUES(1, 1, 1, 1); +INSERT INTO t1 VALUES(5, 2, 1, 1); +INSERT INTO t1 VALUES(6, 2, 1, 1); +INSERT INTO t1 VALUES(7, 3, 1, 1); +INSERT INTO t1 VALUES(9, 3, 1, 1); +INSERT INTO t1 VALUES(10, 4, 1, 1); +INSERT INTO t1 VALUES(11, 4, 1, 1); EXPLAIN SELECT c1 FROM t1 WHERE c2 = 1 AND c4 = 1 AND c5 = 1; diff --git a/mysql-test/main/explain_json.result b/mysql-test/main/explain_json.result index ef6b70aff71..df82b2e31cc 100644 --- a/mysql-test/main/explain_json.result +++ b/mysql-test/main/explain_json.result @@ -739,7 +739,7 @@ EXPLAIN "key": "a", "key_length": "5", "used_key_parts": ["a"], - "rows": 1, + "rows": 2, "filtered": 100, "index_condition": "t1.a < 3", "mrr_type": "Rowid-ordered scan" diff --git a/mysql-test/main/func_group.result b/mysql-test/main/func_group.result index 9f3928615ec..5526acb8825 100644 --- a/mysql-test/main/func_group.result +++ b/mysql-test/main/func_group.result @@ -612,12 +612,12 @@ id select_type table type possible_keys key key_len ref rows Extra explain select max(a3) from t1 where a2 < 2 and a3 < 'SEA'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range k1 k1 3 NULL 6 Using where; Using index +1 SIMPLE t1 range k1 k1 3 NULL 7 Using where; Using index explain -select max(t1.a3), min(t2.a2) from t1, t2 where t1.a2 = 2 and t1.a3 < 'MIN' and t2.a3 > 'CA'; +select max(t1.a3), min(t2.a2) from t1, t2 where t1.a2 = 2 and t1.a3 < 'DEN' and t2.a3 >= 'LA'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range k1 k1 7 NULL 1 Using where; Using index -1 SIMPLE t2 range k1 k1 3 NULL 4 Using where; Using index; Using join buffer (flat, BNL join) +1 SIMPLE t2 range k1 k1 3 NULL 2 Using where; Using index; Using join buffer (flat, BNL join) explain select min(a4 - 0.01) from t1; id select_type table type possible_keys key key_len ref rows Extra @@ -653,7 +653,7 @@ id select_type table type possible_keys key key_len ref rows Extra explain select concat(min(t1.a1),min(t2.a4)) from t1, t2 where t2.a4 <> 'AME'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range k2 k2 4 NULL 6 Using where; Using index +1 SIMPLE t2 index k2 k2 4 NULL 7 Using where; Using index 1 SIMPLE t1 index NULL PRIMARY 3 NULL 15 Using index; Using join buffer (flat, BNL join) drop table t1, t2; create table t1 (a char(10)); @@ -1333,10 +1333,11 @@ SELECT MIN(a), MIN(b) FROM t1; MIN(a) MIN(b) NULL 1 CREATE TABLE t2( a INT, b INT, c INT, KEY(a, b) ); -INSERT INTO t2 ( a, b, c ) VALUES ( 1, NULL, 2 ), ( 1, 3, 4 ), ( 1, 4, 4 ); +INSERT INTO t2 ( a, b, c ) VALUES +( 1, NULL, 2 ), ( 1, 3, 4 ), ( 1, 4, 4 ), ( 2, NULL, 2 ), ( 2, 3, 4 ), ( 2, 4, 4 ); EXPLAIN SELECT MIN(b), MIN(c) FROM t2 WHERE a = 1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ref a a 5 const 2 +1 SIMPLE t2 ref a a 5 const 3 SELECT MIN(b), MIN(c) FROM t2 WHERE a = 1; MIN(b) MIN(c) 3 2 @@ -1839,12 +1840,12 @@ End of 5.1 tests # Bug #904345: MIN/MAX optimization with constant FALSE condition # CREATE TABLE t1 (a int NOT NULL, KEY(a)); -INSERT INTO t1 VALUES (10), (8), (11), (7), (15), (12), (9); +INSERT INTO t1 VALUES (10), (8), (11), (7), (15), (12), (9), (13), (15), (17); CREATE TABLE t2 (a int, b int); INSERT INTO t2 VALUES (8,2), (6,9), (8,4), (5,3), (9,1); EXPLAIN EXTENDED -SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT 3,4) AND a<10; +SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT 3,4) AND a<8; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE 2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used @@ -1857,7 +1858,7 @@ EXPLAIN EXTENDED SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT a,b FROM t2 WHERE b<5) and a<10; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1 100.00 -1 PRIMARY t1 range a a 4 NULL 4 100.00 Using where; Using index; Using join buffer (flat, BNL join) +1 PRIMARY t1 range a a 4 NULL 3 100.00 Using where; Using index; Using join buffer (flat, BNL join) 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where Warnings: Note 1003 select max(`test`.`t1`.`a`) AS `MAX(a)` from `test`.`t1` semi join (`test`.`t2`) where `test`.`t2`.`a` = 1 and `test`.`t2`.`b` = 2 and `test`.`t1`.`a` < 10 @@ -1867,7 +1868,7 @@ NULL EXPLAIN EXTENDED SELECT MAX(a) FROM t1 WHERE RAND()*0<>0 AND a<10; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 range a a 4 NULL 4 100.00 Using where; Using index +1 SIMPLE t1 range a a 4 NULL 3 100.00 Using where; Using index Warnings: Note 1003 select max(`test`.`t1`.`a`) AS `MAX(a)` from `test`.`t1` where rand() * 0 <> 0 and `test`.`t1`.`a` < 10 SELECT MAX(a) FROM t1 WHERE RAND()*0<>0 AND a<10; diff --git a/mysql-test/main/func_group.test b/mysql-test/main/func_group.test index d847f7cd5f7..bc2d6e9047d 100644 --- a/mysql-test/main/func_group.test +++ b/mysql-test/main/func_group.test @@ -363,7 +363,7 @@ select min(a1) from t1 where a1 != 'KKK'; explain select max(a3) from t1 where a2 < 2 and a3 < 'SEA'; explain -select max(t1.a3), min(t2.a2) from t1, t2 where t1.a2 = 2 and t1.a3 < 'MIN' and t2.a3 > 'CA'; +select max(t1.a3), min(t2.a2) from t1, t2 where t1.a2 = 2 and t1.a3 < 'DEN' and t2.a3 >= 'LA'; explain select min(a4 - 0.01) from t1; @@ -849,7 +849,8 @@ EXPLAIN SELECT MIN(a), MIN(b) FROM t1; SELECT MIN(a), MIN(b) FROM t1; CREATE TABLE t2( a INT, b INT, c INT, KEY(a, b) ); -INSERT INTO t2 ( a, b, c ) VALUES ( 1, NULL, 2 ), ( 1, 3, 4 ), ( 1, 4, 4 ); +INSERT INTO t2 ( a, b, c ) VALUES + ( 1, NULL, 2 ), ( 1, 3, 4 ), ( 1, 4, 4 ), ( 2, NULL, 2 ), ( 2, 3, 4 ), ( 2, 4, 4 ); EXPLAIN SELECT MIN(b), MIN(c) FROM t2 WHERE a = 1; SELECT MIN(b), MIN(c) FROM t2 WHERE a = 1; @@ -1168,14 +1169,14 @@ drop table t1; --echo # CREATE TABLE t1 (a int NOT NULL, KEY(a)); -INSERT INTO t1 VALUES (10), (8), (11), (7), (15), (12), (9); +INSERT INTO t1 VALUES (10), (8), (11), (7), (15), (12), (9), (13), (15), (17); CREATE TABLE t2 (a int, b int); INSERT INTO t2 VALUES (8,2), (6,9), (8,4), (5,3), (9,1); EXPLAIN EXTENDED -SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT 3,4) AND a<10; +SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT 3,4) AND a<8; SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT 3,4) AND a<10; EXPLAIN EXTENDED diff --git a/mysql-test/main/func_group_innodb.result b/mysql-test/main/func_group_innodb.result index 27493ae710b..5be46ed95b3 100644 --- a/mysql-test/main/func_group_innodb.result +++ b/mysql-test/main/func_group_innodb.result @@ -1,3 +1,8 @@ +set @innodb_stats_persistent_save= @@innodb_stats_persistent; +set @innodb_stats_persistent_sample_pages_save= +@@innodb_stats_persistent_sample_pages; +set global innodb_stats_persistent= 1; +set global innodb_stats_persistent_sample_pages=100; create table t1 (USR_ID integer not null, MAX_REQ integer not null, constraint PK_SEA_USER primary key (USR_ID)) engine=InnoDB; insert into t1 values (1, 3); select count(*) + MAX_REQ - MAX_REQ + MAX_REQ - MAX_REQ + MAX_REQ - MAX_REQ + MAX_REQ - MAX_REQ + MAX_REQ - MAX_REQ from t1 group by MAX_REQ; @@ -237,7 +242,9 @@ SET storage_engine=@old_engine; CREATE TABLE t1(a BLOB, b VARCHAR(255) CHARSET LATIN1, c INT, KEY(b, c, a(765))) ENGINE=INNODB; INSERT INTO t1(a, b, c) VALUES -('', 'a', 0), ('', 'a', null), ('', 'a', 0), ('', 'a', null), ('', 'a', 0); +('', 'a', 0), ('', 'a', null), ('', 'a', 0), ('', 'a', null), ('', 'a', 0), +('', 'a', 1), ('', 'a', 1), ('', 'a', 2), ('', 'a', 2), ('', 'a', 3), +('', 'a', 3), ('', 'a', 4), ('', 'a', 4), ('', 'a', 5), ('', 'a', 5); ANALYZE TABLE t1; SELECT MIN(c) FROM t1 GROUP BY b; MIN(c) @@ -247,3 +254,6 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range NULL b 263 NULL 3 Using index for group-by DROP TABLE t1; End of 5.5 tests +set global innodb_stats_persistent= @innodb_stats_persistent_save; +set global innodb_stats_persistent_sample_pages= +@innodb_stats_persistent_sample_pages_save; diff --git a/mysql-test/main/func_group_innodb.test b/mysql-test/main/func_group_innodb.test index 1d175f85ed9..0aa657badc1 100644 --- a/mysql-test/main/func_group_innodb.test +++ b/mysql-test/main/func_group_innodb.test @@ -4,6 +4,13 @@ --source include/have_innodb.inc +set @innodb_stats_persistent_save= @@innodb_stats_persistent; +set @innodb_stats_persistent_sample_pages_save= + @@innodb_stats_persistent_sample_pages; + +set global innodb_stats_persistent= 1; +set global innodb_stats_persistent_sample_pages=100; + --disable_warnings create table t1 (USR_ID integer not null, MAX_REQ integer not null, constraint PK_SEA_USER primary key (USR_ID)) engine=InnoDB; --enable_warnings @@ -181,7 +188,9 @@ SET storage_engine=@old_engine; CREATE TABLE t1(a BLOB, b VARCHAR(255) CHARSET LATIN1, c INT, KEY(b, c, a(765))) ENGINE=INNODB; INSERT INTO t1(a, b, c) VALUES -('', 'a', 0), ('', 'a', null), ('', 'a', 0), ('', 'a', null), ('', 'a', 0); +('', 'a', 0), ('', 'a', null), ('', 'a', 0), ('', 'a', null), ('', 'a', 0), +('', 'a', 1), ('', 'a', 1), ('', 'a', 2), ('', 'a', 2), ('', 'a', 3), +('', 'a', 3), ('', 'a', 4), ('', 'a', 4), ('', 'a', 5), ('', 'a', 5); -- disable_result_log ANALYZE TABLE t1; @@ -193,3 +202,7 @@ EXPLAIN SELECT MIN(c) FROM t1 GROUP BY b; DROP TABLE t1; --echo End of 5.5 tests + +set global innodb_stats_persistent= @innodb_stats_persistent_save; +set global innodb_stats_persistent_sample_pages= + @innodb_stats_persistent_sample_pages_save; diff --git a/mysql-test/main/func_in.result b/mysql-test/main/func_in.result index acf718c453e..9a3c1dba045 100644 --- a/mysql-test/main/func_in.result +++ b/mysql-test/main/func_in.result @@ -241,7 +241,7 @@ insert into t2 select C.a*2+1, 'yes' from t1 C; explain select * from t2 where a NOT IN (0, 2,4,6,8,10,12,14,16,18); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range a a 5 NULL 12 Using index condition +1 SIMPLE t2 range a a 5 NULL 11 Using index condition select * from t2 where a NOT IN (0, 2,4,6,8,10,12,14,16,18); a filler 1 yes @@ -271,7 +271,7 @@ select * from t2 where a NOT IN ( '2006-04-25 10:00:00','2006-04-25 10:02:00','2006-04-25 10:04:00', '2006-04-25 10:06:00', '2006-04-25 10:08:00'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range a a 6 NULL 12 Using index condition +1 SIMPLE t2 range a a 6 NULL 11 Using index condition select * from t2 where a NOT IN ( '2006-04-25 10:00:00','2006-04-25 10:02:00','2006-04-25 10:04:00', '2006-04-25 10:06:00', '2006-04-25 10:08:00'); @@ -295,7 +295,7 @@ insert into t2 values ('fon', '1'), ('fop','1'), ('barbaq','1'), ('barbas','1'), ('bazbazbay', '1'),('zz','1'); explain select * from t2 where a not in('foo','barbar', 'bazbazbaz'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range a a 13 NULL 7 Using index condition +1 SIMPLE t2 range a a 13 NULL 6 Using index condition drop table t2; create table t2 (a decimal(10,5), filler char(200), key(a)); insert into t2 select 345.67890, 'no' from t1 A, t1 B; @@ -306,7 +306,7 @@ insert into t2 values (0, '1'), (22334.123,'1'), (33333,'1'), explain select * from t2 where a not in (345.67890, 43245.34, 64224.56344); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range a a 7 NULL 7 Using index condition +1 SIMPLE t2 range a a 7 NULL 6 Using index condition select * from t2 where a not in (345.67890, 43245.34, 64224.56344); a filler 0.00000 1 diff --git a/mysql-test/main/func_like.result b/mysql-test/main/func_like.result index 06a549e94b2..a937037167c 100644 --- a/mysql-test/main/func_like.result +++ b/mysql-test/main/func_like.result @@ -3,12 +3,12 @@ create table t1 (a varchar(10), key(a)); insert into t1 values ("a"),("abc"),("abcd"),("hello"),("test"); explain extended select * from t1 where a like 'abc%'; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 index a a 13 NULL 5 20.00 Using where; Using index +1 SIMPLE t1 index a a 13 NULL 5 40.00 Using where; Using index Warnings: Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` like 'abc%' explain extended select * from t1 where a like concat('abc','%'); id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 index a a 13 NULL 5 20.00 Using where; Using index +1 SIMPLE t1 index a a 13 NULL 5 40.00 Using where; Using index Warnings: Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` like <cache>(concat('abc','%')) select * from t1 where a like "abc%"; diff --git a/mysql-test/main/func_str.result b/mysql-test/main/func_str.result index 07dca08c819..484127a7414 100644 --- a/mysql-test/main/func_str.result +++ b/mysql-test/main/func_str.result @@ -1423,7 +1423,7 @@ SELECT * FROM t1 INNER JOIN t2 ON code=id WHERE id='a12' AND (LENGTH(code)=5 OR code < 'a00'); id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 const PRIMARY PRIMARY 12 const 1 100.00 Using index -1 SIMPLE t1 ref code code 13 const 3 100.00 Using where; Using index +1 SIMPLE t1 ref code code 13 const 4 100.00 Using where; Using index Warnings: Note 1003 select `test`.`t1`.`code` AS `code`,'a12' AS `id` from `test`.`t1` join `test`.`t2` where `test`.`t1`.`code` = 'a12' and octet_length(`test`.`t1`.`code`) = 5 DROP TABLE t1,t2; diff --git a/mysql-test/main/group_by.result b/mysql-test/main/group_by.result index 6f1887290c0..5cf79b0de4e 100644 --- a/mysql-test/main/group_by.result +++ b/mysql-test/main/group_by.result @@ -2429,7 +2429,11 @@ a int, b varchar(1), KEY (b,a) ); -INSERT INTO t1 VALUES (1,NULL),(0,'a'),(1,NULL),(0,'a'); +INSERT INTO t1 VALUES +(1,NULL),(0,'a'),(1,NULL),(0,'a'), (1,'a'),(0,'a'),(2,'a'),(1,'a'); +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK EXPLAIN SELECT SQL_BUFFER_RESULT MIN(a), b FROM t1 WHERE t1.b = 'a' GROUP BY b; id select_type table type possible_keys key key_len ref rows Extra diff --git a/mysql-test/main/group_by.test b/mysql-test/main/group_by.test index 5574a6654cf..c14023f817a 100644 --- a/mysql-test/main/group_by.test +++ b/mysql-test/main/group_by.test @@ -1545,7 +1545,9 @@ CREATE TABLE t1 ( b varchar(1), KEY (b,a) ); -INSERT INTO t1 VALUES (1,NULL),(0,'a'),(1,NULL),(0,'a'); +INSERT INTO t1 VALUES + (1,NULL),(0,'a'),(1,NULL),(0,'a'), (1,'a'),(0,'a'),(2,'a'),(1,'a'); +ANALYZE TABLE t1; let $query= SELECT SQL_BUFFER_RESULT MIN(a), b FROM t1 WHERE t1.b = 'a' GROUP BY b; diff --git a/mysql-test/main/group_min_max.result b/mysql-test/main/group_min_max.result index cfdf9ef9865..4667c4b6daa 100644 --- a/mysql-test/main/group_min_max.result +++ b/mysql-test/main/group_min_max.result @@ -317,7 +317,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 147 NULL 14 Using where; Using index for group-by explain select a1, max(c) from t1 where a1 in ('a','b','d') group by a1,a2,b; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 147 NULL 14 Using where; Using index for group-by +1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 147 NULL 13 Using where; Using index for group-by explain select a1,a2,b, max(c) from t2 where a1 < 'd' group by a1,a2,b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 range idx_t2_0,idx_t2_1,idx_t2_2 idx_t2_1 146 NULL # Using where; Using index for group-by @@ -1653,7 +1653,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range NULL idx_t1_1 163 NULL 17 Using where; Using index for group-by explain select a1,a2,b from t1 where (a1 > 'a') and (a2 > 'a') and (b = 'c') group by a1,a2,b; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 147 NULL 14 Using where; Using index for group-by +1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_2 147 NULL 13 Using where; Using index for group-by explain select a1,a2,b from t2 where (a1 >= 'c' or a2 < 'b') and (b > 'a') group by a1,a2,b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 range idx_t2_0,idx_t2_1,idx_t2_2 idx_t2_1 146 NULL # Using where; Using index for group-by @@ -1718,7 +1718,7 @@ Warnings: Note 1003 select distinct `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where `test`.`t1`.`b` = 'a' and `test`.`t1`.`c` = 'i121' and `test`.`t1`.`a2` >= 'b' explain select distinct a1,a2,b from t1 where (a1 > 'a') and (a2 > 'a') and (b = 'c'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 147 NULL 14 Using where; Using index for group-by +1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_2 147 NULL 13 Using where; Using index for group-by explain select distinct b from t1 where (a2 >= 'b') and (b = 'a'); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index NULL idx_t1_2 147 NULL 128 Using where; Using index @@ -1864,7 +1864,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range NULL idx_t1_1 163 NULL 17 Using where; Using index for group-by explain select distinct a1,a2,b from t1 where (a1 > 'a') and (a2 > 'a') and (b = 'c') group by a1,a2,b; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 147 NULL 14 Using where; Using index for group-by +1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_2 147 NULL 13 Using where; Using index for group-by explain select distinct b from t1 where (a2 >= 'b') and (b = 'a') group by a1,a2,b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range NULL idx_t1_1 147 NULL 17 Using where; Using index for group-by; Using temporary; Using filesort @@ -1959,7 +1959,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range NULL idx_t1_1 163 NULL 65 Using where; Using index for group-by (scanning) explain extended select count(distinct a1,a2,b) from t1 where (a1 > 'a') and (a2 > 'a') and (b = 'c'); id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 147 NULL 14 100.00 Using where; Using index for group-by +1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_2 147 NULL 13 100.00 Using where; Using index for group-by Warnings: Note 1003 select count(distinct `test`.`t1`.`a1`,`test`.`t1`.`a2`,`test`.`t1`.`b`) AS `count(distinct a1,a2,b)` from `test`.`t1` where `test`.`t1`.`b` = 'c' and `test`.`t1`.`a1` > 'a' and `test`.`t1`.`a2` > 'a' explain select count(distinct b) from t1 where (a2 >= 'b') and (b = 'a'); @@ -1967,7 +1967,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index NULL idx_t1_2 147 NULL 128 Using where; Using index explain extended select 98 + count(distinct a1,a2,b) from t1 where (a1 > 'a') and (a2 > 'a'); id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 147 NULL 14 100.00 Using where; Using index for group-by +1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_2 147 NULL 13 100.00 Using where; Using index for group-by Warnings: Note 1003 select 98 + count(distinct `test`.`t1`.`a1`,`test`.`t1`.`a2`,`test`.`t1`.`b`) AS `98 + count(distinct a1,a2,b)` from `test`.`t1` where `test`.`t1`.`a1` > 'a' and `test`.`t1`.`a2` > 'a' select count(distinct a1,a2,b) from t1 where (a2 >= 'b') and (b = 'a'); @@ -2075,19 +2075,19 @@ id select_type table type possible_keys key key_len ref rows Extra explain extended select a1,a2,min(b),max(b) from t1 where (a1 = 'b' or a1 = 'd' or a1 = 'a' or a1 = 'c') and (a2 > 'a') and (c > 'a111') group by a1,a2; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 130 NULL 76 85.53 Using where; Using index +1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 130 NULL 77 85.71 Using where; Using index Warnings: Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,min(`test`.`t1`.`b`) AS `min(b)`,max(`test`.`t1`.`b`) AS `max(b)` from `test`.`t1` where (`test`.`t1`.`a1` = 'b' or `test`.`t1`.`a1` = 'd' or `test`.`t1`.`a1` = 'a' or `test`.`t1`.`a1` = 'c') and `test`.`t1`.`a2` > 'a' and `test`.`t1`.`c` > 'a111' group by `test`.`t1`.`a1`,`test`.`t1`.`a2` explain extended select a1,a2,b,min(c),max(c) from t1 where (a1 = 'b' or a1 = 'd' or a1 = 'a' or a1 = 'c') and (a2 > 'a') and (d > 'xy2') group by a1,a2,b; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 ALL idx_t1_0,idx_t1_1,idx_t1_2 NULL NULL NULL 128 50.78 Using where; Using temporary; Using filesort +1 SIMPLE t1 ALL idx_t1_0,idx_t1_1,idx_t1_2 NULL NULL NULL 128 51.56 Using where; Using temporary; Using filesort Warnings: Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,`test`.`t1`.`b` AS `b`,min(`test`.`t1`.`c`) AS `min(c)`,max(`test`.`t1`.`c`) AS `max(c)` from `test`.`t1` where (`test`.`t1`.`a1` = 'b' or `test`.`t1`.`a1` = 'd' or `test`.`t1`.`a1` = 'a' or `test`.`t1`.`a1` = 'c') and `test`.`t1`.`a2` > 'a' and `test`.`t1`.`d` > 'xy2' group by `test`.`t1`.`a1`,`test`.`t1`.`a2`,`test`.`t1`.`b` explain extended select a1,a2,b,c from t1 where (a1 = 'b' or a1 = 'd' or a1 = 'a' or a1 = 'c') and (a2 > 'a') and (d > 'xy2') group by a1,a2,b,c; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 ALL idx_t1_0,idx_t1_1,idx_t1_2 NULL NULL NULL 128 50.78 Using where; Using temporary; Using filesort +1 SIMPLE t1 ALL idx_t1_0,idx_t1_1,idx_t1_2 NULL NULL NULL 128 51.56 Using where; Using temporary; Using filesort Warnings: Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where (`test`.`t1`.`a1` = 'b' or `test`.`t1`.`a1` = 'd' or `test`.`t1`.`a1` = 'a' or `test`.`t1`.`a1` = 'c') and `test`.`t1`.`a2` > 'a' and `test`.`t1`.`d` > 'xy2' group by `test`.`t1`.`a1`,`test`.`t1`.`a2`,`test`.`t1`.`b`,`test`.`t1`.`c` explain select a1,a2,b,max(c),min(c) from t2 where (a2 = 'a') and (b = 'b') or (b < 'b') group by a1; @@ -2095,7 +2095,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 index NULL idx_t2_1 163 NULL 164 Using where; Using index explain extended select a1,a2,b from t1 where (a1 = 'b' or a1 = 'd' or a1 = 'a' or a1 = 'c') and (a2 > 'a') and (c > 'a111') group by a1,a2,b; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 130 NULL 76 85.53 Using where; Using index +1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 130 NULL 77 85.71 Using where; Using index Warnings: Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a1` = 'b' or `test`.`t1`.`a1` = 'd' or `test`.`t1`.`a1` = 'a' or `test`.`t1`.`a1` = 'c') and `test`.`t1`.`a2` > 'a' and `test`.`t1`.`c` > 'a111' group by `test`.`t1`.`a1`,`test`.`t1`.`a2`,`test`.`t1`.`b` explain select a1,a2,min(b),c from t2 where (a2 = 'a') and (c = 'a111') group by a1; @@ -2119,12 +2119,12 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index NULL idx_t1_2 147 NULL 128 Using index explain extended select a1,a2,count(a2) from t1 where (a1 > 'a') group by a1,a2,b; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 index idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_2 147 NULL 128 75.00 Using where; Using index +1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_2 65 NULL 101 95.05 Using where; Using index Warnings: Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,count(`test`.`t1`.`a2`) AS `count(a2)` from `test`.`t1` where `test`.`t1`.`a1` > 'a' group by `test`.`t1`.`a1`,`test`.`t1`.`a2`,`test`.`t1`.`b` explain extended select sum(ord(a1)) from t1 where (a1 > 'a') group by a1,a2,b; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 index idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_2 147 NULL 128 75.00 Using where; Using index +1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_2 65 NULL 101 95.05 Using where; Using index Warnings: Note 1003 select sum(ord(`test`.`t1`.`a1`)) AS `sum(ord(a1))` from `test`.`t1` where `test`.`t1`.`a1` > 'a' group by `test`.`t1`.`a1`,`test`.`t1`.`a2`,`test`.`t1`.`b` create table t4 as select distinct a1, a2, b, c from t1; @@ -2225,7 +2225,7 @@ a BB EXPLAIN SELECT a FROM t1 WHERE a='AA' GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref PRIMARY PRIMARY 7 const 3 Using where; Using index +1 SIMPLE t1 ref PRIMARY PRIMARY 7 const 4 Using where; Using index EXPLAIN SELECT a FROM t1 WHERE a='BB' GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref PRIMARY PRIMARY 7 const 1 Using where; Using index @@ -2281,9 +2281,15 @@ INSERT INTO t1 (a) VALUES (''), ('CENTRAL'), ('EASTERN'), ('GREATER LONDON'), ('NORTH CENTRAL'), ('NORTH EAST'), ('NORTH WEST'), ('SCOTLAND'), ('SOUTH EAST'), ('SOUTH WEST'), ('WESTERN'); +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK EXPLAIN SELECT DISTINCT a,a FROM t1 ORDER BY a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range NULL a 66 NULL 6 Using index for group-by +1 SIMPLE t1 range NULL a 66 NULL 12 Using index for group-by SELECT DISTINCT a,a FROM t1 ORDER BY a; a a @@ -2342,10 +2348,15 @@ id2 id3 id5 id4 id3 id6 id5 id1 1 1 1 1 1 1 1 1 DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (a int, b int, KEY (a,b), KEY b (b)); -INSERT INTO t1 VALUES (1,1),(1,2),(1,0),(1,3); +INSERT INTO t1 VALUES +(1,1),(1,2),(1,0),(1,3), +(1,-1),(1,-2),(1,-3),(1,-4); +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK explain SELECT MAX(b), a FROM t1 WHERE b < 2 AND a = 1 GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a,b a 10 NULL 1 Using where; Using index for group-by +1 SIMPLE t1 range a,b a 10 NULL 2 Using where; Using index for group-by SELECT MAX(b), a FROM t1 WHERE b < 2 AND a = 1 GROUP BY a; MAX(b) a 1 1 @@ -2364,9 +2375,12 @@ DROP TABLE t1,t2; CREATE TABLE t1 (a INT, b INT, INDEX (a,b)); INSERT INTO t1 (a, b) VALUES (1,1), (1,2), (1,3), (1,4), (1,5), (2,2), (2,3), (2,1), (3,1), (4,1), (4,2), (4,3), (4,4), (4,5), (4,6); +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK EXPLAIN SELECT max(b), a FROM t1 GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range NULL a 5 NULL 8 Using index for group-by +1 SIMPLE t1 range NULL a 5 NULL 4 Using index for group-by FLUSH STATUS; SELECT max(b), a FROM t1 GROUP BY a; max(b) a @@ -2381,7 +2395,7 @@ Handler_read_next 0 Handler_read_retry 0 EXPLAIN SELECT max(b), a FROM t1 GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range NULL a 5 NULL 8 Using index for group-by +1 SIMPLE t1 range NULL a 5 NULL 4 Using index for group-by FLUSH STATUS; CREATE TABLE t2 SELECT max(b), a FROM t1 GROUP BY a; SHOW STATUS LIKE 'handler_read__e%'; @@ -2417,14 +2431,14 @@ Handler_read_retry 0 EXPLAIN (SELECT max(b), a FROM t1 GROUP BY a) UNION (SELECT max(b), a FROM t1 GROUP BY a); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 range NULL a 5 NULL 8 Using index for group-by -2 UNION t1 range NULL a 5 NULL 8 Using index for group-by +1 PRIMARY t1 range NULL a 5 NULL 4 Using index for group-by +2 UNION t1 range NULL a 5 NULL 4 Using index for group-by NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL EXPLAIN SELECT (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2) x FROM t1 AS t1_outer; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1_outer index NULL a 10 NULL 15 Using index -2 SUBQUERY t1 range NULL a 5 NULL 8 Using index for group-by +2 SUBQUERY t1 range NULL a 5 NULL 4 Using index for group-by EXPLAIN SELECT 1 FROM t1 AS t1_outer WHERE EXISTS (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2); id select_type table type possible_keys key key_len ref rows Extra @@ -2434,31 +2448,31 @@ EXPLAIN SELECT 1 FROM t1 AS t1_outer WHERE (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2) > 12; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE -2 SUBQUERY t1 range NULL a 5 NULL 8 Using index for group-by +2 SUBQUERY t1 range NULL a 5 NULL 4 Using index for group-by EXPLAIN SELECT 1 FROM t1 AS t1_outer WHERE a IN (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 8 -1 PRIMARY t1_outer ref a a 5 <subquery2>.max(b) 2 Using index -2 MATERIALIZED t1 range NULL a 5 NULL 8 Using index for group-by +1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 4 +1 PRIMARY t1_outer ref a a 5 <subquery2>.max(b) 4 Using index +2 MATERIALIZED t1 range NULL a 5 NULL 4 Using index for group-by EXPLAIN SELECT 1 FROM t1 AS t1_outer GROUP BY a HAVING a > (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1_outer range NULL a 5 NULL 8 Using index for group-by -2 SUBQUERY t1 range NULL a 5 NULL 8 Using index for group-by +1 PRIMARY t1_outer range NULL a 5 NULL 4 Using index for group-by +2 SUBQUERY t1 range NULL a 5 NULL 4 Using index for group-by EXPLAIN SELECT 1 FROM t1 AS t1_outer1 JOIN t1 AS t1_outer2 ON t1_outer1.a = (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2) AND t1_outer1.b = t1_outer2.b; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1_outer1 ref a a 5 const 1 Using where; Using index 1 PRIMARY t1_outer2 index NULL a 10 NULL 15 Using where; Using index; Using join buffer (flat, BNL join) -2 SUBQUERY t1 range NULL a 5 NULL 8 Using index for group-by +2 SUBQUERY t1 range NULL a 5 NULL 4 Using index for group-by EXPLAIN SELECT (SELECT (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2) x FROM t1 AS t1_outer) x2 FROM t1 AS t1_outer2; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1_outer2 index NULL a 10 NULL 15 Using index 2 SUBQUERY t1_outer index NULL a 10 NULL 15 Using index -3 SUBQUERY t1 range NULL a 5 NULL 8 Using index for group-by +3 SUBQUERY t1 range NULL a 5 NULL 4 Using index for group-by CREATE TABLE t3 LIKE t1; FLUSH STATUS; INSERT INTO t3 SELECT a,MAX(b) FROM t1 GROUP BY a; @@ -2497,9 +2511,12 @@ CREATE TABLE t1 (a int, INDEX idx(a)); INSERT INTO t1 VALUES (4), (2), (1), (2), (4), (2), (1), (4), (4), (2), (1), (2), (2), (4), (1), (4); +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK EXPLAIN SELECT DISTINCT(a) FROM t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range NULL idx 5 NULL 9 Using index for group-by +1 SIMPLE t1 range NULL idx 5 NULL 4 Using index for group-by SELECT DISTINCT(a) FROM t1; a 1 @@ -2507,7 +2524,7 @@ a 4 EXPLAIN SELECT SQL_BIG_RESULT DISTINCT(a) FROM t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range NULL idx 5 NULL 9 Using index for group-by +1 SIMPLE t1 range NULL idx 5 NULL 4 Using index for group-by SELECT SQL_BIG_RESULT DISTINCT(a) FROM t1; a 1 @@ -2515,19 +2532,22 @@ a 4 DROP TABLE t1; CREATE TABLE t1 (a INT, b INT); -INSERT INTO t1 (a, b) VALUES (1,1), (1,2), (1,3); +INSERT INTO t1 (a, b) VALUES (1,1), (1,2), (1,3), (1,4), (1,5); INSERT INTO t1 SELECT a + 1, b FROM t1; INSERT INTO t1 SELECT a + 2, b FROM t1; +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK EXPLAIN SELECT a, MIN(b), MAX(b) FROM t1 GROUP BY a ORDER BY a DESC; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 12 Using temporary; Using filesort +1 SIMPLE t1 ALL NULL NULL NULL NULL 20 Using temporary; Using filesort SELECT a, MIN(b), MAX(b) FROM t1 GROUP BY a ORDER BY a DESC; a MIN(b) MAX(b) -4 1 3 -3 1 3 -2 1 3 -1 1 3 +4 1 5 +3 1 5 +2 1 5 +1 1 5 CREATE INDEX break_it ON t1 (a, b); EXPLAIN SELECT a, MIN(b), MAX(b) FROM t1 GROUP BY a ORDER BY a; @@ -2535,30 +2555,30 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range NULL break_it 10 NULL 7 Using index for group-by SELECT a, MIN(b), MAX(b) FROM t1 GROUP BY a ORDER BY a; a MIN(b) MAX(b) -1 1 3 -2 1 3 -3 1 3 -4 1 3 +1 1 5 +2 1 5 +3 1 5 +4 1 5 EXPLAIN SELECT a, MIN(b), MAX(b) FROM t1 GROUP BY a ORDER BY a DESC; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range NULL break_it 10 NULL 7 Using index for group-by; Using temporary; Using filesort SELECT a, MIN(b), MAX(b) FROM t1 GROUP BY a ORDER BY a DESC; a MIN(b) MAX(b) -4 1 3 -3 1 3 -2 1 3 -1 1 3 +4 1 5 +3 1 5 +2 1 5 +1 1 5 EXPLAIN SELECT a, MIN(b), MAX(b), AVG(b) FROM t1 GROUP BY a ORDER BY a DESC; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL break_it 10 NULL 12 Using index +1 SIMPLE t1 index NULL break_it 10 NULL 20 Using index SELECT a, MIN(b), MAX(b), AVG(b) FROM t1 GROUP BY a ORDER BY a DESC; a MIN(b) MAX(b) AVG(b) -4 1 3 2.0000 -3 1 3 2.0000 -2 1 3 2.0000 -1 1 3 2.0000 +4 1 5 3.0000 +3 1 5 3.0000 +2 1 5 3.0000 +1 1 5 3.0000 DROP TABLE t1; create table t1 (a int, b int, key (a,b), key `index` (a,b)) engine=MyISAM; Warnings: @@ -2644,9 +2664,12 @@ INSERT INTO t1 VALUES (1, 1, 1, 1), (1, 1, 1, 2), (1, 1, 1, 3), (1, 1, 1, 4); INSERT INTO t1 SELECT * FROM t1; INSERT INTO t1 SELECT * FROM t1; INSERT INTO t1 SELECT a,b,c+1,d FROM t1; +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK EXPLAIN SELECT DISTINCT c FROM t1 WHERE d=4; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range NULL foo 10 NULL 9 Using where; Using index for group-by +1 SIMPLE t1 range NULL foo 10 NULL 3 Using where; Using index for group-by SELECT DISTINCT c FROM t1 WHERE d=4; c 1 @@ -2660,12 +2683,15 @@ CREATE TABLE t (a INT, b INT, INDEX (a,b)); INSERT INTO t VALUES (2,0), (2,0), (2,1), (2,1); INSERT INTO t SELECT * FROM t; INSERT INTO t SELECT * FROM t; +ANALYZE TABLE t; +Table Op Msg_type Msg_text +test.t analyze status OK # test MIN #should use range with index for group by EXPLAIN SELECT a, MIN(b) FROM t WHERE b <> 0 GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t range NULL a 10 NULL 9 Using where; Using index for group-by +1 SIMPLE t range NULL a 10 NULL 2 Using where; Using index for group-by #should return 1 row SELECT a, MIN(b) FROM t WHERE b <> 0 GROUP BY a; a MIN(b) @@ -2675,7 +2701,7 @@ a MIN(b) EXPLAIN SELECT a, MAX(b) FROM t WHERE b <> 1 GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t range NULL a 10 NULL 9 Using where; Using index for group-by +1 SIMPLE t range NULL a 10 NULL 2 Using where; Using index for group-by #should return 1 row SELECT a, MAX(b) FROM t WHERE b <> 1 GROUP BY a; a MAX(b) @@ -2686,7 +2712,7 @@ INSERT INTO t SELECT a, 2 FROM t; EXPLAIN SELECT a, MAX(b) FROM t WHERE b > 0 AND b < 2 GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t range NULL a 10 NULL 9 Using where; Using index for group-by +1 SIMPLE t range NULL a 10 NULL 3 Using where; Using index for group-by #should return 1 row SELECT a, MAX(b) FROM t WHERE b > 0 AND b < 2 GROUP BY a; a MAX(b) @@ -3295,10 +3321,14 @@ INSERT INTO t1 VALUES (0,99),(9,99),(4,0),(7,0),(99,0),(7,0),(8,0),(99,0),(1,0); INSERT INTO t1 VALUES (0,99),(9,99),(4,0),(7,0),(99,0),(7,0),(8,0),(99,0),(1,0); CREATE TABLE t2 (c int) ; INSERT INTO t2 VALUES (0),(1); +ANALYZE TABLE t1,t2; +Table Op Msg_type Msg_text +test.t1 analyze status OK +test.t2 analyze status OK EXPLAIN SELECT MIN(a), b FROM t1 WHERE a > 0 GROUP BY b; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range NULL b 10 NULL 10 Using where; Using index for group-by +1 SIMPLE t1 range NULL b 10 NULL 3 Using where; Using index for group-by SELECT MIN(a), b FROM t1 WHERE a > 0 GROUP BY b; MIN(a) b 1 0 @@ -3306,7 +3336,7 @@ MIN(a) b EXPLAIN SELECT MIN(a), b FROM t1 WHERE a > ( SELECT c FROM t2 WHERE c = 0 ) GROUP BY b; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 range NULL b 10 NULL 10 Using where; Using index for group-by +1 PRIMARY t1 range NULL b 10 NULL 3 Using where; Using index for group-by 2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where SELECT MIN(a), b FROM t1 WHERE a > ( SELECT c FROM t2 WHERE c = 0 ) GROUP BY b; MIN(a) b @@ -3330,54 +3360,66 @@ End of 5.3 tests # CREATE TABLE t1 (a INT, b INT, c INT, KEY (a,b)); INSERT INTO t1 VALUES (1,1,1), (1,2,1), (1,3,1), (1,4,1); +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; INSERT INTO t1 SELECT a, b + 4, 1 FROM t1; +INSERT INTO t1 SELECT a, b + 8, 1 FROM t1; INSERT INTO t1 SELECT a + 1, b, 1 FROM t1; CREATE TABLE t2 (a INT, b INT, c INT, d INT, e INT, f INT, KEY (a,b,c)); -INSERT INTO t2 VALUES (1,1,1,1,1,1), (1,2,1,1,1,1), (1,3,1,1,1,1), -(1,4,1,1,1,1); +INSERT INTO t2 VALUES +(1,1,1,1,1,1), (1,2,1,1,1,1), (1,3,1,1,1,1), (1,4,1,1,1,1); +INSERT INTO t2 SELECT * FROM t2; +INSERT INTO t2 SELECT * FROM t2; +INSERT INTO t2 SELECT * FROM t2; +INSERT INTO t2 SELECT * FROM t2; INSERT INTO t2 SELECT a, b + 4, c,d,e,f FROM t2; INSERT INTO t2 SELECT a + 1, b, c,d,e,f FROM t2; +ANALYZE TABLE t1,t2; +Table Op Msg_type Msg_text +test.t1 analyze status OK +test.t2 analyze status OK EXPLAIN SELECT COUNT(DISTINCT a) FROM t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range NULL a 5 NULL 9 Using index for group-by +1 SIMPLE t1 range NULL a 5 NULL 3 Using index for group-by SELECT COUNT(DISTINCT a) FROM t1; COUNT(DISTINCT a) 2 EXPLAIN SELECT COUNT(DISTINCT a,b) FROM t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range NULL a 10 NULL 9 Using index for group-by +1 SIMPLE t1 range NULL a 10 NULL 33 Using index for group-by SELECT COUNT(DISTINCT a,b) FROM t1; COUNT(DISTINCT a,b) -16 +32 EXPLAIN SELECT COUNT(DISTINCT b,a) FROM t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range NULL a 10 NULL 9 Using index for group-by +1 SIMPLE t1 range NULL a 10 NULL 33 Using index for group-by SELECT COUNT(DISTINCT b,a) FROM t1; COUNT(DISTINCT b,a) -16 +32 EXPLAIN SELECT COUNT(DISTINCT b) FROM t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL a 10 NULL 16 Using index +1 SIMPLE t1 index NULL a 10 NULL 256 Using index SELECT COUNT(DISTINCT b) FROM t1; COUNT(DISTINCT b) -8 +16 EXPLAIN SELECT COUNT(DISTINCT a) FROM t1 GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range NULL a 5 NULL 9 Using index for group-by +1 SIMPLE t1 range NULL a 5 NULL 3 Using index for group-by SELECT COUNT(DISTINCT a) FROM t1 GROUP BY a; COUNT(DISTINCT a) 1 1 EXPLAIN SELECT COUNT(DISTINCT b) FROM t1 GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range NULL a 10 NULL 9 Using index for group-by +1 SIMPLE t1 range NULL a 10 NULL 33 Using index for group-by SELECT COUNT(DISTINCT b) FROM t1 GROUP BY a; COUNT(DISTINCT b) -8 -8 +16 +16 EXPLAIN SELECT COUNT(DISTINCT a) FROM t1 GROUP BY b; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL a 10 NULL 16 Using index; Using filesort +1 SIMPLE t1 index NULL a 10 NULL 256 Using index; Using filesort SELECT COUNT(DISTINCT a) FROM t1 GROUP BY b; COUNT(DISTINCT a) 2 @@ -3388,96 +3430,103 @@ COUNT(DISTINCT a) 2 2 2 +2 +2 +2 +2 +2 +2 +2 +2 EXPLAIN SELECT DISTINCT COUNT(DISTINCT a) FROM t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL a 10 NULL 16 Using index +1 SIMPLE t1 index NULL a 10 NULL 256 Using index SELECT DISTINCT COUNT(DISTINCT a) FROM t1; COUNT(DISTINCT a) 2 EXPLAIN SELECT COUNT(DISTINCT a, b + 0) FROM t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL a 10 NULL 16 Using index +1 SIMPLE t1 index NULL a 10 NULL 256 Using index SELECT COUNT(DISTINCT a, b + 0) FROM t1; COUNT(DISTINCT a, b + 0) -16 +32 EXPLAIN SELECT COUNT(DISTINCT a) FROM t1 HAVING COUNT(DISTINCT b) < 10; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL a 10 NULL 16 Using index +1 SIMPLE t1 index NULL a 10 NULL 256 Using index SELECT COUNT(DISTINCT a) FROM t1 HAVING COUNT(DISTINCT b) < 10; COUNT(DISTINCT a) -2 EXPLAIN SELECT COUNT(DISTINCT a) FROM t1 HAVING COUNT(DISTINCT c) < 10; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 16 +1 SIMPLE t1 ALL NULL NULL NULL NULL 256 SELECT COUNT(DISTINCT a) FROM t1 HAVING COUNT(DISTINCT c) < 10; COUNT(DISTINCT a) 2 EXPLAIN SELECT 1 FROM t1 HAVING COUNT(DISTINCT a) < 10; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range NULL a 5 NULL 9 Using index for group-by +1 SIMPLE t1 range NULL a 5 NULL 3 Using index for group-by SELECT 1 FROM t1 HAVING COUNT(DISTINCT a) < 10; 1 1 EXPLAIN SELECT 1 FROM t1 GROUP BY a HAVING COUNT(DISTINCT b) > 1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range NULL a 10 NULL 9 Using index for group-by +1 SIMPLE t1 range NULL a 10 NULL 33 Using index for group-by SELECT 1 FROM t1 GROUP BY a HAVING COUNT(DISTINCT b) > 1; 1 1 1 EXPLAIN SELECT COUNT(DISTINCT t1_1.a) FROM t1 t1_1, t1 t1_2 GROUP BY t1_1.a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1_1 index NULL a 10 NULL 16 Using index; Using temporary; Using filesort -1 SIMPLE t1_2 index NULL a 10 NULL 16 Using index; Using join buffer (flat, BNL join) +1 SIMPLE t1_1 index NULL a 10 NULL 256 Using index; Using temporary; Using filesort +1 SIMPLE t1_2 index NULL a 10 NULL 256 Using index; Using join buffer (flat, BNL join) SELECT COUNT(DISTINCT t1_1.a) FROM t1 t1_1, t1 t1_2 GROUP BY t1_1.a; COUNT(DISTINCT t1_1.a) 1 1 EXPLAIN SELECT COUNT(DISTINCT a), 12 FROM t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range NULL a 5 NULL 9 Using index for group-by +1 SIMPLE t1 range NULL a 5 NULL 3 Using index for group-by SELECT COUNT(DISTINCT a), 12 FROM t1; COUNT(DISTINCT a) 12 2 12 EXPLAIN SELECT COUNT(DISTINCT a, b, c) FROM t2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range NULL a 15 NULL 9 Using index for group-by +1 SIMPLE t2 range NULL a 15 NULL 17 Using index for group-by SELECT COUNT(DISTINCT a, b, c) FROM t2; COUNT(DISTINCT a, b, c) 16 EXPLAIN SELECT COUNT(DISTINCT a), SUM(DISTINCT a), AVG(DISTINCT a) FROM t2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range NULL a 5 NULL 9 Using index for group-by +1 SIMPLE t2 range NULL a 5 NULL 3 Using index for group-by SELECT COUNT(DISTINCT a), SUM(DISTINCT a), AVG(DISTINCT a) FROM t2; COUNT(DISTINCT a) SUM(DISTINCT a) AVG(DISTINCT a) 2 3 1.5000 EXPLAIN SELECT COUNT(DISTINCT a), SUM(DISTINCT a), AVG(DISTINCT f) FROM t2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ALL NULL NULL NULL NULL 16 +1 SIMPLE t2 ALL NULL NULL NULL NULL 256 SELECT COUNT(DISTINCT a), SUM(DISTINCT a), AVG(DISTINCT f) FROM t2; COUNT(DISTINCT a) SUM(DISTINCT a) AVG(DISTINCT f) 2 3 1.0000 EXPLAIN SELECT COUNT(DISTINCT a, b), COUNT(DISTINCT b, a) FROM t2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range NULL a 10 NULL 9 Using index for group-by +1 SIMPLE t2 range NULL a 10 NULL 17 Using index for group-by SELECT COUNT(DISTINCT a, b), COUNT(DISTINCT b, a) FROM t2; COUNT(DISTINCT a, b) COUNT(DISTINCT b, a) 16 16 EXPLAIN SELECT COUNT(DISTINCT a, b), COUNT(DISTINCT b, f) FROM t2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ALL NULL NULL NULL NULL 16 +1 SIMPLE t2 ALL NULL NULL NULL NULL 256 SELECT COUNT(DISTINCT a, b), COUNT(DISTINCT b, f) FROM t2; COUNT(DISTINCT a, b) COUNT(DISTINCT b, f) 16 8 EXPLAIN SELECT COUNT(DISTINCT a, b), COUNT(DISTINCT b, d) FROM t2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ALL NULL NULL NULL NULL 16 +1 SIMPLE t2 ALL NULL NULL NULL NULL 256 SELECT COUNT(DISTINCT a, b), COUNT(DISTINCT b, d) FROM t2; COUNT(DISTINCT a, b) COUNT(DISTINCT b, d) 16 8 EXPLAIN SELECT a, c, COUNT(DISTINCT c, a, b) FROM t2 GROUP BY a, b, c; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range NULL a 15 NULL 9 Using index for group-by +1 SIMPLE t2 range NULL a 15 NULL 17 Using index for group-by SELECT a, c, COUNT(DISTINCT c, a, b) FROM t2 GROUP BY a, b, c; a c COUNT(DISTINCT c, a, b) 1 1 1 @@ -3499,7 +3548,7 @@ a c COUNT(DISTINCT c, a, b) EXPLAIN SELECT COUNT(DISTINCT c, a, b) FROM t2 WHERE a > 5 AND b BETWEEN 10 AND 20 GROUP BY a, b, c; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range a a 15 NULL 1 Using where; Using index for group-by +1 SIMPLE t2 range a a 5 NULL 1 Using where; Using index SELECT COUNT(DISTINCT c, a, b) FROM t2 WHERE a > 5 AND b BETWEEN 10 AND 20 GROUP BY a, b, c; COUNT(DISTINCT c, a, b) @@ -3512,47 +3561,47 @@ GROUP BY b; COUNT(DISTINCT b) SUM(DISTINCT b) EXPLAIN SELECT a, COUNT(DISTINCT b), SUM(DISTINCT b) FROM t2 GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range NULL a 10 NULL 9 Using index for group-by +1 SIMPLE t2 range NULL a 10 NULL 17 Using index for group-by SELECT a, COUNT(DISTINCT b), SUM(DISTINCT b) FROM t2 GROUP BY a; a COUNT(DISTINCT b) SUM(DISTINCT b) 1 8 36 2 8 36 EXPLAIN SELECT COUNT(DISTINCT b), SUM(DISTINCT b) FROM t2 GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range NULL a 10 NULL 9 Using index for group-by +1 SIMPLE t2 range NULL a 10 NULL 17 Using index for group-by SELECT COUNT(DISTINCT b), SUM(DISTINCT b) FROM t2 GROUP BY a; COUNT(DISTINCT b) SUM(DISTINCT b) 8 36 8 36 EXPLAIN SELECT COUNT(DISTINCT a, b) FROM t2 WHERE c = 13 AND d = 42; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ALL NULL NULL NULL NULL 16 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 256 Using where SELECT COUNT(DISTINCT a, b) FROM t2 WHERE c = 13 AND d = 42; COUNT(DISTINCT a, b) 0 EXPLAIN SELECT a, COUNT(DISTINCT a), SUM(DISTINCT a) FROM t2 WHERE b = 13 AND c = 42 GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range NULL a 15 NULL 9 Using where; Using index for group-by +1 SIMPLE t2 range NULL a 15 NULL 3 Using where; Using index for group-by SELECT a, COUNT(DISTINCT a), SUM(DISTINCT a) FROM t2 WHERE b = 13 AND c = 42 GROUP BY a; a COUNT(DISTINCT a) SUM(DISTINCT a) EXPLAIN SELECT COUNT(DISTINCT a, b), SUM(DISTINCT a) FROM t2 WHERE b = 42; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 index NULL a 15 NULL 16 Using where; Using index +1 SIMPLE t2 index NULL a 15 NULL 256 Using where; Using index SELECT COUNT(DISTINCT a, b), SUM(DISTINCT a) FROM t2 WHERE b = 42; COUNT(DISTINCT a, b) SUM(DISTINCT a) 0 NULL EXPLAIN SELECT SUM(DISTINCT a), MAX(b) FROM t2 GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 index NULL a 15 NULL 16 Using index +1 SIMPLE t2 index NULL a 15 NULL 256 Using index SELECT SUM(DISTINCT a), MAX(b) FROM t2 GROUP BY a; SUM(DISTINCT a) MAX(b) 1 8 2 8 EXPLAIN SELECT 42 * (a + c + COUNT(DISTINCT c, a, b)) FROM t2 GROUP BY a, b, c; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range NULL a 15 NULL 9 Using index for group-by +1 SIMPLE t2 range NULL a 15 NULL 17 Using index for group-by SELECT 42 * (a + c + COUNT(DISTINCT c, a, b)) FROM t2 GROUP BY a, b, c; 42 * (a + c + COUNT(DISTINCT c, a, b)) 126 @@ -3573,7 +3622,7 @@ SELECT 42 * (a + c + COUNT(DISTINCT c, a, b)) FROM t2 GROUP BY a, b, c; 168 EXPLAIN SELECT (SUM(DISTINCT a) + MAX(b)) FROM t2 GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 index NULL a 15 NULL 16 Using index +1 SIMPLE t2 index NULL a 15 NULL 256 Using index SELECT (SUM(DISTINCT a) + MAX(b)) FROM t2 GROUP BY a; (SUM(DISTINCT a) + MAX(b)) 9 @@ -3682,8 +3731,12 @@ b c drop table faulty; CREATE TABLE t1 (a INT, b INT); INSERT INTO t1 (a, b) VALUES (1,1), (1,2), (1,3); +INSERT INTO t1 SELECT * FROM t1; INSERT INTO t1 SELECT a + 1, b FROM t1; INSERT INTO t1 SELECT a + 2, b FROM t1; +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK CREATE INDEX break_it ON t1 (a, b); EXPLAIN SELECT distinct a, b FROM t1 where a = '3' ORDER BY b; @@ -3739,24 +3792,28 @@ DROP TABLE t1; CREATE TABLE t1 (a INT, b INT,c INT DEFAULT 0, INDEX (a,b)); INSERT INTO t1 (a, b) VALUES (1,1), (1,2), (1,3), (1,4), (1,5), (2,2), (2,3), (2,1), (3,1), (4,1), (4,2), (4,3), (4,4), (4,5), (4,6); +INSERT INTO t1 SELECT * FROM t1; +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK set @save_optimizer_use_condition_selectivity= @@optimizer_use_condition_selectivity; set @save_use_stat_tables= @@use_stat_tables; set @@optimizer_use_condition_selectivity=4; set @@use_stat_tables=PREFERABLY; explain extended SELECT a FROM t1 AS t1_outer WHERE a IN (SELECT max(b) FROM t1 GROUP BY a); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 8 100.00 -1 PRIMARY t1_outer ref a a 5 <subquery2>.max(b) 2 100.00 Using index -2 MATERIALIZED t1 range NULL a 5 NULL 8 100.00 Using index for group-by +1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 4 100.00 +1 PRIMARY t1_outer ref a a 5 <subquery2>.max(b) 8 100.00 Using index +2 MATERIALIZED t1 range NULL a 5 NULL 4 100.00 Using index for group-by Warnings: Note 1003 /* select#1 */ select `test`.`t1_outer`.`a` AS `a` from <materialize> (/* select#2 */ select max(`test`.`t1`.`b`) from `test`.`t1` group by `test`.`t1`.`a`) join `test`.`t1` `t1_outer` where `test`.`t1_outer`.`a` = `<subquery2>`.`max(b)` set @@optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; set @@use_stat_tables=@save_use_stat_tables; explain extended SELECT a FROM t1 AS t1_outer WHERE a IN (SELECT max(b) FROM t1 GROUP BY a); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 8 100.00 -1 PRIMARY t1_outer ref a a 5 <subquery2>.max(b) 2 100.00 Using index -2 MATERIALIZED t1 range NULL a 5 NULL 8 100.00 Using index for group-by +1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 4 100.00 +1 PRIMARY t1_outer ref a a 5 <subquery2>.max(b) 8 100.00 Using index +2 MATERIALIZED t1 range NULL a 5 NULL 4 100.00 Using index for group-by Warnings: Note 1003 /* select#1 */ select `test`.`t1_outer`.`a` AS `a` from <materialize> (/* select#2 */ select max(`test`.`t1`.`b`) from `test`.`t1` group by `test`.`t1`.`a`) join `test`.`t1` `t1_outer` where `test`.`t1_outer`.`a` = `<subquery2>`.`max(b)` drop table t1; @@ -3786,15 +3843,18 @@ INSERT INTO t1 VALUES (4,'2001-01-01'); INSERT INTO t1 VALUES (4,'2001-01-02'); INSERT INTO t1 VALUES (4,'2001-01-03'); INSERT INTO t1 VALUES (4,'2001-01-04'); +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a>='2001-01-04' GROUP BY id; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range NULL id 8 NULL 9 Using where; Using index for group-by +1 SIMPLE t1 range NULL id 8 NULL 5 Using where; Using index for group-by EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a>=20010104.0 GROUP BY id; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range NULL id 8 NULL 9 Using where; Using index for group-by +1 SIMPLE t1 range NULL id 8 NULL 5 Using where; Using index for group-by EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a>=20010104e0 GROUP BY id; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range NULL id 8 NULL 9 Using where; Using index for group-by +1 SIMPLE t1 range NULL id 8 NULL 5 Using where; Using index for group-by SELECT id,MIN(a),MAX(a) FROM t1 WHERE a>='2001-01-04' GROUP BY id; id MIN(a) MAX(a) 1 2001-01-04 2001-01-04 @@ -3835,6 +3895,11 @@ INSERT INTO t1 VALUES (4,'2001-01-01'); INSERT INTO t1 VALUES (4,'2001-01-02'); INSERT INTO t1 VALUES (4,'2001-01-03'); INSERT INTO t1 VALUES (4,' 2001-01-04'); +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN ' 2001-01-04' AND '2001-01-05' GROUP BY id; id MIN(a) MAX(a) 1 2001-01-04 2001-01-03 @@ -3890,19 +3955,19 @@ id MIN(a) MAX(a) 4 2001-01-04 2001-01-04 EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN ' 2001-01-04' AND '2001-01-05' GROUP BY id; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range NULL id 27 NULL 9 Using where; Using index for group-by +1 SIMPLE t1 range NULL id 27 NULL 10 Using where; Using index for group-by EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN '2001-01-04' AND '2001-01-05' GROUP BY id; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range NULL id 27 NULL 9 Using where; Using index for group-by +1 SIMPLE t1 range NULL id 27 NULL 10 Using where; Using index for group-by EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN DATE'2001-01-04' AND DATE'2001-01-05' GROUP BY id; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL id 27 NULL 16 Using where; Using index +1 SIMPLE t1 index NULL id 27 NULL 64 Using where; Using index EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN DATE'2001-01-04' AND '2001-01-05' GROUP BY id; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL id 27 NULL 16 Using where; Using index +1 SIMPLE t1 index NULL id 27 NULL 64 Using where; Using index EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN '2001-01-04' AND DATE'2001-01-05' GROUP BY id; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL id 27 NULL 16 Using where; Using index +1 SIMPLE t1 index NULL id 27 NULL 64 Using where; Using index DROP TABLE t1; # # MIN() optimization didn't work correctly with BETWEEN when using too diff --git a/mysql-test/main/group_min_max.test b/mysql-test/main/group_min_max.test index e8245dd2898..b32a39b1988 100644 --- a/mysql-test/main/group_min_max.test +++ b/mysql-test/main/group_min_max.test @@ -835,6 +835,10 @@ INSERT INTO t1 (a) VALUES (''), ('CENTRAL'), ('EASTERN'), ('GREATER LONDON'), ('NORTH CENTRAL'), ('NORTH EAST'), ('NORTH WEST'), ('SCOTLAND'), ('SOUTH EAST'), ('SOUTH WEST'), ('WESTERN'); +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +ANALYZE TABLE t1; EXPLAIN SELECT DISTINCT a,a FROM t1 ORDER BY a; SELECT DISTINCT a,a FROM t1 ORDER BY a; @@ -893,7 +897,10 @@ DROP TABLE t1,t2,t3,t4,t5,t6; # Bug#22342: No results returned for query using max and group by # CREATE TABLE t1 (a int, b int, KEY (a,b), KEY b (b)); -INSERT INTO t1 VALUES (1,1),(1,2),(1,0),(1,3); +INSERT INTO t1 VALUES + (1,1),(1,2),(1,0),(1,3), + (1,-1),(1,-2),(1,-3),(1,-4); +ANALYZE TABLE t1; explain SELECT MAX(b), a FROM t1 WHERE b < 2 AND a = 1 GROUP BY a; SELECT MAX(b), a FROM t1 WHERE b < 2 AND a = 1 GROUP BY a; @@ -912,6 +919,7 @@ DROP TABLE t1,t2; CREATE TABLE t1 (a INT, b INT, INDEX (a,b)); INSERT INTO t1 (a, b) VALUES (1,1), (1,2), (1,3), (1,4), (1,5), (2,2), (2,3), (2,1), (3,1), (4,1), (4,2), (4,3), (4,4), (4,5), (4,6); +ANALYZE TABLE t1; EXPLAIN SELECT max(b), a FROM t1 GROUP BY a; FLUSH STATUS; SELECT max(b), a FROM t1 GROUP BY a; @@ -975,6 +983,7 @@ CREATE TABLE t1 (a int, INDEX idx(a)); INSERT INTO t1 VALUES (4), (2), (1), (2), (4), (2), (1), (4), (4), (2), (1), (2), (2), (4), (1), (4); +ANALYZE TABLE t1; EXPLAIN SELECT DISTINCT(a) FROM t1; SELECT DISTINCT(a) FROM t1; @@ -988,9 +997,10 @@ DROP TABLE t1; # CREATE TABLE t1 (a INT, b INT); -INSERT INTO t1 (a, b) VALUES (1,1), (1,2), (1,3); +INSERT INTO t1 (a, b) VALUES (1,1), (1,2), (1,3), (1,4), (1,5); INSERT INTO t1 SELECT a + 1, b FROM t1; INSERT INTO t1 SELECT a + 2, b FROM t1; +ANALYZE TABLE t1; EXPLAIN SELECT a, MIN(b), MAX(b) FROM t1 GROUP BY a ORDER BY a DESC; @@ -1044,6 +1054,7 @@ INSERT INTO t1 VALUES (1, 1, 1, 1), (1, 1, 1, 2), (1, 1, 1, 3), (1, 1, 1, 4); INSERT INTO t1 SELECT * FROM t1; INSERT INTO t1 SELECT * FROM t1; INSERT INTO t1 SELECT a,b,c+1,d FROM t1; +ANALYZE TABLE t1; #Should be non-empty EXPLAIN SELECT DISTINCT c FROM t1 WHERE d=4; @@ -1060,6 +1071,7 @@ CREATE TABLE t (a INT, b INT, INDEX (a,b)); INSERT INTO t VALUES (2,0), (2,0), (2,1), (2,1); INSERT INTO t SELECT * FROM t; INSERT INTO t SELECT * FROM t; +ANALYZE TABLE t; --echo # test MIN --echo #should use range with index for group by @@ -1262,6 +1274,7 @@ INSERT INTO t1 VALUES (0,99),(9,99),(4,0),(7,0),(99,0),(7,0),(8,0),(99,0),(1,0); INSERT INTO t1 VALUES (0,99),(9,99),(4,0),(7,0),(99,0),(7,0),(8,0),(99,0),(1,0); CREATE TABLE t2 (c int) ; INSERT INTO t2 VALUES (0),(1); +ANALYZE TABLE t1,t2; EXPLAIN SELECT MIN(a), b FROM t1 WHERE a > 0 GROUP BY b; @@ -1284,13 +1297,22 @@ drop table t1, t2; CREATE TABLE t1 (a INT, b INT, c INT, KEY (a,b)); INSERT INTO t1 VALUES (1,1,1), (1,2,1), (1,3,1), (1,4,1); +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; INSERT INTO t1 SELECT a, b + 4, 1 FROM t1; +INSERT INTO t1 SELECT a, b + 8, 1 FROM t1; INSERT INTO t1 SELECT a + 1, b, 1 FROM t1; CREATE TABLE t2 (a INT, b INT, c INT, d INT, e INT, f INT, KEY (a,b,c)); -INSERT INTO t2 VALUES (1,1,1,1,1,1), (1,2,1,1,1,1), (1,3,1,1,1,1), - (1,4,1,1,1,1); +INSERT INTO t2 VALUES + (1,1,1,1,1,1), (1,2,1,1,1,1), (1,3,1,1,1,1), (1,4,1,1,1,1); +INSERT INTO t2 SELECT * FROM t2; +INSERT INTO t2 SELECT * FROM t2; +INSERT INTO t2 SELECT * FROM t2; +INSERT INTO t2 SELECT * FROM t2; INSERT INTO t2 SELECT a, b + 4, c,d,e,f FROM t2; INSERT INTO t2 SELECT a + 1, b, c,d,e,f FROM t2; +ANALYZE TABLE t1,t2; EXPLAIN SELECT COUNT(DISTINCT a) FROM t1; SELECT COUNT(DISTINCT a) FROM t1; @@ -1479,8 +1501,10 @@ drop table faulty; CREATE TABLE t1 (a INT, b INT); INSERT INTO t1 (a, b) VALUES (1,1), (1,2), (1,3); +INSERT INTO t1 SELECT * FROM t1; INSERT INTO t1 SELECT a + 1, b FROM t1; INSERT INTO t1 SELECT a + 2, b FROM t1; +ANALYZE TABLE t1; CREATE INDEX break_it ON t1 (a, b); @@ -1527,6 +1551,8 @@ DROP TABLE t1; CREATE TABLE t1 (a INT, b INT,c INT DEFAULT 0, INDEX (a,b)); INSERT INTO t1 (a, b) VALUES (1,1), (1,2), (1,3), (1,4), (1,5), (2,2), (2,3), (2,1), (3,1), (4,1), (4,2), (4,3), (4,4), (4,5), (4,6); +INSERT INTO t1 SELECT * FROM t1; +ANALYZE TABLE t1; set @save_optimizer_use_condition_selectivity= @@optimizer_use_condition_selectivity; set @save_use_stat_tables= @@use_stat_tables; set @@optimizer_use_condition_selectivity=4; @@ -1566,6 +1592,7 @@ INSERT INTO t1 VALUES (4,'2001-01-01'); INSERT INTO t1 VALUES (4,'2001-01-02'); INSERT INTO t1 VALUES (4,'2001-01-03'); INSERT INTO t1 VALUES (4,'2001-01-04'); +ANALYZE TABLE t1; EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a>='2001-01-04' GROUP BY id; EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a>=20010104.0 GROUP BY id; EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a>=20010104e0 GROUP BY id; @@ -1595,6 +1622,9 @@ INSERT INTO t1 VALUES (4,'2001-01-01'); INSERT INTO t1 VALUES (4,'2001-01-02'); INSERT INTO t1 VALUES (4,'2001-01-03'); INSERT INTO t1 VALUES (4,' 2001-01-04'); +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +ANALYZE TABLE t1; SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN ' 2001-01-04' AND '2001-01-05' GROUP BY id; SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN '2001-01-04' AND '2001-01-05' GROUP BY id; SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN DATE'2001-01-04' AND DATE'2001-01-05' GROUP BY id; diff --git a/mysql-test/main/group_min_max_innodb.result b/mysql-test/main/group_min_max_innodb.result index 311032bc453..ed90c137b33 100644 --- a/mysql-test/main/group_min_max_innodb.result +++ b/mysql-test/main/group_min_max_innodb.result @@ -1,3 +1,8 @@ +set @innodb_stats_persistent_save= @@innodb_stats_persistent; +set @innodb_stats_persistent_sample_pages_save= +@@innodb_stats_persistent_sample_pages; +set global innodb_stats_persistent= 1; +set global innodb_stats_persistent_sample_pages=100; drop view if exists v1; drop table if exists t1,t4; create table t4 ( @@ -194,7 +199,7 @@ EXPLAIN SELECT c1, i1, max(i2) FROM t2 WHERE (c1 = 'C' OR ( c1 = 'F' AND i1 < 35)) AND ( i2 = 17 ) GROUP BY c1,i1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range k2 k2 5 NULL 60 Using where; Using index +1 SIMPLE t2 range k2 k2 9 NULL 60 Using where; Using index for group-by SELECT c1, i1, max(i2) FROM t2 WHERE (c1 = 'C' OR ( c1 = 'F' AND i1 < 35)) AND ( i2 = 17 ) GROUP BY c1,i1; @@ -205,7 +210,7 @@ EXPLAIN SELECT c1, i1, max(i2) FROM t2 WHERE (((c1 = 'C' AND i1 < 40) OR ( c1 = 'F' AND i1 < 35)) AND ( i2 = 17 )) GROUP BY c1,i1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range k2 k2 5 NULL 60 Using where; Using index +1 SIMPLE t2 range k2 k2 9 NULL 60 Using where; Using index for group-by SELECT c1, i1, max(i2) FROM t2 WHERE (((c1 = 'C' AND i1 < 40) OR ( c1 = 'F' AND i1 < 35)) AND ( i2 = 17 )) GROUP BY c1,i1; @@ -302,3 +307,6 @@ NULL bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb NULL aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa NULL aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa drop table t1,t2; +set global innodb_stats_persistent= @innodb_stats_persistent_save; +set global innodb_stats_persistent_sample_pages= +@innodb_stats_persistent_sample_pages_save; diff --git a/mysql-test/main/group_min_max_innodb.test b/mysql-test/main/group_min_max_innodb.test index 91e0bd3279f..87a6e320887 100644 --- a/mysql-test/main/group_min_max_innodb.test +++ b/mysql-test/main/group_min_max_innodb.test @@ -6,6 +6,13 @@ --source include/have_innodb.inc +set @innodb_stats_persistent_save= @@innodb_stats_persistent; +set @innodb_stats_persistent_sample_pages_save= + @@innodb_stats_persistent_sample_pages; + +set global innodb_stats_persistent= 1; +set global innodb_stats_persistent_sample_pages=100; + --disable_warnings drop view if exists v1; drop table if exists t1,t4; @@ -243,3 +250,8 @@ CREATE TABLE t2 (`voter_id` int(10) unsigned NOT NULL DEFAULT '0', insert into t2 values (1,repeat("a",1000)),(2,repeat("a",1000)),(3,repeat("b",1000)),(4,repeat("c",1000)),(4,repeat("b",1000)); SELECT GROUP_CONCAT(t1.language_id SEPARATOR ',') AS `translation_resources`, `d`.`serialized_c` FROM t2 AS `d` LEFT JOIN t1 ON `d`.`voter_id` = t1.`voter_id` GROUP BY `d`.`voter_id` ORDER BY 10-d.voter_id+RAND()*0; drop table t1,t2; + +set global innodb_stats_persistent= @innodb_stats_persistent_save; +set global innodb_stats_persistent_sample_pages= + @innodb_stats_persistent_sample_pages_save; + diff --git a/mysql-test/main/index_intersect.result b/mysql-test/main/index_intersect.result index 7a0633d4dc8..bb2478c8c46 100644 --- a/mysql-test/main/index_intersect.result +++ b/mysql-test/main/index_intersect.result @@ -38,6 +38,7 @@ SELECT COUNT(*) FROM CountryLanguage; COUNT(*) 984 CREATE INDEX Name ON City(Name); +SET SESSION optimizer_switch='rowid_filter=off'; SET SESSION optimizer_switch='index_merge_sort_intersection=on'; SELECT COUNT(*) FROM City; COUNT(*) @@ -357,6 +358,9 @@ COUNT(*) SELECT COUNT(*) FROM City WHERE Country LIKE 'B%'; COUNT(*) 339 +SELECT COUNT(*) FROM City WHERE Country LIKE 'J%'; +COUNT(*) +256 EXPLAIN SELECT * FROM City WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%'; @@ -364,7 +368,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City index_merge Population,Country,Name Name,Population 35,4 NULL # Using sort_intersect(Name,Population); Using where EXPLAIN SELECT * FROM City -WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%'; +WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'J%'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City index_merge Population,Country,Name Population,Country 4,3 NULL # Using sort_intersect(Population,Country); Using where EXPLAIN @@ -383,15 +387,13 @@ ID Name Country Population 1810 Montréal CAN 1016376 2259 Medellín COL 1861265 SELECT * FROM City USE INDEX () -WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%'; +WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'J%'; ID Name Country Population -217 Guarulhos BRA 1095874 -218 Goiânia BRA 1056330 +1541 Hiroshima JPN 1119117 SELECT * FROM City -WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%'; +WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'J%'; ID Name Country Population -217 Guarulhos BRA 1095874 -218 Goiânia BRA 1056330 +1541 Hiroshima JPN 1119117 SELECT * FROM City USE INDEX () WHERE Name BETWEEN 'G' AND 'K' AND Population > 500000 AND Country LIKE 'C%'; ID Name Country Population @@ -465,9 +467,9 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City range PRIMARY,Population,Country Population 4 NULL # Using index condition; Using where EXPLAIN SELECT * FROM City -WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; +WHERE ID BETWEEN 1 AND 500 AND Population > 700000 AND Country LIKE 'C%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge PRIMARY,Population,Country Country,Population 3,4 NULL # Using sort_intersect(Country,Population); Using where +1 SIMPLE City range PRIMARY,Population,Country Population 4 NULL # Using index condition; Using where EXPLAIN SELECT * FROM City WHERE ID BETWEEN 2001 AND 2500 AND Population > 300000 AND Country LIKE 'H%'; @@ -494,33 +496,11 @@ WHERE ID BETWEEN 501 AND 1000 AND Population > 700000 AND Country LIKE 'C%'; ID Name Country Population 554 Santiago de Chile CHL 4703954 SELECT * FROM City USE INDEX () -WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; +WHERE ID BETWEEN 1 AND 500 AND Population > 700000 AND Country LIKE 'C%'; ID Name Country Population -1 Kabul AFG 1780000 -126 Yerevan ARM 1248700 -130 Sydney AUS 3276207 -131 Melbourne AUS 2865329 -132 Brisbane AUS 1291117 -133 Perth AUS 1096829 -144 Baku AZE 1787800 -56 Luanda AGO 2022000 -69 Buenos Aires ARG 2982146 -70 La Matanza ARG 1266461 -71 Córdoba ARG 1157507 SELECT * FROM City -WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; +WHERE ID BETWEEN 1 AND 500 AND Population > 700000 AND Country LIKE 'C%'; ID Name Country Population -1 Kabul AFG 1780000 -126 Yerevan ARM 1248700 -130 Sydney AUS 3276207 -131 Melbourne AUS 2865329 -132 Brisbane AUS 1291117 -133 Perth AUS 1096829 -144 Baku AZE 1787800 -56 Luanda AGO 2022000 -69 Buenos Aires ARG 2982146 -70 La Matanza ARG 1266461 -71 Córdoba ARG 1157507 SELECT * FROM City USE INDEX () WHERE ID BETWEEN 2001 AND 2500 AND Population > 300000 AND Country LIKE 'H%'; ID Name Country Population @@ -726,7 +706,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City index_merge Population,Name Population,Name 4,35 NULL # Using sort_intersect(Population,Name); Using where EXPLAIN SELECT * FROM City -WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%'; +WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'J%'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City index_merge Population,Country,Name Population,Country 4,3 NULL # Using sort_intersect(Population,Country); Using where EXPLAIN @@ -736,9 +716,9 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City range Population,Country,Name Name 35 NULL # Using index condition; Using where EXPLAIN SELECT * FROM City -WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; +WHERE ID BETWEEN 1 AND 500 AND Population > 700000 AND Country LIKE 'C%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge PRIMARY,Population,Country Country,Population 3,4 NULL # Using sort_intersect(Country,Population); Using where +1 SIMPLE City range PRIMARY,Population,Country Population 4 NULL # Using index condition; Using where EXPLAIN SELECT * FROM City WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000 @@ -778,10 +758,9 @@ ID Name Country Population 766 Manila PHL 1581082 942 Medan IDN 1843919 SELECT * FROM City -WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'B%'; +WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'J%'; ID Name Country Population -217 Guarulhos BRA 1095874 -218 Goiânia BRA 1056330 +1541 Hiroshima JPN 1119117 SELECT * FROM City WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%'; ID Name Country Population @@ -794,19 +773,8 @@ ID Name Country Population 1937 Huainan CHN 700000 1950 Hegang CHN 520000 SELECT * FROM City -WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; +WHERE ID BETWEEN 1 AND 500 AND Population > 700000 AND Country LIKE 'C%'; ID Name Country Population -1 Kabul AFG 1780000 -56 Luanda AGO 2022000 -69 Buenos Aires ARG 2982146 -70 La Matanza ARG 1266461 -71 Córdoba ARG 1157507 -126 Yerevan ARM 1248700 -130 Sydney AUS 3276207 -131 Melbourne AUS 2865329 -132 Brisbane AUS 1291117 -133 Perth AUS 1096829 -144 Baku AZE 1787800 SELECT * FROM City WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000 AND Country BETWEEN 'S' AND 'Z'; @@ -888,12 +856,12 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City index_merge Population,CountryID,CountryName Population,CountryID 4,3 NULL # Using sort_intersect(Population,CountryID); Using where EXPLAIN SELECT * FROM City -WHERE Country='CHN' AND Population > 1500000; +WHERE Country='USA' AND Population > 1000000; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City index_merge Population,CountryID,CountryName Population,CountryID 4,3 NULL # Using sort_intersect(Population,CountryID); Using where EXPLAIN SELECT * FROM City -WHERE Country='CHN' AND Population > 1500000 AND Name LIKE 'C%'; +WHERE Country='USA' AND Population > 1500000 AND Name LIKE 'C%'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City index_merge Population,Name,CountryID,CountryName CountryName,Population 38,4 NULL # Using sort_intersect(CountryName,Population); Using where SELECT * FROM City USE INDEX () @@ -931,73 +899,37 @@ ID Name Country Population 2698 Maputo MOZ 1018938 2710 Rangoon (Yangon) MMR 3361700 SELECT * FROM City USE INDEX () -WHERE Country='CHN' AND Population > 1500000; +WHERE Country='USA' AND Population > 1000000; ID Name Country Population -1890 Shanghai CHN 9696300 -1891 Peking CHN 7472000 -1892 Chongqing CHN 6351600 -1893 Tianjin CHN 5286800 -1894 Wuhan CHN 4344600 -1895 Harbin CHN 4289800 -1896 Shenyang CHN 4265200 -1897 Kanton [Guangzhou] CHN 4256300 -1898 Chengdu CHN 3361500 -1899 Nanking [Nanjing] CHN 2870300 -1900 Changchun CHN 2812000 -1901 Xi´an CHN 2761400 -1902 Dalian CHN 2697000 -1903 Qingdao CHN 2596000 -1904 Jinan CHN 2278100 -1905 Hangzhou CHN 2190500 -1906 Zhengzhou CHN 2107200 -1907 Shijiazhuang CHN 2041500 -1908 Taiyuan CHN 1968400 -1909 Kunming CHN 1829500 -1910 Changsha CHN 1809800 -1911 Nanchang CHN 1691600 -1912 Fuzhou CHN 1593800 -1913 Lanzhou CHN 1565800 +3793 New York USA 8008278 +3794 Los Angeles USA 3694820 +3795 Chicago USA 2896016 +3796 Houston USA 1953631 +3797 Philadelphia USA 1517550 +3798 Phoenix USA 1321045 +3799 San Diego USA 1223400 +3800 Dallas USA 1188580 +3801 San Antonio USA 1144646 SELECT * FROM City -WHERE Country='CHN' AND Population > 1500000; +WHERE Country='USA' AND Population > 1000000; ID Name Country Population -1890 Shanghai CHN 9696300 -1891 Peking CHN 7472000 -1892 Chongqing CHN 6351600 -1893 Tianjin CHN 5286800 -1894 Wuhan CHN 4344600 -1895 Harbin CHN 4289800 -1896 Shenyang CHN 4265200 -1897 Kanton [Guangzhou] CHN 4256300 -1898 Chengdu CHN 3361500 -1899 Nanking [Nanjing] CHN 2870300 -1900 Changchun CHN 2812000 -1901 Xi´an CHN 2761400 -1902 Dalian CHN 2697000 -1903 Qingdao CHN 2596000 -1904 Jinan CHN 2278100 -1905 Hangzhou CHN 2190500 -1906 Zhengzhou CHN 2107200 -1907 Shijiazhuang CHN 2041500 -1908 Taiyuan CHN 1968400 -1909 Kunming CHN 1829500 -1910 Changsha CHN 1809800 -1911 Nanchang CHN 1691600 -1912 Fuzhou CHN 1593800 -1913 Lanzhou CHN 1565800 +3793 New York USA 8008278 +3794 Los Angeles USA 3694820 +3795 Chicago USA 2896016 +3796 Houston USA 1953631 +3797 Philadelphia USA 1517550 +3798 Phoenix USA 1321045 +3799 San Diego USA 1223400 +3800 Dallas USA 1188580 +3801 San Antonio USA 1144646 SELECT * FROM City USE INDEX () -WHERE Country='CHN' AND Population > 1500000 AND Name LIKE 'C%'; +WHERE Country='USA' AND Population > 1500000 AND Name LIKE 'C%'; ID Name Country Population -1892 Chongqing CHN 6351600 -1898 Chengdu CHN 3361500 -1900 Changchun CHN 2812000 -1910 Changsha CHN 1809800 +3795 Chicago USA 2896016 SELECT * FROM City -WHERE Country='CHN' AND Population > 1500000 AND Name LIKE 'C%'; +WHERE Country='USA' AND Population > 1500000 AND Name LIKE 'C%'; ID Name Country Population -1892 Chongqing CHN 6351600 -1898 Chengdu CHN 3361500 -1900 Changchun CHN 2812000 -1910 Changsha CHN 1809800 +3795 Chicago USA 2896016 EXPLAIN SELECT * FROM City, Country WHERE City.Name LIKE 'C%' AND City.Population > 1000000 AND @@ -1041,3 +973,4 @@ f1 f4 f5 998 a 0 DROP TABLE t1; SET SESSION optimizer_switch='index_merge_sort_intersection=on'; +SET SESSION optimizer_switch='rowid_filter=default'; diff --git a/mysql-test/main/index_intersect.test b/mysql-test/main/index_intersect.test index 1be963cb9e5..c77eccc6335 100644 --- a/mysql-test/main/index_intersect.test +++ b/mysql-test/main/index_intersect.test @@ -33,6 +33,7 @@ ANALYZE TABLE City; --enable_result_log --enable_query_log +SET SESSION optimizer_switch='rowid_filter=off'; SET SESSION optimizer_switch='index_merge_sort_intersection=on'; SELECT COUNT(*) FROM City; @@ -117,6 +118,7 @@ SELECT COUNT(*) FROM City WHERE Population > 1000000; SELECT COUNT(*) FROM City WHERE Population > 500000; SELECT COUNT(*) FROM City WHERE Country LIKE 'C%'; SELECT COUNT(*) FROM City WHERE Country LIKE 'B%'; +SELECT COUNT(*) FROM City WHERE Country LIKE 'J%'; # The pattern of the WHERE condition used in the following 3 queries is @@ -134,7 +136,7 @@ SELECT * FROM City --replace_column 9 # EXPLAIN SELECT * FROM City - WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%'; + WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'J%'; --replace_column 7 # 9 # --replace_result Population,Country,Name Population,Name,Country @@ -156,11 +158,11 @@ SELECT * FROM City SELECT * FROM City USE INDEX () - WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%'; + WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'J%'; --sorted_result SELECT * FROM City - WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%'; + WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'J%'; SELECT * FROM City USE INDEX () @@ -207,7 +209,7 @@ SELECT * FROM City --replace_column 9 # EXPLAIN SELECT * FROM City - WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; + WHERE ID BETWEEN 1 AND 500 AND Population > 700000 AND Country LIKE 'C%'; --replace_column 9 # EXPLAIN @@ -241,10 +243,10 @@ SELECT * FROM City --sorted_result SELECT * FROM City USE INDEX () - WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; + WHERE ID BETWEEN 1 AND 500 AND Population > 700000 AND Country LIKE 'C%'; --sorted_result SELECT * FROM City - WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; + WHERE ID BETWEEN 1 AND 500 AND Population > 700000 AND Country LIKE 'C%'; SELECT * FROM City USE INDEX () @@ -293,7 +295,7 @@ SELECT * FROM City WHERE --replace_column 9 # EXPLAIN SELECT * FROM City - WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%'; + WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'J%'; --replace_column 9 # EXPLAIN @@ -304,7 +306,7 @@ SELECT * FROM City --replace_column 9 # EXPLAIN SELECT * FROM City - WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; + WHERE ID BETWEEN 1 AND 500 AND Population > 700000 AND Country LIKE 'C%'; --replace_column 9 # --replace_result PRIMARY,Country,Population PRIMARY,Population,Country 4,7,4 4,4,7 @@ -326,7 +328,7 @@ SELECT * FROM City WHERE --sorted_result SELECT * FROM City - WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'B%'; + WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'J%'; --sorted_result SELECT * FROM City @@ -334,7 +336,7 @@ SELECT * FROM City SELECT * FROM City - WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; + WHERE ID BETWEEN 1 AND 500 AND Population > 700000 AND Country LIKE 'C%'; --sorted_result SELECT * FROM City WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000 @@ -371,12 +373,12 @@ SELECT * FROM City --replace_column 9 # EXPLAIN SELECT * FROM City - WHERE Country='CHN' AND Population > 1500000; + WHERE Country='USA' AND Population > 1000000; --replace_column 9 # EXPLAIN SELECT * FROM City - WHERE Country='CHN' AND Population > 1500000 AND Name LIKE 'C%'; + WHERE Country='USA' AND Population > 1500000 AND Name LIKE 'C%'; # Check that the previous 3 plans return the right results when executed @@ -390,18 +392,18 @@ SELECT * FROM City --sorted_result SELECT * FROM City USE INDEX () - WHERE Country='CHN' AND Population > 1500000; + WHERE Country='USA' AND Population > 1000000; --sorted_result SELECT * FROM City - WHERE Country='CHN' AND Population > 1500000; + WHERE Country='USA' AND Population > 1000000; SELECT * FROM City USE INDEX () - WHERE Country='CHN' AND Population > 1500000 AND Name LIKE 'C%'; + WHERE Country='USA' AND Population > 1500000 AND Name LIKE 'C%'; --sorted_result SELECT * FROM City - WHERE Country='CHN' AND Population > 1500000 AND Name LIKE 'C%'; + WHERE Country='USA' AND Population > 1500000 AND Name LIKE 'C%'; # @@ -459,3 +461,4 @@ WHERE (f1 < 535 OR f1 > 985) AND ( f4='r' OR f4 LIKE 'a%' ) ; DROP TABLE t1; SET SESSION optimizer_switch='index_merge_sort_intersection=on'; +SET SESSION optimizer_switch='rowid_filter=default'; diff --git a/mysql-test/main/index_intersect_innodb.result b/mysql-test/main/index_intersect_innodb.result index 15244098170..854bcd75e5c 100644 --- a/mysql-test/main/index_intersect_innodb.result +++ b/mysql-test/main/index_intersect_innodb.result @@ -1,4 +1,9 @@ SET SESSION STORAGE_ENGINE='InnoDB'; +set @innodb_stats_persistent_save= @@innodb_stats_persistent; +set @innodb_stats_persistent_sample_pages_save= +@@innodb_stats_persistent_sample_pages; +set global innodb_stats_persistent= 1; +set global innodb_stats_persistent_sample_pages=100; DROP TABLE IF EXISTS t1,t2,t3,t4; DROP DATABASE IF EXISTS world; set names utf8; @@ -39,6 +44,7 @@ SELECT COUNT(*) FROM CountryLanguage; COUNT(*) 984 CREATE INDEX Name ON City(Name); +SET SESSION optimizer_switch='rowid_filter=off'; SET SESSION optimizer_switch='index_merge_sort_intersection=on'; SELECT COUNT(*) FROM City; COUNT(*) @@ -80,7 +86,7 @@ EXPLAIN SELECT * FROM City WHERE Name LIKE 'M%' AND Population > 7000000; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge Population,Name Population,Name 4,35 NULL # Using sort_intersect(Population,Name); Using where +1 SIMPLE City range Population,Name Population 4 NULL # Using index condition; Using where SELECT * FROM City USE INDEX () WHERE Name LIKE 'C%' AND Population > 1000000; ID Name Country Population @@ -335,8 +341,8 @@ ID Name Country Population SELECT * FROM City WHERE Name LIKE 'M%' AND Population > 7000000; ID Name Country Population -1024 Mumbai (Bombay) IND 10500000 3580 Moscow RUS 8389200 +1024 Mumbai (Bombay) IND 10500000 SELECT COUNT(*) FROM City WHERE Name BETWEEN 'M' AND 'N'; COUNT(*) 301 @@ -358,16 +364,19 @@ COUNT(*) SELECT COUNT(*) FROM City WHERE Country LIKE 'B%'; COUNT(*) 339 +SELECT COUNT(*) FROM City WHERE Country LIKE 'J%'; +COUNT(*) +256 EXPLAIN SELECT * FROM City WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge Population,Country,Name Population,Name,Country 4,35,3 NULL # Using sort_intersect(Population,Name,Country); Using where +1 SIMPLE City index_merge Population,Country,Name Population,Name 4,35 NULL # Using sort_intersect(Population,Name); Using where EXPLAIN SELECT * FROM City -WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%'; +WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'J%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge Population,Country,Name Population,Country,Name 4,3,35 NULL # Using sort_intersect(Population,Country,Name); Using where +1 SIMPLE City index_merge Population,Country,Name Population,Country 4,3 NULL # Using sort_intersect(Population,Country); Using where EXPLAIN SELECT * FROM City WHERE Name BETWEEN 'G' AND 'K' AND Population > 500000 AND Country LIKE 'C%'; @@ -384,15 +393,13 @@ ID Name Country Population 1810 Montréal CAN 1016376 2259 Medellín COL 1861265 SELECT * FROM City USE INDEX () -WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%'; +WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'J%'; ID Name Country Population -217 Guarulhos BRA 1095874 -218 Goiânia BRA 1056330 +1541 Hiroshima JPN 1119117 SELECT * FROM City -WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%'; +WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'J%'; ID Name Country Population -217 Guarulhos BRA 1095874 -218 Goiânia BRA 1056330 +1541 Hiroshima JPN 1119117 SELECT * FROM City USE INDEX () WHERE Name BETWEEN 'G' AND 'K' AND Population > 500000 AND Country LIKE 'C%'; ID Name Country Population @@ -466,9 +473,9 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City index_merge PRIMARY,Population,Country PRIMARY,Country,Population 4,7,4 NULL # Using sort_intersect(PRIMARY,Country,Population); Using where EXPLAIN SELECT * FROM City -WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; +WHERE ID BETWEEN 1 AND 500 AND Population > 700000 AND Country LIKE 'C%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge PRIMARY,Population,Country PRIMARY,Population,Country 4,4,7 NULL # Using sort_intersect(PRIMARY,Population,Country); Using where +1 SIMPLE City index_merge PRIMARY,Population,Country PRIMARY,Country,Population 4,7,4 NULL # Using sort_intersect(PRIMARY,Country,Population); Using where EXPLAIN SELECT * FROM City WHERE ID BETWEEN 2001 AND 2500 AND Population > 300000 AND Country LIKE 'H%'; @@ -479,7 +486,7 @@ SELECT * FROM City WHERE ID BETWEEN 3701 AND 4000 AND Population > 1000000 AND Country BETWEEN 'S' AND 'Z'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge PRIMARY,Population,Country PRIMARY,Country,Population 4,7,4 NULL # Using sort_intersect(PRIMARY,Country,Population); Using where +1 SIMPLE City index_merge PRIMARY,Population,Country PRIMARY,Population 4,4 NULL # Using sort_intersect(PRIMARY,Population); Using where EXPLAIN SELECT * FROM City WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000 @@ -495,33 +502,11 @@ WHERE ID BETWEEN 501 AND 1000 AND Population > 700000 AND Country LIKE 'C%'; ID Name Country Population 554 Santiago de Chile CHL 4703954 SELECT * FROM City USE INDEX () -WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; +WHERE ID BETWEEN 1 AND 500 AND Population > 700000 AND Country LIKE 'C%'; ID Name Country Population -1 Kabul AFG 1780000 -126 Yerevan ARM 1248700 -130 Sydney AUS 3276207 -131 Melbourne AUS 2865329 -132 Brisbane AUS 1291117 -133 Perth AUS 1096829 -144 Baku AZE 1787800 -56 Luanda AGO 2022000 -69 Buenos Aires ARG 2982146 -70 La Matanza ARG 1266461 -71 Córdoba ARG 1157507 SELECT * FROM City -WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; +WHERE ID BETWEEN 1 AND 500 AND Population > 700000 AND Country LIKE 'C%'; ID Name Country Population -1 Kabul AFG 1780000 -126 Yerevan ARM 1248700 -130 Sydney AUS 3276207 -131 Melbourne AUS 2865329 -132 Brisbane AUS 1291117 -133 Perth AUS 1096829 -144 Baku AZE 1787800 -56 Luanda AGO 2022000 -69 Buenos Aires ARG 2982146 -70 La Matanza ARG 1266461 -71 Córdoba ARG 1157507 SELECT * FROM City USE INDEX () WHERE ID BETWEEN 2001 AND 2500 AND Population > 300000 AND Country LIKE 'H%'; ID Name Country Population @@ -727,19 +712,19 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City index_merge Population,Name Population,Name 4,35 NULL # Using sort_intersect(Population,Name); Using where EXPLAIN SELECT * FROM City -WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%'; +WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'J%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge Population,Country,Name Population,Country,Name 4,3,35 NULL # Using sort_intersect(Population,Country,Name); Using where +1 SIMPLE City index_merge Population,Country,Name Population,Country 4,3 NULL # Using sort_intersect(Population,Country); Using where EXPLAIN SELECT * FROM City WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge Population,Country,Name Name,Population,Country 35,4,3 NULL # Using sort_intersect(Name,Population,Country); Using where +1 SIMPLE City index_merge Population,Country,Name Name,Population 35,4 NULL # Using sort_intersect(Name,Population); Using where EXPLAIN SELECT * FROM City -WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; +WHERE ID BETWEEN 1 AND 500 AND Population > 700000 AND Country LIKE 'C%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge PRIMARY,Population,Country PRIMARY,Population,Country 4,4,7 NULL # Using sort_intersect(PRIMARY,Population,Country); Using where +1 SIMPLE City index_merge PRIMARY,Population,Country PRIMARY,Country,Population 4,7,4 NULL # Using sort_intersect(PRIMARY,Country,Population); Using where EXPLAIN SELECT * FROM City WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000 @@ -779,10 +764,9 @@ ID Name Country Population 766 Manila PHL 1581082 942 Medan IDN 1843919 SELECT * FROM City -WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'B%'; +WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'J%'; ID Name Country Population -217 Guarulhos BRA 1095874 -218 Goiânia BRA 1056330 +1541 Hiroshima JPN 1119117 SELECT * FROM City WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%'; ID Name Country Population @@ -795,19 +779,8 @@ ID Name Country Population 1937 Huainan CHN 700000 1950 Hegang CHN 520000 SELECT * FROM City -WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; +WHERE ID BETWEEN 1 AND 500 AND Population > 700000 AND Country LIKE 'C%'; ID Name Country Population -1 Kabul AFG 1780000 -56 Luanda AGO 2022000 -69 Buenos Aires ARG 2982146 -70 La Matanza ARG 1266461 -71 Córdoba ARG 1157507 -126 Yerevan ARM 1248700 -130 Sydney AUS 3276207 -131 Melbourne AUS 2865329 -132 Brisbane AUS 1291117 -133 Perth AUS 1096829 -144 Baku AZE 1787800 SELECT * FROM City WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000 AND Country BETWEEN 'S' AND 'Z'; @@ -889,12 +862,12 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City index_merge Population,CountryID,CountryName Population,CountryID 4,3 NULL # Using sort_intersect(Population,CountryID); Using where EXPLAIN SELECT * FROM City -WHERE Country='CHN' AND Population > 1500000; +WHERE Country='USA' AND Population > 1000000; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City index_merge Population,CountryID,CountryName Population,CountryID 4,3 NULL # Using sort_intersect(Population,CountryID); Using where EXPLAIN SELECT * FROM City -WHERE Country='CHN' AND Population > 1500000 AND Name LIKE 'C%'; +WHERE Country='USA' AND Population > 1500000 AND Name LIKE 'C%'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City index_merge Population,Name,CountryID,CountryName CountryName,Population 38,4 NULL # Using sort_intersect(CountryName,Population); Using where SELECT * FROM City USE INDEX () @@ -932,73 +905,37 @@ ID Name Country Population 2698 Maputo MOZ 1018938 2710 Rangoon (Yangon) MMR 3361700 SELECT * FROM City USE INDEX () -WHERE Country='CHN' AND Population > 1500000; +WHERE Country='USA' AND Population > 1000000; ID Name Country Population -1890 Shanghai CHN 9696300 -1891 Peking CHN 7472000 -1892 Chongqing CHN 6351600 -1893 Tianjin CHN 5286800 -1894 Wuhan CHN 4344600 -1895 Harbin CHN 4289800 -1896 Shenyang CHN 4265200 -1897 Kanton [Guangzhou] CHN 4256300 -1898 Chengdu CHN 3361500 -1899 Nanking [Nanjing] CHN 2870300 -1900 Changchun CHN 2812000 -1901 Xi´an CHN 2761400 -1902 Dalian CHN 2697000 -1903 Qingdao CHN 2596000 -1904 Jinan CHN 2278100 -1905 Hangzhou CHN 2190500 -1906 Zhengzhou CHN 2107200 -1907 Shijiazhuang CHN 2041500 -1908 Taiyuan CHN 1968400 -1909 Kunming CHN 1829500 -1910 Changsha CHN 1809800 -1911 Nanchang CHN 1691600 -1912 Fuzhou CHN 1593800 -1913 Lanzhou CHN 1565800 +3793 New York USA 8008278 +3794 Los Angeles USA 3694820 +3795 Chicago USA 2896016 +3796 Houston USA 1953631 +3797 Philadelphia USA 1517550 +3798 Phoenix USA 1321045 +3799 San Diego USA 1223400 +3800 Dallas USA 1188580 +3801 San Antonio USA 1144646 SELECT * FROM City -WHERE Country='CHN' AND Population > 1500000; +WHERE Country='USA' AND Population > 1000000; ID Name Country Population -1890 Shanghai CHN 9696300 -1891 Peking CHN 7472000 -1892 Chongqing CHN 6351600 -1893 Tianjin CHN 5286800 -1894 Wuhan CHN 4344600 -1895 Harbin CHN 4289800 -1896 Shenyang CHN 4265200 -1897 Kanton [Guangzhou] CHN 4256300 -1898 Chengdu CHN 3361500 -1899 Nanking [Nanjing] CHN 2870300 -1900 Changchun CHN 2812000 -1901 Xi´an CHN 2761400 -1902 Dalian CHN 2697000 -1903 Qingdao CHN 2596000 -1904 Jinan CHN 2278100 -1905 Hangzhou CHN 2190500 -1906 Zhengzhou CHN 2107200 -1907 Shijiazhuang CHN 2041500 -1908 Taiyuan CHN 1968400 -1909 Kunming CHN 1829500 -1910 Changsha CHN 1809800 -1911 Nanchang CHN 1691600 -1912 Fuzhou CHN 1593800 -1913 Lanzhou CHN 1565800 +3793 New York USA 8008278 +3794 Los Angeles USA 3694820 +3795 Chicago USA 2896016 +3796 Houston USA 1953631 +3797 Philadelphia USA 1517550 +3798 Phoenix USA 1321045 +3799 San Diego USA 1223400 +3800 Dallas USA 1188580 +3801 San Antonio USA 1144646 SELECT * FROM City USE INDEX () -WHERE Country='CHN' AND Population > 1500000 AND Name LIKE 'C%'; +WHERE Country='USA' AND Population > 1500000 AND Name LIKE 'C%'; ID Name Country Population -1892 Chongqing CHN 6351600 -1898 Chengdu CHN 3361500 -1900 Changchun CHN 2812000 -1910 Changsha CHN 1809800 +3795 Chicago USA 2896016 SELECT * FROM City -WHERE Country='CHN' AND Population > 1500000 AND Name LIKE 'C%'; +WHERE Country='USA' AND Population > 1500000 AND Name LIKE 'C%'; ID Name Country Population -1892 Chongqing CHN 6351600 -1898 Chengdu CHN 3361500 -1900 Changchun CHN 2812000 -1910 Changsha CHN 1809800 +3795 Chicago USA 2896016 EXPLAIN SELECT * FROM City, Country WHERE City.Name LIKE 'C%' AND City.Population > 1000000 AND @@ -1042,4 +979,8 @@ f1 f4 f5 998 a 0 DROP TABLE t1; SET SESSION optimizer_switch='index_merge_sort_intersection=on'; +SET SESSION optimizer_switch='rowid_filter=default'; +set global innodb_stats_persistent= @innodb_stats_persistent_save; +set global innodb_stats_persistent_sample_pages= +@innodb_stats_persistent_sample_pages_save; SET SESSION STORAGE_ENGINE=DEFAULT; diff --git a/mysql-test/main/index_intersect_innodb.test b/mysql-test/main/index_intersect_innodb.test index f2e44cb3947..637056ad795 100644 --- a/mysql-test/main/index_intersect_innodb.test +++ b/mysql-test/main/index_intersect_innodb.test @@ -2,6 +2,15 @@ SET SESSION STORAGE_ENGINE='InnoDB'; +set @innodb_stats_persistent_save= @@innodb_stats_persistent; +set @innodb_stats_persistent_sample_pages_save= + @@innodb_stats_persistent_sample_pages; + +set global innodb_stats_persistent= 1; +set global innodb_stats_persistent_sample_pages=100; --source index_intersect.test +set global innodb_stats_persistent= @innodb_stats_persistent_save; +set global innodb_stats_persistent_sample_pages= + @innodb_stats_persistent_sample_pages_save; SET SESSION STORAGE_ENGINE=DEFAULT; diff --git a/mysql-test/main/index_merge_innodb.result b/mysql-test/main/index_merge_innodb.result index 6a3ea839535..26b51ba444b 100644 --- a/mysql-test/main/index_merge_innodb.result +++ b/mysql-test/main/index_merge_innodb.result @@ -1,5 +1,6 @@ set @optimizer_switch_save= @@optimizer_switch; set optimizer_switch='index_merge_sort_intersection=off'; +set optimizer_switch='rowid_filter=off'; #---------------- Index merge test 2 ------------------------------------------- SET SESSION STORAGE_ENGINE = InnoDB; drop table if exists t1,t2; diff --git a/mysql-test/main/index_merge_innodb.test b/mysql-test/main/index_merge_innodb.test index 53ce3114b49..e8dc8378ffe 100644 --- a/mysql-test/main/index_merge_innodb.test +++ b/mysql-test/main/index_merge_innodb.test @@ -20,6 +20,7 @@ let $merge_table_support= 0; set @optimizer_switch_save= @@optimizer_switch; set optimizer_switch='index_merge_sort_intersection=off'; +set optimizer_switch='rowid_filter=off'; # The first two tests are disabled because of non deterministic explain output. # If include/index_merge1.inc can be enabled for InnoDB and all other diff --git a/mysql-test/main/index_merge_myisam.result b/mysql-test/main/index_merge_myisam.result index 725a888c914..8e83bdf6bbb 100644 --- a/mysql-test/main/index_merge_myisam.result +++ b/mysql-test/main/index_merge_myisam.result @@ -1,4 +1,5 @@ set @optimizer_switch_save= @@optimizer_switch; +set optimizer_switch='rowid_filter=off'; set optimizer_switch='index_merge_sort_intersection=off'; #---------------- Index merge test 1 ------------------------------------------- SET SESSION STORAGE_ENGINE = MyISAM; @@ -19,27 +20,26 @@ update t0 set key2=key1,key3=key1,key4=key1,key5=key1,key6=key1,key7=key1,key8=1 analyze table t0; Table Op Msg_type Msg_text test.t0 analyze status OK -explain select * from t0 where key1 < 3 or key1 > 1020; +explain select * from t0 where key1 < 3 or key1 > 920 and key1 < 924; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t0 range i1 i1 4 NULL 78 Using index condition; Using where +1 SIMPLE t0 range i1 i1 4 NULL 5 Using index condition; Using where explain -select * from t0 where key1 < 3 or key2 > 1020; +select * from t0 where key1 < 3 or key2 > 920 and key2 < 924; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t0 index_merge i1,i2 i1,i2 4,4 NULL 45 Using sort_union(i1,i2); Using where -select * from t0 where key1 < 3 or key2 > 1020; +1 SIMPLE t0 index_merge i1,i2 i1,i2 4,4 NULL 5 Using sort_union(i1,i2); Using where +select * from t0 where key1 < 3 or key2 > 920 and key2 < 924; key1 key2 key3 key4 key5 key6 key7 key8 1 1 1 1 1 1 1 1023 2 2 2 2 2 2 2 1022 -1021 1021 1021 1021 1021 1021 1021 3 -1022 1022 1022 1022 1022 1022 1022 2 -1023 1023 1023 1023 1023 1023 1023 1 -1024 1024 1024 1024 1024 1024 1024 0 +921 921 921 921 921 921 921 103 +922 922 922 922 922 922 922 102 +923 923 923 923 923 923 923 101 select * from t0 where key1=1022; key1 key2 key3 key4 key5 key6 key7 key8 1022 1022 1022 1022 1022 1022 1022 2 explain select * from t0 where key1 < 3 or key2 <4; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t0 index_merge i1,i2 i1,i2 4,4 NULL 7 Using sort_union(i1,i2); Using where +1 SIMPLE t0 index_merge i1,i2 i1,i2 4,4 NULL 5 Using sort_union(i1,i2); Using where explain select * from t0 where (key1 > 30 and key1<35) or (key2 >32 and key2 < 40); id select_type table type possible_keys key key_len ref rows Extra @@ -63,7 +63,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t0 ref i1,i2,i3 i3 4 const 1 Using where explain select * from t0 use index (i1,i2) where (key1 < 3 or key2 <4) and key3 = 50; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t0 index_merge i1,i2 i1,i2 4,4 NULL 7 Using sort_union(i1,i2); Using where +1 SIMPLE t0 index_merge i1,i2 i1,i2 4,4 NULL 5 Using sort_union(i1,i2); Using where explain select * from t0 where (key1 > 1 or key2 > 2); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t0 ALL i1,i2 NULL NULL NULL 1024 Using where @@ -74,7 +74,7 @@ explain select * from t0 where key1<3 or key2<3 or (key1>5 and key1<8) or (key1>10 and key1<12) or (key2>100 and key2<110); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t0 index_merge i1,i2 i1,i2 4,4 NULL 17 Using sort_union(i1,i2); Using where +1 SIMPLE t0 index_merge i1,i2 i1,i2 4,4 NULL 15 Using sort_union(i1,i2); Using where explain select * from t0 where key2 = 45 or key1 <=> null; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t0 range i1,i2 i2 4 NULL 1 Using index condition @@ -93,19 +93,19 @@ id select_type table type possible_keys key key_len ref rows Extra explain select key1 from t0 where (key1 <=> null) or (key2 < 5) or (key3=10) or (key4 <=> null); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t0 index_merge i1,i2,i3,i4 i2,i3 4,4 NULL 6 Using sort_union(i2,i3); Using where +1 SIMPLE t0 index_merge i1,i2,i3,i4 i2,i3 4,4 NULL 5 Using sort_union(i2,i3); Using where explain select key1 from t0 where (key1 <=> null) or (key1 < 5) or (key3=10) or (key4 <=> null); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t0 index_merge i1,i3,i4 i1,i3 4,4 NULL 6 Using sort_union(i1,i3); Using where +1 SIMPLE t0 index_merge i1,i3,i4 i1,i3 4,4 NULL 5 Using sort_union(i1,i3); Using where explain select * from t0 where (key1 < 3 or key2 < 3) and (key3 < 4 or key4 < 4) and (key5 < 5 or key6 < 5); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t0 index_merge i1,i2,i3,i4,i5,i6 i1,i2 4,4 NULL 6 Using sort_union(i1,i2); Using where +1 SIMPLE t0 index_merge i1,i2,i3,i4,i5,i6 i1,i2 4,4 NULL 4 Using sort_union(i1,i2); Using where explain select * from t0 where (key1 < 3 or key2 < 6) and (key1 < 7 or key3 < 4); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t0 index_merge i1,i2,i3 i1,i2 4,4 NULL 9 Using sort_union(i1,i2); Using where +1 SIMPLE t0 index_merge i1,i2,i3 i1,i2 4,4 NULL 7 Using sort_union(i1,i2); Using where select * from t0 where (key1 < 3 or key2 < 6) and (key1 < 7 or key3 < 4); key1 key2 key3 key4 key5 key6 key7 key8 1 1 1 1 1 1 1 1023 @@ -116,15 +116,15 @@ key1 key2 key3 key4 key5 key6 key7 key8 explain select * from t0 where (key1 < 3 or key2 < 3) and (key3 < 4 or key4 < 4) and (key5 < 2 or key6 < 2); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t0 index_merge i1,i2,i3,i4,i5,i6 i1,i2 4,4 NULL 6 Using sort_union(i1,i2); Using where +1 SIMPLE t0 index_merge i1,i2,i3,i4,i5,i6 i5,i6 4,4 NULL 2 Using sort_union(i5,i6); Using where explain select * from t0 where (key1 < 3 or key2 < 3) and (key3 < 100); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t0 index_merge i1,i2,i3 i1,i2 4,4 NULL 6 Using sort_union(i1,i2); Using where +1 SIMPLE t0 index_merge i1,i2,i3 i1,i2 4,4 NULL 4 Using sort_union(i1,i2); Using where explain select * from t0 where (key1 < 3 or key2 < 3) and (key3 < 1000); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t0 index_merge i1,i2,i3 i1,i2 4,4 NULL 6 Using sort_union(i1,i2); Using where +1 SIMPLE t0 index_merge i1,i2,i3 i1,i2 4,4 NULL 4 Using sort_union(i1,i2); Using where explain select * from t0 where ((key1 < 4 or key2 < 4) and (key2 <5 or key3 < 4)) or @@ -136,7 +136,7 @@ explain select * from t0 where or key1 < 7; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t0 index_merge i1,i2,i3 i1,i2 4,4 NULL 10 Using sort_union(i1,i2); Using where +1 SIMPLE t0 index_merge i1,i2,i3 i1,i2 4,4 NULL 8 Using sort_union(i1,i2); Using where select * from t0 where ((key1 < 4 or key2 < 4) and (key2 <5 or key3 < 4)) or @@ -148,30 +148,36 @@ key1 key2 key3 key4 key5 key6 key7 key8 4 4 4 4 4 4 4 1020 5 5 5 5 5 5 5 1019 6 6 6 6 6 6 6 1018 +select count(*) from t0 where +((key1 < 4 or key2 < 4) and (key3 <5 or key5 < 4)) +or +((key5 < 5 or key6 < 6) and (key7 <7 or key8 < 4)); +count(*) +5 explain select * from t0 where ((key1 < 4 or key2 < 4) and (key3 <5 or key5 < 4)) or ((key5 < 5 or key6 < 6) and (key7 <7 or key8 < 4)); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t0 index_merge i1,i2,i3,i5,i6,i7,i8 i1,i2,i5,i6 4,4,4,4 NULL 19 Using sort_union(i1,i2,i5,i6); Using where +1 SIMPLE t0 index_merge i1,i2,i3,i5,i6,i7,i8 i1,i2,i5,i6 4,4,4,4 NULL 15 Using sort_union(i1,i2,i5,i6); Using where explain select * from t0 where ((key3 <5 or key5 < 4) and (key1 < 4 or key2 < 4)) or ((key7 <7 or key8 < 4) and (key5 < 5 or key6 < 6)); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t0 index_merge i1,i2,i3,i5,i6,i7,i8 i3,i5,i7,i8 4,4,4,4 NULL 20 Using sort_union(i3,i5,i7,i8); Using where +1 SIMPLE t0 index_merge i1,i2,i3,i5,i6,i7,i8 i3,i5,i7,i8 4,4,4,4 NULL 16 Using sort_union(i3,i5,i7,i8); Using where explain select * from t0 where ((key3 <5 or key5 < 4) and (key1 < 4 or key2 < 4)) or ((key3 <7 or key5 < 2) and (key5 < 5 or key6 < 6)); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t0 index_merge i1,i2,i3,i5,i6 i3,i5 4,4 NULL 11 Using sort_union(i3,i5); Using where +1 SIMPLE t0 index_merge i1,i2,i3,i5,i6 i3,i5 4,4 NULL 9 Using sort_union(i3,i5); Using where explain select * from t0 where ((key3 <5 or key5 < 4) and (key1 < 4 or key2 < 4)) or (((key3 <7 and key7 < 6) or key5 < 2) and (key5 < 5 or key6 < 6)); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t0 index_merge i1,i2,i3,i5,i6,i7 i3,i5 4,4 NULL 11 Using sort_union(i3,i5); Using where +1 SIMPLE t0 index_merge i1,i2,i3,i5,i6,i7 i3,i5 4,4 NULL 9 Using sort_union(i3,i5); Using where explain select * from t0 where ((key3 <5 or key5 < 4) and (key1 < 4 or key2 < 4)) or @@ -197,7 +203,7 @@ key1 key2 key3 key4 key5 key6 key7 key8 explain select * from t0 where key1 < 5 or key8 < 4 order by key1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t0 index_merge i1,i8 i1,i8 4,4 NULL 9 Using sort_union(i1,i8); Using where; Using filesort +1 SIMPLE t0 index_merge i1,i8 i1,i8 4,4 NULL 7 Using sort_union(i1,i8); Using where; Using filesort create table t2 like t0; insert into t2 select * from t0; alter table t2 add index i1_3(key1, key3); @@ -213,7 +219,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 index i1_3,i2_3 i321 12 NULL 1024 Using where; Using index explain select key7 from t2 where key1 <100 or key2 < 100; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 index_merge i1_3,i2_3 i1_3,i2_3 4,4 NULL 188 Using sort_union(i1_3,i2_3); Using where +1 SIMPLE t2 index_merge i1_3,i2_3 i1_3,i2_3 4,4 NULL 186 Using sort_union(i1_3,i2_3); Using where create table t4 ( key1a int not null, key1b int not null, @@ -238,10 +244,10 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t4 index_merge i1a,i1b i1a,i1b 4,4 NULL 2 Using sort_union(i1a,i1b); Using where explain select * from t4 where key2 = 1 and (key2_1 = 1 or key3 = 5); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t4 ref i2_1,i2_2 i2_1 4 const 10 Using where +1 SIMPLE t4 ref i2_1,i2_2 i2_1 4 const 9 Using where explain select * from t4 where key2 = 1 and (key2_1 = 1 or key2_2 = 5); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t4 ref i2_1,i2_2 i2_1 4 const 10 Using where +1 SIMPLE t4 ref i2_1,i2_2 i2_1 4 const 9 Using where explain select * from t4 where key2_1 = 1 or key2_2 = 5; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t4 ALL NULL NULL NULL NULL 1024 Using where @@ -282,13 +288,13 @@ id select_type table type possible_keys key key_len ref rows Extra explain select * from t0,t1 where t0.key1 < 3 and (t1.key1 = t0.key1 or t1.key8 = t0.key1); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t0 range i1 i1 4 NULL 3 Using index condition +1 SIMPLE t0 range i1 i1 4 NULL 2 Using index condition 1 SIMPLE t1 ALL i1,i8 NULL NULL NULL 1024 Range checked for each record (index map: 0x81) explain select * from t1 where key1=3 or key2=4 union select * from t1 where key1<4 or key3=5; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 index_merge i1,i2 i1,i2 4,4 NULL 2 Using union(i1,i2); Using where -2 UNION t1 index_merge i1,i3 i1,i3 4,4 NULL 5 Using sort_union(i1,i3); Using where +2 UNION t1 index_merge i1,i3 i1,i3 4,4 NULL 4 Using sort_union(i1,i3); Using where NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL set @tmp_optimizer_switch=@@optimizer_switch; set optimizer_switch='derived_merge=off,derived_with_keys=off'; @@ -329,7 +335,7 @@ key1 key2 key3 key4 key5 key6 key7 key8 key9 keyA keyB keyC 1016 1016 1016 1016 1016 1016 1016 8 1016 1016 1016 1016 explain select * from t0 where key1 < 3 or key2 < 4; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t0 index_merge i1,i2 i1,i2 4,4 NULL 7 Using sort_union(i1,i2); Using where +1 SIMPLE t0 index_merge i1,i2 i1,i2 4,4 NULL 5 Using sort_union(i1,i2); Using where select * from t0 where key1 < 3 or key2 < 4; key1 key2 key3 key4 key5 key6 key7 key8 1 1 1 1 1 1 1 1023 @@ -357,8 +363,8 @@ from t0 as A force index(i1,i2), t0 as B force index (i1,i2) where (A.key1 < 500000 or A.key2 < 3) and (B.key1 < 500000 or B.key2 < 3); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE A index_merge i1,i2 i1,i2 4,4 NULL 1013 Using sort_union(i1,i2); Using where -1 SIMPLE B index_merge i1,i2 i1,i2 4,4 NULL 1013 Using sort_union(i1,i2); Using where; Using join buffer (flat, BNL join) +1 SIMPLE A index_merge i1,i2 i1,i2 4,4 NULL 1010 Using sort_union(i1,i2); Using where +1 SIMPLE B index_merge i1,i2 i1,i2 4,4 NULL 1010 Using sort_union(i1,i2); Using where; Using join buffer (flat, BNL join) select max(A.key1 + B.key1 + A.key2 + B.key2 + A.key3 + B.key3 + A.key4 + B.key4 + A.key5 + B.key5) from t0 as A force index(i1,i2), t0 as B force index (i1,i2) where (A.key1 < 500000 or A.key2 < 3) @@ -371,8 +377,8 @@ from t0 as A force index(i1,i2), t0 as B force index (i1,i2) where (A.key1 = 1 or A.key2 = 1) and (B.key1 = 1 or B.key2 = 1); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE A index_merge i1,i2 i1,i2 4,4 NULL 1020 Using union(i1,i2); Using where -1 SIMPLE B index_merge i1,i2 i1,i2 4,4 NULL 1020 Using union(i1,i2); Using where; Using join buffer (flat, BNL join) +1 SIMPLE A index_merge i1,i2 i1,i2 4,4 NULL 1021 Using union(i1,i2); Using where +1 SIMPLE B index_merge i1,i2 i1,i2 4,4 NULL 1021 Using union(i1,i2); Using where; Using join buffer (flat, BNL join) select max(A.key1 + B.key1 + A.key2 + B.key2 + A.key3 + B.key3 + A.key4 + B.key4 + A.key5 + B.key5) from t0 as A force index(i1,i2), t0 as B force index (i1,i2) where (A.key1 = 1 or A.key2 = 1) @@ -517,7 +523,7 @@ a filler b must use union, not sort-union: explain select * from t2 where a=4 or b=4; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 index_merge a,b a,b 5,5 NULL # Using union(a,b); Using where +1 SIMPLE t2 ALL a,b NULL NULL NULL # Using where select * from t2 where a=4 or b=4; a filler b 4 4 0 @@ -705,19 +711,19 @@ select key1,key2,filler1 from t1 where key2=100 and key2=200; key1 key2 filler1 explain select key1,key2,key3,key4,filler1 from t1 where key1=100 and key2=100 or key3=100 and key4=100; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index_merge key1,key2,key3,key4 key1,key2,key3,key4 5,5,5,5 NULL 152 Using union(intersect(key1,key2),intersect(key3,key4)); Using where +1 SIMPLE t1 index_merge key1,key2,key3,key4 key1,key2,key3,key4 5,5,5,5 NULL 154 Using union(intersect(key1,key2),intersect(key3,key4)); Using where select key1,key2,key3,key4,filler1 from t1 where key1=100 and key2=100 or key3=100 and key4=100; key1 key2 key3 key4 filler1 -1 -1 100 100 key4-key3 delete from t1 where key3=100 and key4=100; explain select key1,key2,key3,key4,filler1 from t1 where key1=100 and key2=100 or key3=100 and key4=100; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index_merge key1,key2,key3,key4 key1,key2,key3,key4 5,5,5,5 NULL 152 Using union(intersect(key1,key2),intersect(key3,key4)); Using where +1 SIMPLE t1 index_merge key1,key2,key3,key4 key1,key2,key3,key4 5,5,5,5 NULL 154 Using union(intersect(key1,key2),intersect(key3,key4)); Using where select key1,key2,key3,key4,filler1 from t1 where key1=100 and key2=100 or key3=100 and key4=100; key1 key2 key3 key4 filler1 explain select key1,key2 from t1 where key1=100 and key2=100; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index_merge key1,key2 key1,key2 5,5 NULL 76 Using intersect(key1,key2); Using where; Using index +1 SIMPLE t1 index_merge key1,key2 key1,key2 5,5 NULL 77 Using intersect(key1,key2); Using where; Using index select key1,key2 from t1 where key1=100 and key2=100; key1 key2 insert into t1 (key1, key2, key3, key4, filler1) values (100, 100, 200, 200,'key1-key2-key3-key4-1'); @@ -725,7 +731,7 @@ insert into t1 (key1, key2, key3, key4, filler1) values (100, 100, 200, 200,'key insert into t1 (key1, key2, key3, key4, filler1) values (100, 100, 200, 200,'key1-key2-key3-key4-3'); explain select key1,key2,key3,key4,filler1 from t1 where key3=200 or (key1=100 and key2=100) or key4=200; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index_merge key1,key2,key3,key4 key3,key1,key2,key4 5,5,5,5 NULL 136 Using union(key3,intersect(key1,key2),key4); Using where +1 SIMPLE t1 index_merge key1,key2,key3,key4 key3,key1,key2,key4 5,5,5,5 NULL 137 Using union(key3,intersect(key1,key2),key4); Using where select key1,key2,key3,key4,filler1 from t1 where key3=200 or (key1=100 and key2=100) or key4=200; key1 key2 key3 key4 filler1 100 100 200 200 key1-key2-key3-key4-3 @@ -734,7 +740,7 @@ key1 key2 key3 key4 filler1 insert into t1 (key1, key2, key3, key4, filler1) values (-1, -1, -1, 200,'key4'); explain select key1,key2,key3,key4,filler1 from t1 where key3=200 or (key1=100 and key2=100) or key4=200; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index_merge key1,key2,key3,key4 key3,key1,key2,key4 5,5,5,5 NULL 146 Using union(key3,intersect(key1,key2),key4); Using where +1 SIMPLE t1 index_merge key1,key2,key3,key4 key3,key1,key2,key4 5,5,5,5 NULL 148 Using union(key3,intersect(key1,key2),key4); Using where select key1,key2,key3,key4,filler1 from t1 where key3=200 or (key1=100 and key2=100) or key4=200; key1 key2 key3 key4 filler1 100 100 200 200 key1-key2-key3-key4-3 @@ -744,7 +750,7 @@ key1 key2 key3 key4 filler1 insert into t1 (key1, key2, key3, key4, filler1) values (-1, -1, 200, -1,'key3'); explain select key1,key2,key3,key4,filler1 from t1 where key3=200 or (key1=100 and key2=100) or key4=200; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index_merge key1,key2,key3,key4 key3,key1,key2,key4 5,5,5,5 NULL 156 Using union(key3,intersect(key1,key2),key4); Using where +1 SIMPLE t1 index_merge key1,key2,key3,key4 key3,key1,key2,key4 5,5,5,5 NULL 159 Using union(key3,intersect(key1,key2),key4); Using where select key1,key2,key3,key4,filler1 from t1 where key3=200 or (key1=100 and key2=100) or key4=200; key1 key2 key3 key4 filler1 100 100 200 200 key1-key2-key3-key4-3 @@ -760,7 +766,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index_merge sta_swt12a,sta_swt1a,sta_swt2a,sta_swt21a,st_a,stb_swt1a_2b,stb_swt1b,st_b st_a,st_b 4,4 NULL 3515 Using intersect(st_a,st_b); Using where; Using index explain select st_a from t1 ignore index (st_a) where st_a=1 and st_b=1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref sta_swt12a,sta_swt1a,sta_swt2a,sta_swt21a,stb_swt1a_2b,stb_swt1b,st_b st_b 4 const 15093 Using where +1 SIMPLE t1 ref sta_swt12a,sta_swt1a,sta_swt2a,sta_swt21a,stb_swt1a_2b,stb_swt1b,st_b st_b 4 const 15094 Using where explain select * from t1 where st_a=1 and swt1a=1 and swt2a=1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref sta_swt12a,sta_swt1a,sta_swt2a,sta_swt21a,st_a sta_swt21a 12 const,const,const 971 @@ -850,7 +856,7 @@ INDEX i2(key2) ); explain select * from t1 where key1 < 5 or key2 > 197; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index_merge i1,i2 i1,i2 4,4 NULL 10 Using sort_union(i1,i2); Using where +1 SIMPLE t1 index_merge i1,i2 i1,i2 4,4 NULL 8 Using sort_union(i1,i2); Using where select * from t1 where key1 < 5 or key2 > 197; key1 key2 0 200 @@ -860,7 +866,7 @@ key1 key2 4 196 explain select * from t1 where key1 < 3 or key2 > 195; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index_merge i1,i2 i1,i2 4,4 NULL 10 Using sort_union(i1,i2); Using where +1 SIMPLE t1 index_merge i1,i2 i1,i2 4,4 NULL 8 Using sort_union(i1,i2); Using where select * from t1 where key1 < 3 or key2 > 195; key1 key2 0 200 @@ -876,7 +882,7 @@ update t1 set str1='aaa', str2='bbb', str3=concat(key2, '-', key1 div 2, '_' ,if alter table t1 add primary key (str1, zeroval, str2, str3); explain select * from t1 where key1 < 5 or key2 > 197; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index_merge i1,i2 i1,i2 4,4 NULL 10 Using sort_union(i1,i2); Using where +1 SIMPLE t1 index_merge i1,i2 i1,i2 4,4 NULL 8 Using sort_union(i1,i2); Using where select * from t1 where key1 < 5 or key2 > 197; key1 key2 str1 zeroval str2 str3 0 200 aaa 0 bbb 200-0_a @@ -886,7 +892,7 @@ key1 key2 str1 zeroval str2 str3 4 196 aaa 0 bbb 196-2_a explain select * from t1 where key1 < 3 or key2 > 195; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index_merge i1,i2 i1,i2 4,4 NULL 10 Using sort_union(i1,i2); Using where +1 SIMPLE t1 index_merge i1,i2 i1,i2 4,4 NULL 8 Using sort_union(i1,i2); Using where select * from t1 where key1 < 3 or key2 > 195; key1 key2 str1 zeroval str2 str3 0 200 aaa 0 bbb 200-0_a @@ -1444,7 +1450,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref key1,pktail4bad pktail4bad 4 const 82 Using where explain select * from t1 where pktail5bad=1 and key1=10; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref key1,pktail5bad pktail5bad 4 const 70 Using where +1 SIMPLE t1 ref key1,pktail5bad pktail5bad 4 const 69 Using where explain select pk1,pk2,key1,key2 from t1 where key1 = 10 and key2=10 limit 10; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index_merge key1,key2 key1,key2 4,4 NULL 1 Using intersect(key1,key2); Using where @@ -1498,7 +1504,7 @@ EXPLAIN SELECT t1.f1 FROM t1 WHERE (SELECT COUNT(*) FROM t2 WHERE t2.f3 = 'h' AND t2.f2 = t1.f1) = 0 AND t1.f1 = 2; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system PRIMARY NULL NULL NULL 1 -2 SUBQUERY t2 ref f2,f3 f2 5 const 1 Using where +2 SUBQUERY t2 ref f2,f3 f2 5 const 2 Using where DROP TABLE t1,t2; create table t0 (a int); insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); @@ -1515,12 +1521,12 @@ explain select * from t1 where a=1 or b=1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index_merge a,b a,b 5,5 NULL 2 Using union(a,b); Using where This should use ALL: -set optimizer_switch='default,index_merge=off'; +set optimizer_switch='default,index_merge=off,rowid_filter=off'; explain select * from t1 where a=1 or b=1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL a,b NULL NULL NULL 1000 Using where This should use sort-union: -set optimizer_switch='default,index_merge_union=off'; +set optimizer_switch='default,index_merge_union=off,rowid_filter=off'; explain select * from t1 where a=1 or b=1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index_merge a,b a,b 5,5 NULL 2 Using sort_union(a,b); Using where @@ -1530,17 +1536,17 @@ explain select * from t1 where a<1 or b <1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index_merge a,b a,b 5,5 NULL 38 Using sort_union(a,b); Using where This should use ALL: -set optimizer_switch='default,index_merge_sort_union=off'; +set optimizer_switch='default,index_merge_sort_union=off,rowid_filter=off'; explain select * from t1 where a<1 or b <1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL a,b NULL NULL NULL 1000 Using where This should use ALL: -set optimizer_switch='default,index_merge=off'; +set optimizer_switch='default,index_merge=off,rowid_filter=off'; explain select * from t1 where a<1 or b <1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL a,b NULL NULL NULL 1000 Using where This will use sort-union: -set optimizer_switch='default,index_merge_union=off'; +set optimizer_switch='default,index_merge_union=off,rowid_filter=off'; explain select * from t1 where a<1 or b <1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index_merge a,b a,b 5,5 NULL 38 Using sort_union(a,b); Using where @@ -1552,7 +1558,7 @@ explain select * from t1 where (a=3 or b in (1,2)) and (c=3 or d=4); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index_merge a,b,c,d a,b 5,5 NULL 3 Using sort_union(a,b); Using where And if we disable sort_union, union: -set optimizer_switch='default,index_merge_sort_union=off'; +set optimizer_switch='default,index_merge_sort_union=off,rowid_filter=off'; explain select * from t1 where (a=3 or b in (1,2)) and (c=3 or d=4); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index_merge a,b,c,d c,d 5,5 NULL 100 Using union(c,d); Using where @@ -1571,22 +1577,22 @@ explain select * from t1 where a=10 and b=10; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index_merge a,b a,b 5,5 NULL 1 Using intersect(a,b); Using where No intersect when index_merge is disabled: -set optimizer_switch='default,index_merge=off'; +set optimizer_switch='default,index_merge=off,rowid_filter=off'; explain select * from t1 where a=10 and b=10; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref a,b a 5 const 49 Using where No intersect if it is disabled: -set optimizer_switch='default,index_merge_sort_intersection=off,index_merge_intersection=off'; +set optimizer_switch='default,index_merge_sort_intersection=off,index_merge_intersection=off,rowid_filter=off'; explain select * from t1 where a=10 and b=10; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref a,b a 5 const 49 Using where Do intersect when union was disabled -set optimizer_switch='default,index_merge_union=off'; +set optimizer_switch='default,index_merge_union=off,rowid_filter=off'; explain select * from t1 where a=10 and b=10; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index_merge a,b a,b 5,5 NULL 1 Using intersect(a,b); Using where Do intersect when sort_union was disabled -set optimizer_switch='default,index_merge_sort_union=off'; +set optimizer_switch='default,index_merge_sort_union=off,rowid_filter=off'; explain select * from t1 where a=10 and b=10; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index_merge a,b a,b 5,5 NULL 1 Using intersect(a,b); Using where @@ -1596,13 +1602,13 @@ explain select * from t1 where a=10 and b=10 or c=10; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index_merge a,b,c a,b,c 5,5,5 NULL 6 Using union(intersect(a,b),c); Using where Should be only union left: -set optimizer_switch='default,index_merge_intersection=off'; +set optimizer_switch='default,index_merge_intersection=off,rowid_filter=off'; explain select * from t1 where a=10 and b=10 or c=10; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index_merge a,b,c a,c 5,5 NULL 54 Using union(a,c); Using where This will switch to sort-union (intersection will be gone, too, that's a known limitation: -set optimizer_switch='default,index_merge_union=off'; +set optimizer_switch='default,index_merge_union=off,rowid_filter=off'; explain select * from t1 where a=10 and b=10 or c=10; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index_merge a,b,c a,c 5,5 NULL 54 Using sort_union(a,c); Using where @@ -1647,7 +1653,7 @@ SELECT * FROM t1 FORCE INDEX ( PRIMARY, population_rate, area_rate, code ) WHERE pk = 1 OR population_rate = 1 OR ( area_rate IN ( 1,2 ) OR area_rate IS NULL ) AND (population_rate = 25 OR area_rate BETWEEN 2 AND 25 OR code BETWEEN 'MA' AND 'TX'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index_merge PRIMARY,code,population_rate,area_rate PRIMARY,population_rate,area_rate 4,5,5 NULL 2 Using sort_union(PRIMARY,population_rate,area_rate); Using where +1 SIMPLE t1 index_merge PRIMARY,code,population_rate,area_rate PRIMARY,population_rate,area_rate,code 4,5,5,3 NULL 2 Using sort_union(PRIMARY,population_rate,area_rate,code); Using where SELECT * FROM t1 FORCE INDEX ( PRIMARY, population_rate, area_rate, code ) WHERE pk = 1 OR population_rate = 1 OR ( area_rate IN ( 1,2 ) OR area_rate IS NULL ) AND (population_rate = 25 OR area_rate BETWEEN 2 AND 25 OR code BETWEEN 'MA' AND 'TX'); diff --git a/mysql-test/main/index_merge_myisam.test b/mysql-test/main/index_merge_myisam.test index 75beb9bd883..c3ac7fd32e5 100644 --- a/mysql-test/main/index_merge_myisam.test +++ b/mysql-test/main/index_merge_myisam.test @@ -16,6 +16,7 @@ let $merge_table_support= 1; set @optimizer_switch_save= @@optimizer_switch; +set optimizer_switch='rowid_filter=off'; set optimizer_switch='index_merge_sort_intersection=off'; --source include/index_merge1.inc @@ -39,11 +40,11 @@ from t0 A, t0 B, t0 C; explain select * from t1 where a=1 or b=1; --echo This should use ALL: -set optimizer_switch='default,index_merge=off'; +set optimizer_switch='default,index_merge=off,rowid_filter=off'; explain select * from t1 where a=1 or b=1; --echo This should use sort-union: -set optimizer_switch='default,index_merge_union=off'; +set optimizer_switch='default,index_merge_union=off,rowid_filter=off'; explain select * from t1 where a=1 or b=1; --echo This will use sort-union: @@ -51,16 +52,16 @@ set optimizer_switch=default; explain select * from t1 where a<1 or b <1; --echo This should use ALL: -set optimizer_switch='default,index_merge_sort_union=off'; +set optimizer_switch='default,index_merge_sort_union=off,rowid_filter=off'; explain select * from t1 where a<1 or b <1; --echo This should use ALL: -set optimizer_switch='default,index_merge=off'; +set optimizer_switch='default,index_merge=off,rowid_filter=off'; explain select * from t1 where a<1 or b <1; --echo This will use sort-union: -set optimizer_switch='default,index_merge_union=off'; +set optimizer_switch='default,index_merge_union=off,rowid_filter=off'; explain select * from t1 where a<1 or b <1; alter table t1 add d int, add key(d); @@ -71,7 +72,7 @@ set optimizer_switch=default; explain select * from t1 where (a=3 or b in (1,2)) and (c=3 or d=4); --echo And if we disable sort_union, union: -set optimizer_switch='default,index_merge_sort_union=off'; +set optimizer_switch='default,index_merge_sort_union=off,rowid_filter=off'; explain select * from t1 where (a=3 or b in (1,2)) and (c=3 or d=4); drop table t1; @@ -92,19 +93,19 @@ set optimizer_switch=default; explain select * from t1 where a=10 and b=10; --echo No intersect when index_merge is disabled: -set optimizer_switch='default,index_merge=off'; +set optimizer_switch='default,index_merge=off,rowid_filter=off'; explain select * from t1 where a=10 and b=10; --echo No intersect if it is disabled: -set optimizer_switch='default,index_merge_sort_intersection=off,index_merge_intersection=off'; +set optimizer_switch='default,index_merge_sort_intersection=off,index_merge_intersection=off,rowid_filter=off'; explain select * from t1 where a=10 and b=10; --echo Do intersect when union was disabled -set optimizer_switch='default,index_merge_union=off'; +set optimizer_switch='default,index_merge_union=off,rowid_filter=off'; explain select * from t1 where a=10 and b=10; --echo Do intersect when sort_union was disabled -set optimizer_switch='default,index_merge_sort_union=off'; +set optimizer_switch='default,index_merge_sort_union=off,rowid_filter=off'; explain select * from t1 where a=10 and b=10; # Now take union-of-intersection and see how we can disable parts of it @@ -113,12 +114,12 @@ set optimizer_switch=default; explain select * from t1 where a=10 and b=10 or c=10; --echo Should be only union left: -set optimizer_switch='default,index_merge_intersection=off'; +set optimizer_switch='default,index_merge_intersection=off,rowid_filter=off'; explain select * from t1 where a=10 and b=10 or c=10; --echo This will switch to sort-union (intersection will be gone, too, --echo that's a known limitation: -set optimizer_switch='default,index_merge_union=off'; +set optimizer_switch='default,index_merge_union=off,rowid_filter=off'; explain select * from t1 where a=10 and b=10 or c=10; set optimizer_switch=default; diff --git a/mysql-test/main/innodb_ext_key.result b/mysql-test/main/innodb_ext_key.result index c55e8d138f8..3339e00e7bf 100644 --- a/mysql-test/main/innodb_ext_key.result +++ b/mysql-test/main/innodb_ext_key.result @@ -1,6 +1,11 @@ DROP TABLE IF EXISTS t1,t2,t3,t4; DROP DATABASE IF EXISTS dbt3_s001; SET SESSION STORAGE_ENGINE='InnoDB'; +set @innodb_stats_persistent_save= @@innodb_stats_persistent; +set @innodb_stats_persistent_sample_pages_save= +@@innodb_stats_persistent_sample_pages; +set global innodb_stats_persistent= 1; +set global innodb_stats_persistent_sample_pages=100; CREATE DATABASE dbt3_s001; use dbt3_s001; set @save_ext_key_optimizer_switch=@@optimizer_switch; @@ -1027,10 +1032,14 @@ create table t1 (a bigint not null unique auto_increment, b varchar(10), primary create table t2 (a bigint not null unique auto_increment, b varchar(10), primary key (a), key (b(2))) engine = innodb default character set utf8; insert into t1 (b) values (null), (null), (null); insert into t2 (b) values (null), (null), (null); +analyze table t1,t2; +Table Op Msg_type Msg_text +test.t1 analyze status OK +test.t2 analyze status OK set optimizer_switch='extended_keys=on'; explain select a from t1 where b is null order by a desc limit 2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index b PRIMARY 8 NULL 3 Using where +1 SIMPLE t1 index b PRIMARY 8 NULL 2 Using where select a from t1 where b is null order by a desc limit 2; a 3 @@ -1208,3 +1217,6 @@ EXPLAIN } } drop table t1; +set global innodb_stats_persistent= @innodb_stats_persistent_save; +set global innodb_stats_persistent_sample_pages= +@innodb_stats_persistent_sample_pages_save; diff --git a/mysql-test/main/innodb_ext_key.test b/mysql-test/main/innodb_ext_key.test index a721943e8bc..9ec9f569210 100644 --- a/mysql-test/main/innodb_ext_key.test +++ b/mysql-test/main/innodb_ext_key.test @@ -7,6 +7,13 @@ DROP DATABASE IF EXISTS dbt3_s001; SET SESSION STORAGE_ENGINE='InnoDB'; +set @innodb_stats_persistent_save= @@innodb_stats_persistent; +set @innodb_stats_persistent_sample_pages_save= + @@innodb_stats_persistent_sample_pages; + +set global innodb_stats_persistent= 1; +set global innodb_stats_persistent_sample_pages=100; + CREATE DATABASE dbt3_s001; use dbt3_s001; @@ -674,6 +681,8 @@ create table t2 (a bigint not null unique auto_increment, b varchar(10), primary insert into t1 (b) values (null), (null), (null); insert into t2 (b) values (null), (null), (null); +analyze table t1,t2; + set optimizer_switch='extended_keys=on'; explain select a from t1 where b is null order by a desc limit 2; select a from t1 where b is null order by a desc limit 2; @@ -821,3 +830,7 @@ INSERT INTO t1 VALUES (1,2,'2','abc'),(2,3,'3','def'); explain format= json select * from t1 force index(k1) where f2 <= 5 and pk2 <=5 and pk1 = 'abc' and f1 <= '3'; drop table t1; + +set global innodb_stats_persistent= @innodb_stats_persistent_save; +set global innodb_stats_persistent_sample_pages= + @innodb_stats_persistent_sample_pages_save; diff --git a/mysql-test/main/innodb_icp.result b/mysql-test/main/innodb_icp.result index 8a58a769ed9..c65e4d1f7f2 100644 --- a/mysql-test/main/innodb_icp.result +++ b/mysql-test/main/innodb_icp.result @@ -1,5 +1,10 @@ set @save_storage_engine= @@storage_engine; set storage_engine=InnoDB; +set @innodb_stats_persistent_save= @@innodb_stats_persistent; +set @innodb_stats_persistent_sample_pages_save= +@@innodb_stats_persistent_sample_pages; +set global innodb_stats_persistent= 1; +set global innodb_stats_persistent_sample_pages=100; set @innodb_icp_tmp=@@optimizer_switch; set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; # @@ -590,6 +595,10 @@ i1 INTEGER NOT NULL, PRIMARY KEY (pk) ); INSERT INTO t2 VALUES (4,1); +ANALYZE TABLE t1,t2; +Table Op Msg_type Msg_text +test.t1 analyze status OK +test.t2 analyze status OK EXPLAIN SELECT t1.d1, t2.pk, t2.i1 FROM t1 STRAIGHT_JOIN t2 ON t2.i1 WHERE t2.pk <> t1.d1 AND t2.pk = 4; @@ -679,7 +688,7 @@ EXPLAIN SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0 HAVING t1.c != 5 ORDER BY t1.c; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using where; Using filesort +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 1 Using where; Using filesort 1 SIMPLE t2 ref a a 515 test.t1.a 1 Using where SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0 HAVING t1.c != 5 ORDER BY t1.c; @@ -690,7 +699,7 @@ EXPLAIN SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0 HAVING t1.c != 5 ORDER BY t1.c; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using where; Using filesort +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 1 Using where; Using filesort 1 SIMPLE t2 ref a a 515 test.t1.a 1 Using where SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0 HAVING t1.c != 5 ORDER BY t1.c; @@ -795,6 +804,10 @@ INSERT INTO t2 (g,h) VALUES (0,'p'),(0,'f'),(0,'p'),(7,'d'),(7,'f'),(5,'j'), (3,'e'),(1,'u'),(4,'v'),(9,'u'),(6,'i'),(1,'x'), (7,'f'),(5,'j'),(3,'e'),(1,'u'),(4,'v'),(9,'u'); +ANALYZE TABLE t1,t2; +Table Op Msg_type Msg_text +test.t1 analyze status OK +test.t2 analyze status OK SET @save_optimize_switch=@@optimizer_switch; SET optimizer_switch='materialization=on'; EXPLAIN @@ -947,3 +960,6 @@ pk key1 key2 drop table t1, t2; set optimizer_switch=@innodb_icp_tmp; set storage_engine= @save_storage_engine; +set global innodb_stats_persistent= @innodb_stats_persistent_save; +set global innodb_stats_persistent_sample_pages= +@innodb_stats_persistent_sample_pages_save; diff --git a/mysql-test/main/innodb_icp.test b/mysql-test/main/innodb_icp.test index acb8238e01f..d192ce044df 100644 --- a/mysql-test/main/innodb_icp.test +++ b/mysql-test/main/innodb_icp.test @@ -7,6 +7,13 @@ set @save_storage_engine= @@storage_engine; set storage_engine=InnoDB; +set @innodb_stats_persistent_save= @@innodb_stats_persistent; +set @innodb_stats_persistent_sample_pages_save= + @@innodb_stats_persistent_sample_pages; + +set global innodb_stats_persistent= 1; +set global innodb_stats_persistent_sample_pages=100; + set @innodb_icp_tmp=@@optimizer_switch; set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; @@ -76,3 +83,7 @@ drop table t1, t2; set optimizer_switch=@innodb_icp_tmp; set storage_engine= @save_storage_engine; +set global innodb_stats_persistent= @innodb_stats_persistent_save; +set global innodb_stats_persistent_sample_pages= + @innodb_stats_persistent_sample_pages_save; + diff --git a/mysql-test/main/invisible_field_debug.result b/mysql-test/main/invisible_field_debug.result index b3c84d18333..64f1d7f720e 100644 --- a/mysql-test/main/invisible_field_debug.result +++ b/mysql-test/main/invisible_field_debug.result @@ -329,6 +329,9 @@ insert into t1 values(1,1,1); insert into t1 values(2,2,2); insert into t1 values(3,3,3); insert into t1 values(4,4,4); +insert into t1 values(5,5,5); +insert into t1 values(6,6,6); +insert into t1 values(7,7,7); set debug_dbug= "+d,test_completely_invisible,test_invisible_index"; select invisible, a ,b from t1 order by b; invisible a b @@ -336,9 +339,12 @@ invisible a b 9 2 2 9 3 3 9 4 4 +9 5 5 +9 6 6 +9 7 7 explain select * from t1 where invisible =9; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref invisible invisible 5 const 3 +1 SIMPLE t1 ALL invisible NULL NULL NULL 7 Using where alter table t1 add x int default 3; select invisible, a ,b from t1; invisible a b @@ -346,6 +352,9 @@ invisible a b 9 2 2 9 3 3 9 4 4 +9 5 5 +9 6 6 +9 7 7 set debug_dbug=@old_debug; Show index from t1; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment @@ -357,11 +366,11 @@ drop index invisible on t1; ERROR 42000: Can't DROP INDEX `invisible`; check that it exists explain select * from t1 where invisible =9; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref invisible invisible 5 const 3 +1 SIMPLE t1 ALL invisible NULL NULL NULL 7 Using where create index invisible on t1(c); explain select * from t1 where invisible =9; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref invisible_2 invisible_2 5 const 3 +1 SIMPLE t1 ALL invisible_2 NULL NULL NULL 7 Using where show indexes in t1; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment t1 1 b 1 b A NULL NULL NULL YES BTREE diff --git a/mysql-test/main/invisible_field_debug.test b/mysql-test/main/invisible_field_debug.test index c1d6899d16e..48cccb1d2cc 100644 --- a/mysql-test/main/invisible_field_debug.test +++ b/mysql-test/main/invisible_field_debug.test @@ -249,6 +249,9 @@ insert into t1 values(1,1,1); insert into t1 values(2,2,2); insert into t1 values(3,3,3); insert into t1 values(4,4,4); +insert into t1 values(5,5,5); +insert into t1 values(6,6,6); +insert into t1 values(7,7,7); set debug_dbug= "+d,test_completely_invisible,test_invisible_index"; select invisible, a ,b from t1 order by b; explain select * from t1 where invisible =9; diff --git a/mysql-test/main/join.result b/mysql-test/main/join.result index 6ff294906e7..0a0afe6c71d 100644 --- a/mysql-test/main/join.result +++ b/mysql-test/main/join.result @@ -1268,6 +1268,10 @@ id select_type table type possible_keys key key_len ref rows Extra INSERT INTO t1 VALUES (3,'b'),(4,NULL),(5,'c'),(6,'cc'),(7,'d'), (8,'dd'),(9,'e'),(10,'ee'); INSERT INTO t2 VALUES (2,NULL); +ANALYZE TABLE t1,t2; +Table Op Msg_type Msg_text +test.t1 analyze status OK +test.t2 analyze status OK FLUSH STATUS; SELECT * FROM t1 JOIN t2 ON t1.v = t2.v WHERE t2.v IS NULL ORDER BY 1; pk v pk v diff --git a/mysql-test/main/join.test b/mysql-test/main/join.test index 3d2a02e2346..ffb997260cd 100644 --- a/mysql-test/main/join.test +++ b/mysql-test/main/join.test @@ -955,6 +955,7 @@ EXPLAIN SELECT * FROM t1 JOIN t2 ON t1.v = t2.v; INSERT INTO t1 VALUES (3,'b'),(4,NULL),(5,'c'),(6,'cc'),(7,'d'), (8,'dd'),(9,'e'),(10,'ee'); INSERT INTO t2 VALUES (2,NULL); +ANALYZE TABLE t1,t2; FLUSH STATUS; SELECT * FROM t1 JOIN t2 ON t1.v = t2.v WHERE t2.v IS NULL ORDER BY 1; SHOW STATUS LIKE 'Handler_read_%'; diff --git a/mysql-test/main/join_cache.result b/mysql-test/main/join_cache.result index fde6e0fec6b..d079cc8ba3a 100644 --- a/mysql-test/main/join_cache.result +++ b/mysql-test/main/join_cache.result @@ -6,6 +6,11 @@ set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on'; set @@optimizer_switch='semijoin_with_cache=on'; set @@optimizer_switch='outer_join_with_cache=on'; set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; +set @innodb_stats_persistent_save= @@innodb_stats_persistent; +set @innodb_stats_persistent_sample_pages_save= +@@innodb_stats_persistent_sample_pages; +set global innodb_stats_persistent= 1; +set global innodb_stats_persistent_sample_pages=100; set @local_join_cache_test_optimizer_switch_default=@@optimizer_switch; set names utf8; CREATE DATABASE world; @@ -402,7 +407,7 @@ ON City.Country=Country.Code AND City.Population > 5000000 WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where -1 SIMPLE City hash_range City_Population #hash#$hj:City_Population 3:4 world.Country.Code 25 Using where; Rowid-ordered scan; Using join buffer (flat, BNLH join) +1 SIMPLE City hash_range City_Population #hash#$hj:City_Population 3:4 world.Country.Code 24 Using where; Rowid-ordered scan; Using join buffer (flat, BNLH join) SELECT Country.Name, Country.Population, City.Name, City.Population FROM Country LEFT JOIN City ON City.Country=Country.Code AND City.Population > 5000000 @@ -3037,13 +3042,13 @@ t6.formattypeid IN (2) AND (t3.formatid IN (31, 8, 76)) AND t1.metaid = t2.metaid AND t1.affiliateid = '2'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t6 system PRIMARY NULL NULL NULL 1 -1 SIMPLE t1 ref t1_affiliateid,t1_metaid t1_affiliateid 4 const 1 -1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.metaid 1 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan -1 SIMPLE t7 ref PRIMARY PRIMARY 4 test.t1.metaid 1 Using index -1 SIMPLE t8 eq_ref PRIMARY PRIMARY 4 test.t7.artistid 1 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +1 SIMPLE t5 ref PRIMARY,t5_formattypeid t5_formattypeid 4 const 1 +1 SIMPLE t1 ref t1_affiliateid,t1_metaid t1_affiliateid 4 const 2 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.metaid 1 Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan 1 SIMPLE t3 ref t3_metaid,t3_formatid,t3_metaidformatid t3_metaidformatid 4 test.t1.metaid 1 Using index condition; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan 1 SIMPLE t4 eq_ref PRIMARY,t4_formatclassid,t4_formats_idx PRIMARY 4 test.t3.formatid 1 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan -1 SIMPLE t5 eq_ref PRIMARY,t5_formattypeid PRIMARY 4 test.t4.formatclassid 1 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan +1 SIMPLE t7 ref PRIMARY PRIMARY 4 test.t1.metaid 1 Using index +1 SIMPLE t8 eq_ref PRIMARY PRIMARY 4 test.t7.artistid 1 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan 1 SIMPLE t9 index PRIMARY,t9_subgenreid,t9_metaid PRIMARY 8 NULL 2 Using where; Using index; Using join buffer (incremental, BNL join) 1 SIMPLE t10 eq_ref PRIMARY,t10_genreid PRIMARY 4 test.t9.subgenreid 1 Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan 1 SIMPLE t11 eq_ref PRIMARY PRIMARY 4 test.t10.genreid 1 Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan @@ -3160,7 +3165,7 @@ Warning 1292 Truncated incorrect join_buffer_size value: '32' set join_cache_level=8; EXPLAIN SELECT * FROM t1,t2 WHERE t1.a=t2.a AND t1.b >= 30; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL idx NULL NULL NULL 7 Using where +1 SIMPLE t1 range idx idx 5 NULL 3 Using index condition; Using where; Rowid-ordered scan 1 SIMPLE t2 ref idx idx 5 test.t1.a 2 Using join buffer (flat, BKAH join); Key-ordered Rowid-ordered scan SELECT * FROM t1,t2 WHERE t1.a=t2.a AND t1.b >= 30; a b a b @@ -5095,7 +5100,7 @@ SET SESSION join_cache_level = 1; EXPLAIN SELECT * FROM t1,t2 WHERE t1.a < 3 and t2.a IS NULL; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 Using where; Using index +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using where; Using index 1 SIMPLE t2 ref idx idx 5 const 4 Using index condition SELECT * FROM t1,t2 WHERE t1.a < 3 and t2.a IS NULL; a a b @@ -5111,7 +5116,7 @@ SET SESSION join_cache_level = 4; EXPLAIN SELECT * FROM t1,t2 WHERE t1.a < 3 and t2.a IS NULL; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 Using where; Using index +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using where; Using index 1 SIMPLE t2 hash_range idx #hash#idx:idx 5:5 const 4 Using index condition; Using where; Rowid-ordered scan; Using join buffer (flat, BNLH join) SELECT * FROM t1,t2 WHERE t1.a < 3 and t2.a IS NULL; a a b @@ -5414,7 +5419,7 @@ ORDER BY t2.b; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system NULL NULL NULL NULL 1 1 PRIMARY t3 system NULL NULL NULL NULL 1 -1 PRIMARY t2 range a,c a 5 NULL 1 Using index condition; Using where; Using filesort +1 PRIMARY t2 range a,c a 5 NULL 2 Using index condition; Using where; Using filesort 1 PRIMARY t4 ref c c 5 test.t2.c 2 Using where; Start temporary; End temporary SELECT * FROM t1,t2 WHERE t2.c IN (SELECT c FROM t3,t4 WHERE t4.a < 10) AND @@ -5432,7 +5437,7 @@ ORDER BY t2.b; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system NULL NULL NULL NULL 1 Using temporary; Using filesort 1 PRIMARY t3 system NULL NULL NULL NULL 1 -1 PRIMARY t2 range a,c a 5 NULL 1 Using index condition; Using where +1 PRIMARY t2 range a,c a 5 NULL 2 Using index condition; Using where 1 PRIMARY t4 ref c c 5 test.t2.c 2 Using where; Start temporary; End temporary SELECT * FROM t1,t2 WHERE t2.c IN (SELECT c FROM t3,t4 WHERE t4.a < 10) AND @@ -5451,7 +5456,7 @@ ORDER BY t2.b; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system NULL NULL NULL NULL 1 Using temporary; Using filesort 1 PRIMARY t3 system NULL NULL NULL NULL 1 -1 PRIMARY t2 range a,c a 5 NULL 1 Using index condition; Using where +1 PRIMARY t2 range a,c a 5 NULL 2 Using index condition; Using where 1 PRIMARY t4 ref c c 5 test.t2.c 2 Using where; Start temporary; End temporary SELECT * FROM t1,t2 WHERE t2.c IN (SELECT c FROM t3,t4 WHERE t4.a < 10) AND @@ -5934,6 +5939,10 @@ CREATE TABLE t2 (i1 int, v1 varchar(1), KEY v1 (v1,i1)) ENGINE=InnoDB; INSERT INTO t2 VALUES (NULL,'x'),(1,'x'),(3,'x'),(5,'x'),(8,'x'),(48,'x'), (228,'x'),(3,'y'),(1,'z'),(9,'z'); +ANALYZE TABLE t1,t2; +Table Op Msg_type Msg_text +test.t1 analyze status OK +test.t2 analyze status OK CREATE TABLE temp SELECT t1.i1 AS f1, t1.v1 AS f2 FROM (t2 JOIN t1 ON (t1.v1 = t2.v1)); SELECT * FROM temp @@ -6050,3 +6059,6 @@ f2 drop table t1, t2; set join_buffer_size = default; set @@optimizer_switch=@save_optimizer_switch; +set global innodb_stats_persistent= @innodb_stats_persistent_save; +set global innodb_stats_persistent_sample_pages= +@innodb_stats_persistent_sample_pages_save; diff --git a/mysql-test/main/join_cache.test b/mysql-test/main/join_cache.test index df89fc30dee..82c438a96c1 100644 --- a/mysql-test/main/join_cache.test +++ b/mysql-test/main/join_cache.test @@ -10,6 +10,13 @@ set @@optimizer_switch='semijoin_with_cache=on'; set @@optimizer_switch='outer_join_with_cache=on'; set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; +set @innodb_stats_persistent_save= @@innodb_stats_persistent; +set @innodb_stats_persistent_sample_pages_save= + @@innodb_stats_persistent_sample_pages; + +set global innodb_stats_persistent= 1; +set global innodb_stats_persistent_sample_pages=100; + set @local_join_cache_test_optimizer_switch_default=@@optimizer_switch; set names utf8; @@ -3886,6 +3893,8 @@ INSERT INTO t2 VALUES (NULL,'x'),(1,'x'),(3,'x'),(5,'x'),(8,'x'),(48,'x'), (228,'x'),(3,'y'),(1,'z'),(9,'z'); +ANALYZE TABLE t1,t2; + CREATE TABLE temp SELECT t1.i1 AS f1, t1.v1 AS f2 FROM (t2 JOIN t1 ON (t1.v1 = t2.v1)); @@ -3990,3 +3999,7 @@ set join_buffer_size = default; # The following command must be the last one the file set @@optimizer_switch=@save_optimizer_switch; + +set global innodb_stats_persistent= @innodb_stats_persistent_save; +set global innodb_stats_persistent_sample_pages= + @innodb_stats_persistent_sample_pages_save; diff --git a/mysql-test/main/join_nested.result b/mysql-test/main/join_nested.result index b6b4716d8b1..603612eb683 100644 --- a/mysql-test/main/join_nested.result +++ b/mysql-test/main/join_nested.result @@ -1062,9 +1062,9 @@ t0.b=t1.b AND (t8.b=t9.b OR t8.c IS NULL) AND (t9.a=1); id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t0 ref idx_a idx_a 5 const 1 100.00 Using where -1 SIMPLE t1 ref idx_b idx_b 5 test.t0.b 2 100.00 +1 SIMPLE t0 ref idx_a idx_a 5 const 2 100.00 1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t1 ALL idx_b NULL NULL NULL 7 85.71 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using where 1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where 1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 2 100.00 Using where @@ -1110,13 +1110,13 @@ t0.b=t1.b AND (t9.a=1); a b a b a b a b a b a b a b a b a b a b 1 2 2 2 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1 1 +1 2 2 2 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1 2 1 2 3 2 4 2 1 2 3 2 3 1 6 2 1 1 NULL NULL 1 1 1 2 3 2 4 2 1 2 3 2 3 3 NULL NULL NULL NULL NULL NULL 1 1 1 2 3 2 4 2 1 2 4 2 3 1 6 2 1 1 NULL NULL 1 1 1 2 3 2 4 2 1 2 4 2 3 3 NULL NULL NULL NULL NULL NULL 1 1 1 2 3 2 5 3 NULL NULL NULL NULL 3 1 6 2 1 1 NULL NULL 1 1 1 2 3 2 5 3 NULL NULL NULL NULL 3 3 NULL NULL NULL NULL NULL NULL 1 1 -1 2 2 2 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1 2 1 2 3 2 4 2 1 2 3 2 3 1 6 2 1 1 NULL NULL 1 2 1 2 3 2 4 2 1 2 3 2 2 2 6 2 2 2 0 2 1 2 1 2 3 2 4 2 1 2 3 2 3 3 NULL NULL NULL NULL NULL NULL 1 2 @@ -1209,13 +1209,13 @@ INSERT INTO t3 VALUES (0), (1), (2), (3), (4), (5); EXPLAIN SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON c < 3 and b = c; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index NULL a 5 NULL 21 Using index -1 SIMPLE t3 index c c 5 NULL 6 Using where; Using index -1 SIMPLE t2 ref b b 5 test.t3.c 2 Using index +1 SIMPLE t2 range b b 5 NULL 3 Using where; Using index +1 SIMPLE t3 ref c c 5 test.t2.b 2 Using index EXPLAIN SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index NULL a 5 NULL 21 Using index -1 SIMPLE t3 index c c 5 NULL 6 Using where; Using index -1 SIMPLE t2 ref b b 5 test.t3.c 2 Using index +1 SIMPLE t2 range b b 5 NULL 3 Using where; Using index +1 SIMPLE t3 ref c c 5 test.t2.b 2 Using index SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c; a b c NULL 0 0 diff --git a/mysql-test/main/join_nested_jcl6.result b/mysql-test/main/join_nested_jcl6.result index 6b1901d8642..bc65286588c 100644 --- a/mysql-test/main/join_nested_jcl6.result +++ b/mysql-test/main/join_nested_jcl6.result @@ -1073,9 +1073,9 @@ t0.b=t1.b AND (t8.b=t9.b OR t8.c IS NULL) AND (t9.a=1); id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t0 ref idx_a idx_a 5 const 1 100.00 Using where -1 SIMPLE t1 ref idx_b idx_b 5 test.t0.b 2 100.00 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan -1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE t0 ref idx_a idx_a 5 const 2 100.00 +1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t1 ALL idx_b NULL NULL NULL 7 85.71 Using where; Using join buffer (incremental, BNL join) 1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using where; Using join buffer (incremental, BNL join) 1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join) 1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan @@ -1220,13 +1220,13 @@ INSERT INTO t3 VALUES (0), (1), (2), (3), (4), (5); EXPLAIN SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON c < 3 and b = c; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index NULL a 5 NULL 21 Using index -1 SIMPLE t3 index c c 5 NULL 6 Using where; Using index -1 SIMPLE t2 ref b b 5 test.t3.c 2 Using index +1 SIMPLE t2 range b b 5 NULL 3 Using where; Using index +1 SIMPLE t3 ref c c 5 test.t2.b 2 Using index EXPLAIN SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index NULL a 5 NULL 21 Using index -1 SIMPLE t3 index c c 5 NULL 6 Using where; Using index -1 SIMPLE t2 ref b b 5 test.t3.c 2 Using index +1 SIMPLE t2 range b b 5 NULL 3 Using where; Using index +1 SIMPLE t3 ref c c 5 test.t2.b 2 Using index SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c; a b c NULL 0 0 @@ -2002,8 +2002,8 @@ ON t6.b >= 2 AND t5.b=t7.b AND (t8.a > 0 OR t8.c IS NULL) AND t6.a>0 AND t7.a>0; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t5 ALL NULL NULL NULL NULL 3 -1 SIMPLE t7 ref PRIMARY,b_i b_i 5 test.t5.b 2 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan -1 SIMPLE t6 ALL PRIMARY,b_i NULL NULL NULL 7 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE t7 ref|filter PRIMARY,b_i b_i|PRIMARY 5|4 test.t5.b 2 (29%) Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan; Using filter +1 SIMPLE t6 range|filter PRIMARY,b_i PRIMARY|b_i 4|5 NULL 3 (86%) Using where; Rowid-ordered scan; Using join buffer (incremental, BNL join); Using filter 1 SIMPLE t8 ref b_i b_i 5 test.t5.b 2 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b FROM t5 diff --git a/mysql-test/main/join_outer.result b/mysql-test/main/join_outer.result index 6b671a0759f..11bc380e6e6 100644 --- a/mysql-test/main/join_outer.result +++ b/mysql-test/main/join_outer.result @@ -1740,7 +1740,7 @@ from t1,t2 where t2.pk=t1.pk+1000 and t1.pk>1000 group by t2.pk; id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 index PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Using index; Using temporary; Using filesort +1 PRIMARY t1 index PRIMARY PRIMARY 4 NULL 2 50.00 Using where; Using index; Using temporary; Using filesort 1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 func 1 100.00 Using where; Using index 2 DEPENDENT SUBQUERY t3 eq_ref PRIMARY PRIMARY 4 func 1 100.00 Using where; Using index 2 DEPENDENT SUBQUERY t4 eq_ref PRIMARY PRIMARY 4 test.t3.pk 1 100.00 Using index diff --git a/mysql-test/main/join_outer_jcl6.result b/mysql-test/main/join_outer_jcl6.result index f46f3e2df21..bca340ad2cc 100644 --- a/mysql-test/main/join_outer_jcl6.result +++ b/mysql-test/main/join_outer_jcl6.result @@ -1751,7 +1751,7 @@ from t1,t2 where t2.pk=t1.pk+1000 and t1.pk>1000 group by t2.pk; id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 index PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Using index; Using temporary; Using filesort +1 PRIMARY t1 index PRIMARY PRIMARY 4 NULL 2 50.00 Using where; Using index; Using temporary; Using filesort 1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 func 1 100.00 Using where; Using index 2 DEPENDENT SUBQUERY t3 eq_ref PRIMARY PRIMARY 4 func 1 100.00 Using where; Using index 2 DEPENDENT SUBQUERY t4 eq_ref PRIMARY PRIMARY 4 test.t3.pk 1 100.00 Using index diff --git a/mysql-test/main/key.result b/mysql-test/main/key.result index ba1124aaa14..42eca8d6cf0 100644 --- a/mysql-test/main/key.result +++ b/mysql-test/main/key.result @@ -216,7 +216,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 Using index explain select 1 from t1 where id =2 or id=3; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index PRIMARY PRIMARY 4 NULL 7 Using where; Using index +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using where; Using index explain select name from t1 where id =2; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 @@ -603,11 +603,14 @@ INSERT INTO t1 (a, b) VALUES (1,1), (1,2), (1,3), (1,4), (1,5), (2,2), (2,3), (2,1), (3,1), (4,1), (4,2), (4,3), (4,4), (4,5), (4,6); +ANALYZE table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK EXPLAIN SELECT 1 FROM t1 AS t1_outer WHERE (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2) > 12; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE -2 SUBQUERY t1 range NULL a 5 NULL 8 Using index for group-by +2 SUBQUERY t1 range NULL a 5 NULL 4 Using index for group-by SELECT 1 as RES FROM t1 AS t1_outer WHERE (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2) > 12; RES diff --git a/mysql-test/main/key.test b/mysql-test/main/key.test index 0695dc2eecb..ccaef163d08 100644 --- a/mysql-test/main/key.test +++ b/mysql-test/main/key.test @@ -555,6 +555,7 @@ INSERT INTO t1 (a, b) VALUES (1,1), (1,2), (1,3), (1,4), (1,5), (2,2), (2,3), (2,1), (3,1), (4,1), (4,2), (4,3), (4,4), (4,5), (4,6); +ANALYZE table t1; EXPLAIN SELECT 1 FROM t1 AS t1_outer WHERE (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2) > 12; SELECT 1 as RES FROM t1 AS t1_outer WHERE diff --git a/mysql-test/main/key_cache.result b/mysql-test/main/key_cache.result index 1146ae8bbfa..b3368b26bf3 100644 --- a/mysql-test/main/key_cache.result +++ b/mysql-test/main/key_cache.result @@ -440,25 +440,25 @@ VARIABLE_NAME VARIABLE_VALUE KEY_BLOCKS_NOT_FLUSHED 0 KEY_BLOCKS_USED 4 KEY_BLOCKS_WARM 0 -KEY_READ_REQUESTS 22 +KEY_READ_REQUESTS 24 KEY_READS 0 KEY_WRITE_REQUESTS 26 KEY_WRITES 6 select variable_value into @key_blocks_unused from information_schema.session_status where variable_name = 'Key_blocks_unused'; select * from information_schema.key_caches where segment_number is null; KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES -default NULL NULL 2097152 1024 4 # 0 22 0 26 6 +default NULL NULL 2097152 1024 4 # 0 24 0 26 6 small NULL NULL 1048576 1024 1 # 0 1 0 2 1 delete from t2 where a='zzzz'; select * from information_schema.key_caches where segment_number is null; KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES -default NULL NULL 2097152 1024 4 # 0 29 0 32 9 +default NULL NULL 2097152 1024 4 # 0 32 0 32 9 small NULL NULL 1048576 1024 1 # 0 1 0 2 1 delete from t1; delete from t2; select * from information_schema.key_caches where segment_number is null; KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES -default NULL NULL 2097152 1024 4 # 0 29 0 32 9 +default NULL NULL 2097152 1024 4 # 0 32 0 32 9 small NULL NULL 1048576 1024 1 # 0 1 0 2 1 set global key_cache_segments=2; select @@key_cache_segments; @@ -488,7 +488,7 @@ VARIABLE_NAME VARIABLE_VALUE KEY_BLOCKS_NOT_FLUSHED 0 KEY_BLOCKS_USED 4 KEY_BLOCKS_WARM 0 -KEY_READ_REQUESTS 22 +KEY_READ_REQUESTS 24 KEY_READS 0 KEY_WRITE_REQUESTS 26 KEY_WRITES 6 @@ -497,13 +497,13 @@ variable_value < @key_blocks_unused 1 select * from information_schema.key_caches where segment_number is null; KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES -default 2 NULL 2097152 1024 4 # 0 22 0 26 6 +default 2 NULL 2097152 1024 4 # 0 24 0 26 6 small NULL NULL 1048576 1024 1 # 0 1 0 2 1 delete from t1; delete from t2; select * from information_schema.key_caches where segment_number is null; KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES -default 2 NULL 2097152 1024 4 # 0 22 0 26 6 +default 2 NULL 2097152 1024 4 # 0 24 0 26 6 small NULL NULL 1048576 1024 1 # 0 1 0 2 1 set global key_cache_segments=1; select @@key_cache_segments; @@ -533,7 +533,7 @@ VARIABLE_NAME VARIABLE_VALUE KEY_BLOCKS_NOT_FLUSHED 0 KEY_BLOCKS_USED 4 KEY_BLOCKS_WARM 0 -KEY_READ_REQUESTS 22 +KEY_READ_REQUESTS 24 KEY_READS 0 KEY_WRITE_REQUESTS 26 KEY_WRITES 6 @@ -542,13 +542,13 @@ variable_value = @key_blocks_unused 1 select * from information_schema.key_caches where segment_number is null; KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES -default 1 NULL 2097152 1024 4 # 0 22 0 26 6 +default 1 NULL 2097152 1024 4 # 0 24 0 26 6 small NULL NULL 1048576 1024 1 # 0 1 0 2 1 delete from t1; delete from t2; select * from information_schema.key_caches where segment_number is null; KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES -default 1 NULL 2097152 1024 4 # 0 22 0 26 6 +default 1 NULL 2097152 1024 4 # 0 24 0 26 6 small NULL NULL 1048576 1024 1 # 0 1 0 2 1 flush tables; flush status; @@ -586,7 +586,7 @@ update t1 set p=3 where p=1; update t2 set i=2 where i=1; select * from information_schema.key_caches where segment_number is null; KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES -default 2 NULL 32768 1024 4 # 0 22 0 26 6 +default 2 NULL 32768 1024 4 # 0 24 0 26 6 small NULL NULL 1048576 1024 1 # 0 0 0 0 0 insert into t1(a) select a from t1; insert into t1(a) select a from t1; @@ -606,7 +606,7 @@ insert into t2(i,a) select i,a from t2; insert into t2(i,a) select i,a from t2; select * from information_schema.key_caches where segment_number is null; KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES -default 2 NULL 32768 1024 # # 0 6733 # 3684 103 +default 2 NULL 32768 1024 # # 0 6735 # 3684 103 small NULL NULL 1048576 1024 # # 0 0 # 0 0 select * from t1 where p between 1010 and 1020 ; p a @@ -625,7 +625,7 @@ p i a 1020 3 zzzz select * from information_schema.key_caches where segment_number is null; KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES -default 2 NULL 32768 1024 # # 0 6750 # 3684 103 +default 2 NULL 32768 1024 # # 0 6756 # 3684 103 small NULL NULL 1048576 1024 # # 0 0 # 0 0 flush tables; flush status; @@ -633,7 +633,7 @@ update t1 set a='zzzz' where a='qqqq'; update t2 set i=1 where i=2; select * from information_schema.key_caches where segment_number is null; KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES -default 2 NULL 32768 1024 # # 0 3076 18 1552 18 +default 2 NULL 32768 1024 # # 0 3078 18 1552 18 small NULL NULL 1048576 1024 # # 0 0 0 0 0 set global keycache1.key_buffer_size=256*1024; select @@keycache1.key_buffer_size; @@ -645,7 +645,7 @@ select @@keycache1.key_cache_segments; 7 select * from information_schema.key_caches where segment_number is null; KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES -default 2 NULL 32768 1024 # # 0 3076 18 1552 18 +default 2 NULL 32768 1024 # # 0 3078 18 1552 18 small NULL NULL 1048576 1024 # # 0 0 0 0 0 keycache1 7 NULL 262143 2048 # # 0 0 0 0 0 select * from information_schema.key_caches where key_cache_name like "key%" @@ -662,7 +662,7 @@ select p from t1 where p between 1010 and 1020; p explain select i from t2 where p between 1010 and 1020; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 28 Using index condition +1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 9 Using index condition select i from t2 where p between 1010 and 1020; i 1 @@ -685,13 +685,13 @@ count(*) 256 select * from information_schema.key_caches where segment_number is null; KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES -default 2 NULL 32768 1024 # # 0 3172 24 1552 18 +default 2 NULL 32768 1024 # # 0 3178 24 1552 18 small NULL NULL 1048576 1024 # # 0 0 0 0 0 -keycache1 7 NULL 262143 2048 # # 0 14 3 0 0 +keycache1 7 NULL 262143 2048 # # 0 18 3 0 0 select * from information_schema.key_caches where key_cache_name like "key%" and segment_number is null; KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES -keycache1 7 NULL 262143 2048 3 # 0 14 3 0 0 +keycache1 7 NULL 262143 2048 3 # 0 18 3 0 0 cache index t2 in keycache1; Table Op Msg_type Msg_text test.t2 assign_to_keycache status OK @@ -699,7 +699,7 @@ update t2 set p=p+3000, i=2 where a='qqqq'; select * from information_schema.key_caches where key_cache_name like "key%" and segment_number is null; KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES -keycache1 7 NULL 262143 2048 25 # 0 2082 25 1071 19 +keycache1 7 NULL 262143 2048 25 # 0 2088 25 1071 19 set global keycache2.key_buffer_size=1024*1024; cache index t2 in keycache2; Table Op Msg_type Msg_text @@ -712,7 +712,7 @@ keycache2 NULL NULL 1048576 1024 6 # 0 6 6 3 3 select * from information_schema.key_caches where key_cache_name like "key%" and segment_number is null; KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES -keycache1 7 NULL 262143 2048 25 # 0 2082 25 1071 19 +keycache1 7 NULL 262143 2048 25 # 0 2088 25 1071 19 keycache2 NULL NULL 1048576 1024 6 # 0 6 6 3 3 cache index t2 in keycache1; Table Op Msg_type Msg_text @@ -728,7 +728,7 @@ p i a 1019 1 yyyy explain select p from t2 where p between 1010 and 1020; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 7 Using where; Using index +1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 8 Using where; Using index select p from t2 where p between 1010 and 1020; p 1010 @@ -739,92 +739,92 @@ p 1019 explain select i from t2 where a='yyyy' and i=3; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ref k1,k2 k1 5 const 188 Using where +1 SIMPLE t2 ref|filter k1,k2 k1|k2 5|11 const 189 (27%) Using where; Using filter select i from t2 where a='yyyy' and i=3; i 3 explain select a from t2 where a='yyyy' and i=3; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ref k1,k2 k1 5 const 188 Using where +1 SIMPLE t2 ref|filter k1,k2 k1|k2 5|11 const 189 (27%) Using where; Using filter select a from t2 where a='yyyy' and i=3 ; a yyyy select * from information_schema.key_caches where segment_number is null; KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES -default 2 NULL 32768 1024 # # 0 3172 24 1552 18 +default 2 NULL 32768 1024 # # 0 3178 24 1552 18 small NULL NULL 1048576 1024 # # 0 0 0 0 0 -keycache1 7 NULL 262143 2048 # # 0 3201 43 1594 30 +keycache1 7 NULL 262143 2048 # # 0 3283 43 1594 30 keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3 set global keycache1.key_cache_block_size=2*1024; insert into t2 values (7000, 3, 'yyyy'); select * from information_schema.key_caches where segment_number is null; KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES -default 2 NULL 32768 1024 # # 0 3172 24 1552 18 +default 2 NULL 32768 1024 # # 0 3178 24 1552 18 small NULL NULL 1048576 1024 # # 0 0 0 0 0 keycache1 7 NULL 262143 2048 # # 0 6 6 3 3 keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3 set global keycache1.key_cache_block_size=8*1024; select * from information_schema.key_caches where segment_number is null; KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES -default 2 NULL 32768 1024 # # 0 3172 24 1552 18 +default 2 NULL 32768 1024 # # 0 3178 24 1552 18 small NULL NULL 1048576 1024 # # 0 0 0 0 0 keycache1 3 NULL 262143 8192 # # 0 0 0 0 0 keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3 insert into t2 values (8000, 3, 'yyyy'); select * from information_schema.key_caches where segment_number is null; KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES -default 2 NULL 32768 1024 # # 0 3172 24 1552 18 +default 2 NULL 32768 1024 # # 0 3178 24 1552 18 small NULL NULL 1048576 1024 # # 0 0 0 0 0 keycache1 3 NULL 262143 8192 # # 0 6 5 3 3 keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3 set global keycache1.key_buffer_size=64*1024; select * from information_schema.key_caches where segment_number is null; KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES -default 2 NULL 32768 1024 # # 0 3172 24 1552 18 +default 2 NULL 32768 1024 # # 0 3178 24 1552 18 small NULL NULL 1048576 1024 # # 0 0 0 0 0 keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3 set global keycache1.key_cache_block_size=2*1024; select * from information_schema.key_caches where segment_number is null; KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES -default 2 NULL 32768 1024 # # 0 3172 24 1552 18 +default 2 NULL 32768 1024 # # 0 3178 24 1552 18 small NULL NULL 1048576 1024 # # 0 0 0 0 0 keycache1 3 NULL 65535 2048 # # 0 0 0 0 0 keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3 set global keycache1.key_cache_block_size=8*1024; select * from information_schema.key_caches where segment_number is null; KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES -default 2 NULL 32768 1024 # # 0 3172 24 1552 18 +default 2 NULL 32768 1024 # # 0 3178 24 1552 18 small NULL NULL 1048576 1024 # # 0 0 0 0 0 keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3 set global keycache1.key_buffer_size=0; select * from information_schema.key_caches where segment_number is null; KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES -default 2 NULL 32768 1024 # # 0 3172 24 1552 18 +default 2 NULL 32768 1024 # # 0 3178 24 1552 18 small NULL NULL 1048576 1024 # # 0 0 0 0 0 keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3 set global keycache1.key_cache_block_size=8*1024; select * from information_schema.key_caches where segment_number is null; KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES -default 2 NULL 32768 1024 # # 0 3172 24 1552 18 +default 2 NULL 32768 1024 # # 0 3178 24 1552 18 small NULL NULL 1048576 1024 # # 0 0 0 0 0 keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3 set global keycache1.key_buffer_size=0; select * from information_schema.key_caches where segment_number is null; KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES -default 2 NULL 32768 1024 # # 0 3172 24 1552 18 +default 2 NULL 32768 1024 # # 0 3178 24 1552 18 small NULL NULL 1048576 1024 # # 0 0 0 0 0 keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3 set global keycache1.key_buffer_size=128*1024; select * from information_schema.key_caches where segment_number is null; KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES -default 2 NULL 32768 1024 # # 0 3172 24 1552 18 +default 2 NULL 32768 1024 # # 0 3178 24 1552 18 small NULL NULL 1048576 1024 # # 0 0 0 0 0 keycache1 1 NULL 131072 8192 # # 0 0 0 0 0 keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3 set global keycache1.key_cache_block_size=1024; select * from information_schema.key_caches where segment_number is null; KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES -default 2 NULL 32768 1024 # # 0 3172 24 1552 18 +default 2 NULL 32768 1024 # # 0 3178 24 1552 18 small NULL NULL 1048576 1024 # # 0 0 0 0 0 keycache1 7 NULL 131068 1024 # # 0 0 0 0 0 keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3 diff --git a/mysql-test/main/mdev13607.result b/mysql-test/main/mdev13607.result index 08848bc645b..0d573b06b93 100644 --- a/mysql-test/main/mdev13607.result +++ b/mysql-test/main/mdev13607.result @@ -76,21 +76,21 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY p7 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join) 1 PRIMARY p8 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join) 1 PRIMARY p9 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join) -1 PRIMARY <derived3> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join) -1 PRIMARY <derived4> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join) -1 PRIMARY <derived5> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join) -1 PRIMARY <derived6> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join) -1 PRIMARY <derived7> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join) -1 PRIMARY <derived8> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join) -1 PRIMARY <derived9> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join) -1 PRIMARY <derived10> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join) -1 PRIMARY <derived11> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join) -1 PRIMARY <derived12> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join) -1 PRIMARY <derived13> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join) -1 PRIMARY <derived14> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join) -1 PRIMARY <derived15> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join) -1 PRIMARY <derived16> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join) -1 PRIMARY <derived17> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join) +1 PRIMARY <derived3> ALL NULL NULL NULL NULL 17319535557742690304 Using join buffer (incremental, BNL join) +1 PRIMARY <derived4> ALL NULL NULL NULL NULL 17319535557742690304 Using join buffer (incremental, BNL join) +1 PRIMARY <derived5> ALL NULL NULL NULL NULL 17319535557742690304 Using join buffer (incremental, BNL join) +1 PRIMARY <derived6> ALL NULL NULL NULL NULL 17319535557742690304 Using join buffer (incremental, BNL join) +1 PRIMARY <derived7> ALL NULL NULL NULL NULL 17319535557742690304 Using join buffer (incremental, BNL join) +1 PRIMARY <derived8> ALL NULL NULL NULL NULL 17319535557742690304 Using join buffer (incremental, BNL join) +1 PRIMARY <derived9> ALL NULL NULL NULL NULL 17319535557742690304 Using join buffer (incremental, BNL join) +1 PRIMARY <derived10> ALL NULL NULL NULL NULL 17319535557742690304 Using join buffer (incremental, BNL join) +1 PRIMARY <derived11> ALL NULL NULL NULL NULL 17319535557742690304 Using join buffer (incremental, BNL join) +1 PRIMARY <derived12> ALL NULL NULL NULL NULL 17319535557742690304 Using join buffer (incremental, BNL join) +1 PRIMARY <derived13> ALL NULL NULL NULL NULL 17319535557742690304 Using join buffer (incremental, BNL join) +1 PRIMARY <derived14> ALL NULL NULL NULL NULL 17319535557742690304 Using join buffer (incremental, BNL join) +1 PRIMARY <derived15> ALL NULL NULL NULL NULL 17319535557742690304 Using join buffer (incremental, BNL join) +1 PRIMARY <derived16> ALL NULL NULL NULL NULL 17319535557742690304 Using join buffer (incremental, BNL join) +1 PRIMARY <derived17> ALL NULL NULL NULL NULL 17319535557742690304 Using join buffer (incremental, BNL join) 17 DERIVED r1 ALL NULL NULL NULL NULL 2 17 DERIVED d1 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join) 17 DERIVED r2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join) diff --git a/mysql-test/main/merge.result b/mysql-test/main/merge.result index 4f6765420ec..b3cc731a6a9 100644 --- a/mysql-test/main/merge.result +++ b/mysql-test/main/merge.result @@ -38,7 +38,7 @@ insert into t1 select NULL,message from t2; create table t3 (a int not null, b char(20), key(a)) engine=MERGE UNION=(test.t1,test.t2); explain select * from t3 where a < 10; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t3 range a a 4 NULL 18 Using where +1 SIMPLE t3 range a a 4 NULL 17 Using where explain select * from t3 where a > 10 and a < 20; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t3 range a a 4 NULL 17 Using where @@ -669,15 +669,15 @@ KEY files (fileset_id,fileset_root_id) EXPLAIN SELECT * FROM t2 IGNORE INDEX (files) WHERE fileset_id = 2 AND file_code BETWEEN '0000000115' AND '0000000120' LIMIT 1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range PRIMARY PRIMARY 35 NULL 5 Using where +1 SIMPLE t2 range PRIMARY PRIMARY 35 NULL 6 Using where EXPLAIN SELECT * FROM t2 WHERE fileset_id = 2 AND file_code BETWEEN '0000000115' AND '0000000120' LIMIT 1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range PRIMARY,files PRIMARY 35 NULL 5 Using where +1 SIMPLE t2 range PRIMARY,files PRIMARY 35 NULL 6 Using where EXPLAIN SELECT * FROM t1 WHERE fileset_id = 2 AND file_code BETWEEN '0000000115' AND '0000000120' LIMIT 1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY,files PRIMARY 35 NULL 5 Using index condition +1 SIMPLE t1 range PRIMARY,files PRIMARY 35 NULL 6 Using index condition EXPLAIN SELECT * FROM t2 WHERE fileset_id = 2 AND file_code = '0000000115' LIMIT 1; id select_type table type possible_keys key key_len ref rows Extra @@ -742,7 +742,7 @@ insert into t1 (a,b,c) values (1,1,0),(1,2,0); insert into t2 (a,b,c) values (1,1,1),(1,2,1); explain select a,b,c from t3 force index (a) where a=1 order by a,b,c; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t3 ref a a 5 const 2 Using where; Using index +1 SIMPLE t3 ref a a 5 const 4 Using where; Using index select a,b,c from t3 force index (a) where a=1 order by a,b,c; a b c 1 1 0 @@ -751,7 +751,7 @@ a b c 1 2 1 explain select a,b,c from t3 force index (a) where a=1 order by a desc, b desc, c desc; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t3 ref a a 5 const 2 Using where; Using index +1 SIMPLE t3 ref a a 5 const 4 Using where; Using index select a,b,c from t3 force index (a) where a=1 order by a desc, b desc, c desc; a b c 1 2 1 diff --git a/mysql-test/main/mrr_icp_extra.result b/mysql-test/main/mrr_icp_extra.result index 95788b393dd..49acd7bde20 100644 --- a/mysql-test/main/mrr_icp_extra.result +++ b/mysql-test/main/mrr_icp_extra.result @@ -1,6 +1,7 @@ call mtr.add_suppression("Can't find record in .*"); set @mrr_icp_extra_tmp=@@optimizer_switch; set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; +set optimizer_switch='rowid_filter=off'; SET NAMES latin1; CREATE TABLE t1 (s1 char(10) COLLATE latin1_german1_ci, @@ -82,7 +83,7 @@ a b 4 NULL explain select * from t1 where b=2 or b is null order by a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref_or_null b b 5 const 3 Using index condition; Using where; Using filesort +1 SIMPLE t1 ref_or_null b b 5 const 4 Using index condition; Using where; Using filesort select * from t1 where b=2 or b is null order by a; a b 3 NULL @@ -103,10 +104,10 @@ KEY StringField (FieldKey,StringVal(32)) INSERT INTO t1 VALUES ('0',3,'0'),('0',2,'1'),('0',1,'2'),('1',2,'1'),('1',1,'3'), ('1',0,'2'),('2',3,'0'),('2',2,'1'),('2',1,'2'),('2',3,'0'),('2',2,'1'),('2',1,'2'),('3',2,'1'),('3',1,'2'),('3','3','3'); EXPLAIN SELECT * FROM t1 IGNORE INDEX (LongField, StringField) WHERE FieldKey > '2' ORDER BY LongVal; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range FieldKey FieldKey 38 NULL 4 Using index condition; Rowid-ordered scan; Using filesort +1 SIMPLE t1 range FieldKey FieldKey 38 NULL 3 Using index condition; Rowid-ordered scan; Using filesort EXPLAIN SELECT * FROM t1 IGNORE INDEX (FieldKey, LongField) WHERE FieldKey > '2' ORDER BY LongVal; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range StringField StringField 38 NULL 4 Using where; Using filesort +1 SIMPLE t1 range StringField StringField 38 NULL 3 Using where; Using filesort SELECT * FROM t1 WHERE FieldKey > '2' ORDER BY LongVal; FieldKey LongVal StringVal 3 1 2 @@ -124,7 +125,7 @@ Table Op Msg_type Msg_text test.t1 optimize status OK explain select * from t1 force index (a) where a=0 or a=2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 4 NULL 4 Using index condition; Using where; Rowid-ordered scan +1 SIMPLE t1 range a a 4 NULL 5 Using index condition; Using where; Rowid-ordered scan select * from t1 force index (a) where a=0 or a=2; a b c 0 NULL 0 diff --git a/mysql-test/main/mrr_icp_extra.test b/mysql-test/main/mrr_icp_extra.test index 75ddc85b984..38306f54ed5 100644 --- a/mysql-test/main/mrr_icp_extra.test +++ b/mysql-test/main/mrr_icp_extra.test @@ -4,6 +4,7 @@ call mtr.add_suppression("Can't find record in .*"); set @mrr_icp_extra_tmp=@@optimizer_switch; set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; +set optimizer_switch='rowid_filter=off'; SET NAMES latin1; CREATE TABLE t1 (s1 char(10) COLLATE latin1_german1_ci, diff --git a/mysql-test/main/myisam.result b/mysql-test/main/myisam.result index bef8790e141..498536c1862 100644 --- a/mysql-test/main/myisam.result +++ b/mysql-test/main/myisam.result @@ -395,7 +395,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL a NULL NULL NULL 5 Using where explain select * from t1 force index (a) where a=0 or a=2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 4 NULL 4 Using index condition; Using where +1 SIMPLE t1 range a a 4 NULL 5 Using index condition; Using where explain select * from t1 where c=1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref c,c_2 c 5 const 1 @@ -641,7 +641,7 @@ create table t1 ( a tinytext, b char(1), index idx (a(1),b) ); insert into t1 values (null,''), (null,''); explain select count(*) from t1 where a is null; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref idx idx 4 const 1 Using where +1 SIMPLE t1 ref idx idx 4 const 2 Using where select count(*) from t1 where a is null; count(*) 2 diff --git a/mysql-test/main/myisam_explain_non_select_all.result b/mysql-test/main/myisam_explain_non_select_all.result index 8e4db5ed482..939d6c417eb 100644 --- a/mysql-test/main/myisam_explain_non_select_all.result +++ b/mysql-test/main/myisam_explain_non_select_all.result @@ -696,12 +696,12 @@ Warnings: Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead EXPLAIN DELETE FROM t1 WHERE t1.a > 0 ORDER BY t1.a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 1 Using where +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE FLUSH STATUS; FLUSH TABLES; EXPLAIN EXTENDED DELETE FROM t1 WHERE t1.a > 0 ORDER BY t1.a; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 1 100.00 Using where +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE # Status of EXPLAIN EXTENDED query Variable_name Value FLUSH STATUS; @@ -721,9 +721,8 @@ Variable_name Value Handler_read_rnd_next 1 # Status of testing query execution: Variable_name Value -Handler_read_key 1 -INSERT INTO t1 VALUES (1), (2), (3); +INSERT INTO t1 VALUES (1), (2), (3), (-1), (-2), (-3); # # query: DELETE FROM t1 WHERE t1.a > 0 ORDER BY t1.a # select: SELECT * FROM t1 WHERE t1.a > 0 ORDER BY t1.a @@ -2351,19 +2350,19 @@ Warnings: Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead EXPLAIN UPDATE t1 SET a=a+10 WHERE a > 34; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 Using where; Using buffer +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using where; Using buffer FLUSH STATUS; FLUSH TABLES; EXPLAIN EXTENDED UPDATE t1 SET a=a+10 WHERE a > 34; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 100.00 Using where; Using buffer +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Using buffer # Status of EXPLAIN EXTENDED query Variable_name Value FLUSH STATUS; FLUSH TABLES; EXPLAIN EXTENDED SELECT * FROM t1 WHERE a > 34; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 100.00 Using where; Using index +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Using index Warnings: Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 34 # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution @@ -2627,7 +2626,7 @@ DROP TABLE t1; DROP VIEW v1; #63 CREATE TABLE t1 (a INT, PRIMARY KEY(a)); -INSERT INTO t1 VALUES (1), (2), (3), (4), (5); +INSERT INTO t1 VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9); CREATE VIEW v1 (a) AS SELECT a FROM t1; # # query: DELETE FROM v1 WHERE a < 4 diff --git a/mysql-test/main/myisam_icp.result b/mysql-test/main/myisam_icp.result index 6a70521cd72..b9b4926455c 100644 --- a/mysql-test/main/myisam_icp.result +++ b/mysql-test/main/myisam_icp.result @@ -505,7 +505,7 @@ SELECT c2 FROM t1 JOIN t2 ON t1.c1 = t2.c1 WHERE (t2.pk <= 4 AND t1.pk IN (2,1)) OR (t1.pk > 1 AND t2.pk BETWEEN 6 AND 6); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using where; Rowid-ordered scan +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 1 Using index condition; Using where; Rowid-ordered scan 1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using where; Rowid-ordered scan; Using join buffer (flat, BNL join) SELECT c2 FROM t1 JOIN t2 ON t1.c1 = t2.c1 WHERE (t2.pk <= 4 AND t1.pk IN (2,1)) OR @@ -588,6 +588,10 @@ i1 INTEGER NOT NULL, PRIMARY KEY (pk) ); INSERT INTO t2 VALUES (4,1); +ANALYZE TABLE t1,t2; +Table Op Msg_type Msg_text +test.t1 analyze status OK +test.t2 analyze status OK EXPLAIN SELECT t1.d1, t2.pk, t2.i1 FROM t1 STRAIGHT_JOIN t2 ON t2.i1 WHERE t2.pk <> t1.d1 AND t2.pk = 4; @@ -793,6 +797,10 @@ INSERT INTO t2 (g,h) VALUES (0,'p'),(0,'f'),(0,'p'),(7,'d'),(7,'f'),(5,'j'), (3,'e'),(1,'u'),(4,'v'),(9,'u'),(6,'i'),(1,'x'), (7,'f'),(5,'j'),(3,'e'),(1,'u'),(4,'v'),(9,'u'); +ANALYZE TABLE t1,t2; +Table Op Msg_type Msg_text +test.t1 analyze status OK +test.t2 analyze status Table is already up to date SET @save_optimize_switch=@@optimizer_switch; SET optimizer_switch='materialization=on'; EXPLAIN @@ -913,7 +921,7 @@ SET SESSION optimizer_switch='index_condition_pushdown=off'; EXPLAIN SELECT a, MIN(c) FROM t1 WHERE b = 'x' AND c > 'x' GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref idx idx 4 const 1 Using where; Using temporary; Using filesort +1 SIMPLE t1 ref idx idx 4 const 2 Using where; Using temporary; Using filesort SELECT a, MIN(c) FROM t1 WHERE b = 'x' AND c > 'x' GROUP BY a; a MIN(c) 5 y @@ -921,7 +929,7 @@ SET SESSION optimizer_switch='index_condition_pushdown=on'; EXPLAIN SELECT a, MIN(c) FROM t1 WHERE b = 'x' AND c > 'x' GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref idx idx 4 const 1 Using index condition; Using where; Using temporary; Using filesort +1 SIMPLE t1 ref idx idx 4 const 2 Using index condition; Using where; Using temporary; Using filesort SELECT a, MIN(c) FROM t1 WHERE b = 'x' AND c > 'x' GROUP BY a; a MIN(c) 5 y @@ -976,7 +984,7 @@ set optimizer_switch='mrr=off'; # Must not use ICP: explain select * from t1 where a between 5 and 8 order by a desc, col desc; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 39 Using where +1 SIMPLE t1 range a a 5 NULL 40 Using where set optimizer_switch= @tmp_10000051; # Must not use ICP: explain select * from t1 where a=3 and col > 500 order by a desc, col desc; diff --git a/mysql-test/main/myisam_mrr.result b/mysql-test/main/myisam_mrr.result index 511e6a8d01f..95aa93eb40e 100644 --- a/mysql-test/main/myisam_mrr.result +++ b/mysql-test/main/myisam_mrr.result @@ -210,7 +210,7 @@ NULL NULL NULL NULL-1 explain select * from t4 where (a ='b-1' or a='bb-1') and b IS NULL and (c='c-1' or c='cc-2'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t4 range idx1 idx1 29 NULL 21 Using index condition; Using where; Rowid-ordered scan +1 SIMPLE t4 range idx1 idx1 29 NULL 20 Using index condition; Using where; Rowid-ordered scan select * from t4 where (a ='b-1' or a='bb-1') and b IS NULL and (c='c-1' or c='cc-2'); a b c filler b-1 NULL c-1 NULL-15 @@ -575,7 +575,7 @@ insert into t1 select A.a+10*B.a+100*C.a+1000*D.a, 123,'filler' from t0 A, t0 B, t0 C, t0 D; explain select sum(b) from t1 where a < 10; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 8 Using index condition; Rowid-ordered scan +1 SIMPLE t1 range a a 5 NULL 9 Using index condition; Rowid-ordered scan # This should show one MRR scan and no re-fills: flush status; select sum(b) from t1 where a < 10; diff --git a/mysql-test/main/mysql_client_test.result b/mysql-test/main/mysql_client_test.result index 6f65979517b..b5100f96e7d 100644 --- a/mysql-test/main/mysql_client_test.result +++ b/mysql-test/main/mysql_client_test.result @@ -135,7 +135,7 @@ EXPALIN number of fields: 10 - 5: name: 'key'/''; table: ''/''; db: ''; catalog: 'def'; length: 192; max_length: 0; type: 253; decimals: 39 - 6: name: 'key_len'/''; table: ''/''; db: ''; catalog: 'def'; length: 12288; max_length: 0; type: 253; decimals: 39 - 7: name: 'ref'/''; table: ''/''; db: ''; catalog: 'def'; length: 6144; max_length: 0; type: 253; decimals: 39 - - 8: name: 'rows'/''; table: ''/''; db: ''; catalog: 'def'; length: 10; max_length: 0; type: 8; decimals: 0 + - 8: name: 'rows'/''; table: ''/''; db: ''; catalog: 'def'; length: 192; max_length: 0; type: 253; decimals: 39 - 9: name: 'Extra'/''; table: ''/''; db: ''; catalog: 'def'; length: 765; max_length: 0; type: 253; decimals: 39 EXPALIN JSON number of fields: 1 - 0: name: 'EXPLAIN'/''; table: ''/''; db: ''; catalog: 'def'; length: 234; max_length: 0; type: 253; decimals: 39 @@ -148,7 +148,7 @@ ANALYZE number of fields: 13 - 5: name: 'key'/''; table: ''/''; db: ''; catalog: 'def'; length: 192; max_length: 0; type: 253; decimals: 39 - 6: name: 'key_len'/''; table: ''/''; db: ''; catalog: 'def'; length: 12288; max_length: 0; type: 253; decimals: 39 - 7: name: 'ref'/''; table: ''/''; db: ''; catalog: 'def'; length: 6144; max_length: 0; type: 253; decimals: 39 - - 8: name: 'rows'/''; table: ''/''; db: ''; catalog: 'def'; length: 10; max_length: 0; type: 8; decimals: 0 + - 8: name: 'rows'/''; table: ''/''; db: ''; catalog: 'def'; length: 192; max_length: 0; type: 253; decimals: 39 - 9: name: 'r_rows'/''; table: ''/''; db: ''; catalog: 'def'; length: 4; max_length: 0; type: 5; decimals: 10 - 10: name: 'filtered'/''; table: ''/''; db: ''; catalog: 'def'; length: 4; max_length: 0; type: 5; decimals: 2 - 11: name: 'r_filtered'/''; table: ''/''; db: ''; catalog: 'def'; length: 4; max_length: 0; type: 5; decimals: 2 @@ -164,7 +164,7 @@ EXPALIN INSERT number of fields: 10 - 5: name: 'key'/''; table: ''/''; db: ''; catalog: 'def'; length: 192; max_length: 0; type: 253; decimals: 39 - 6: name: 'key_len'/''; table: ''/''; db: ''; catalog: 'def'; length: 12288; max_length: 0; type: 253; decimals: 39 - 7: name: 'ref'/''; table: ''/''; db: ''; catalog: 'def'; length: 6144; max_length: 0; type: 253; decimals: 39 - - 8: name: 'rows'/''; table: ''/''; db: ''; catalog: 'def'; length: 10; max_length: 0; type: 8; decimals: 0 + - 8: name: 'rows'/''; table: ''/''; db: ''; catalog: 'def'; length: 192; max_length: 0; type: 253; decimals: 39 - 9: name: 'Extra'/''; table: ''/''; db: ''; catalog: 'def'; length: 765; max_length: 0; type: 253; decimals: 39 EXPALIN JSON INSERT number of fields: 1 - 0: name: 'EXPLAIN'/''; table: ''/''; db: ''; catalog: 'def'; length: 234; max_length: 0; type: 253; decimals: 39 @@ -177,7 +177,7 @@ ANALYZE INSERT number of fields: 13 - 5: name: 'key'/''; table: ''/''; db: ''; catalog: 'def'; length: 192; max_length: 0; type: 253; decimals: 39 - 6: name: 'key_len'/''; table: ''/''; db: ''; catalog: 'def'; length: 12288; max_length: 0; type: 253; decimals: 39 - 7: name: 'ref'/''; table: ''/''; db: ''; catalog: 'def'; length: 6144; max_length: 0; type: 253; decimals: 39 - - 8: name: 'rows'/''; table: ''/''; db: ''; catalog: 'def'; length: 10; max_length: 0; type: 8; decimals: 0 + - 8: name: 'rows'/''; table: ''/''; db: ''; catalog: 'def'; length: 192; max_length: 0; type: 253; decimals: 39 - 9: name: 'r_rows'/''; table: ''/''; db: ''; catalog: 'def'; length: 4; max_length: 0; type: 5; decimals: 10 - 10: name: 'filtered'/''; table: ''/''; db: ''; catalog: 'def'; length: 4; max_length: 0; type: 5; decimals: 2 - 11: name: 'r_filtered'/''; table: ''/''; db: ''; catalog: 'def'; length: 4; max_length: 0; type: 5; decimals: 2 @@ -193,7 +193,7 @@ EXPALIN UPDATE number of fields: 10 - 5: name: 'key'/''; table: ''/''; db: ''; catalog: 'def'; length: 192; max_length: 0; type: 253; decimals: 39 - 6: name: 'key_len'/''; table: ''/''; db: ''; catalog: 'def'; length: 12288; max_length: 0; type: 253; decimals: 39 - 7: name: 'ref'/''; table: ''/''; db: ''; catalog: 'def'; length: 6144; max_length: 0; type: 253; decimals: 39 - - 8: name: 'rows'/''; table: ''/''; db: ''; catalog: 'def'; length: 10; max_length: 0; type: 8; decimals: 0 + - 8: name: 'rows'/''; table: ''/''; db: ''; catalog: 'def'; length: 192; max_length: 0; type: 253; decimals: 39 - 9: name: 'Extra'/''; table: ''/''; db: ''; catalog: 'def'; length: 765; max_length: 0; type: 253; decimals: 39 EXPALIN JSON UPDATE number of fields: 1 - 0: name: 'EXPLAIN'/''; table: ''/''; db: ''; catalog: 'def'; length: 234; max_length: 0; type: 253; decimals: 39 @@ -206,7 +206,7 @@ ANALYZE UPDATE number of fields: 13 - 5: name: 'key'/''; table: ''/''; db: ''; catalog: 'def'; length: 192; max_length: 0; type: 253; decimals: 39 - 6: name: 'key_len'/''; table: ''/''; db: ''; catalog: 'def'; length: 12288; max_length: 0; type: 253; decimals: 39 - 7: name: 'ref'/''; table: ''/''; db: ''; catalog: 'def'; length: 6144; max_length: 0; type: 253; decimals: 39 - - 8: name: 'rows'/''; table: ''/''; db: ''; catalog: 'def'; length: 10; max_length: 0; type: 8; decimals: 0 + - 8: name: 'rows'/''; table: ''/''; db: ''; catalog: 'def'; length: 192; max_length: 0; type: 253; decimals: 39 - 9: name: 'r_rows'/''; table: ''/''; db: ''; catalog: 'def'; length: 4; max_length: 0; type: 5; decimals: 10 - 10: name: 'filtered'/''; table: ''/''; db: ''; catalog: 'def'; length: 4; max_length: 0; type: 5; decimals: 2 - 11: name: 'r_filtered'/''; table: ''/''; db: ''; catalog: 'def'; length: 4; max_length: 0; type: 5; decimals: 2 @@ -222,7 +222,7 @@ EXPALIN DELETE number of fields: 10 - 5: name: 'key'/''; table: ''/''; db: ''; catalog: 'def'; length: 192; max_length: 0; type: 253; decimals: 39 - 6: name: 'key_len'/''; table: ''/''; db: ''; catalog: 'def'; length: 12288; max_length: 0; type: 253; decimals: 39 - 7: name: 'ref'/''; table: ''/''; db: ''; catalog: 'def'; length: 6144; max_length: 0; type: 253; decimals: 39 - - 8: name: 'rows'/''; table: ''/''; db: ''; catalog: 'def'; length: 10; max_length: 0; type: 8; decimals: 0 + - 8: name: 'rows'/''; table: ''/''; db: ''; catalog: 'def'; length: 192; max_length: 0; type: 253; decimals: 39 - 9: name: 'Extra'/''; table: ''/''; db: ''; catalog: 'def'; length: 765; max_length: 0; type: 253; decimals: 39 EXPALIN JSON DELETE number of fields: 1 - 0: name: 'EXPLAIN'/''; table: ''/''; db: ''; catalog: 'def'; length: 234; max_length: 0; type: 253; decimals: 39 @@ -235,7 +235,7 @@ ANALYZE DELETE number of fields: 13 - 5: name: 'key'/''; table: ''/''; db: ''; catalog: 'def'; length: 192; max_length: 0; type: 253; decimals: 39 - 6: name: 'key_len'/''; table: ''/''; db: ''; catalog: 'def'; length: 12288; max_length: 0; type: 253; decimals: 39 - 7: name: 'ref'/''; table: ''/''; db: ''; catalog: 'def'; length: 6144; max_length: 0; type: 253; decimals: 39 - - 8: name: 'rows'/''; table: ''/''; db: ''; catalog: 'def'; length: 10; max_length: 0; type: 8; decimals: 0 + - 8: name: 'rows'/''; table: ''/''; db: ''; catalog: 'def'; length: 192; max_length: 0; type: 253; decimals: 39 - 9: name: 'r_rows'/''; table: ''/''; db: ''; catalog: 'def'; length: 4; max_length: 0; type: 5; decimals: 10 - 10: name: 'filtered'/''; table: ''/''; db: ''; catalog: 'def'; length: 4; max_length: 0; type: 5; decimals: 2 - 11: name: 'r_filtered'/''; table: ''/''; db: ''; catalog: 'def'; length: 4; max_length: 0; type: 5; decimals: 2 diff --git a/mysql-test/main/mysqld--help.result b/mysql-test/main/mysqld--help.result index 5ee85eee7de..68ed55c7e60 100644 --- a/mysql-test/main/mysqld--help.result +++ b/mysql-test/main/mysqld--help.result @@ -546,6 +546,8 @@ The following specify which files/extra groups are read (specified before remain relay log will be rotated automatically when the size exceeds this value. If 0 at startup, it's set to max_binlog_size + --max-rowid-filter-size=# + The maximum number of rows that fit in memory --max-seeks-for-key=# Limit assumed max number of seeks when looking up rows based on a key @@ -679,7 +681,7 @@ The following specify which files/extra groups are read (specified before remain optimize_join_buffer_size, table_elimination, extended_keys, exists_to_in, orderby_uses_equalities, condition_pushdown_for_derived, split_materialized, - condition_pushdown_for_subquery + condition_pushdown_for_subquery, rowid_filter --optimizer-use-condition-selectivity=# Controls selectivity of which conditions the optimizer takes into account to calculate cardinality of a partial @@ -1509,6 +1511,7 @@ max-long-data-size 16777216 max-prepared-stmt-count 16382 max-recursive-iterations 18446744073709551615 max-relay-log-size 1073741824 +max-rowid-filter-size 131072 max-seeks-for-key 18446744073709551615 max-session-mem-used 9223372036854775807 max-sort-length 1024 @@ -1545,7 +1548,7 @@ old-style-user-limits FALSE optimizer-prune-level 1 optimizer-search-depth 62 optimizer-selectivity-sampling-limit 100 -optimizer-switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on +optimizer-switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on optimizer-use-condition-selectivity 1 performance-schema FALSE performance-schema-accounts-size -1 diff --git a/mysql-test/main/mysqldump.result b/mysql-test/main/mysqldump.result index 1a3b927f981..28b37eb6644 100644 --- a/mysql-test/main/mysqldump.result +++ b/mysql-test/main/mysqldump.result @@ -4336,11 +4336,12 @@ show create event ee1; Event sql_mode time_zone Create Event character_set_client collation_connection Database Collation ee1 UTC CREATE DEFINER=`root`@`localhost` EVENT `ee1` ON SCHEDULE AT '2035-12-31 20:01:23' ON COMPLETION NOT PRESERVE ENABLE DO set @a=5 latin1 latin1_swedish_ci latin1_swedish_ci create event ee2 on schedule at '2018-12-31 21:01:23' do set @a=5; +Warnings: +Note 1588 Event execution time is in the past and ON COMPLETION NOT PRESERVE is set. The event was dropped immediately after creation create event ee3 on schedule at '2030-12-31 22:01:23' do set @a=5; show events; Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation second ee1 root@localhost UTC ONE TIME 2035-12-31 20:01:23 NULL NULL NULL NULL ENABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci -second ee2 root@localhost UTC ONE TIME 2018-12-31 21:01:23 NULL NULL NULL NULL ENABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci second ee3 root@localhost UTC ONE TIME 2030-12-31 22:01:23 NULL NULL NULL NULL ENABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci drop database second; create database third; @@ -4348,7 +4349,6 @@ use third; show events; Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation third ee1 root@localhost UTC ONE TIME 2035-12-31 20:01:23 NULL NULL NULL NULL ENABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci -third ee2 root@localhost UTC ONE TIME 2018-12-31 21:01:23 NULL NULL NULL NULL ENABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci third ee3 root@localhost UTC ONE TIME 2030-12-31 22:01:23 NULL NULL NULL NULL ENABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci drop database third; set time_zone = 'SYSTEM'; diff --git a/mysql-test/main/negation_elimination.result b/mysql-test/main/negation_elimination.result index 1b08baee60a..6e40074c317 100644 --- a/mysql-test/main/negation_elimination.result +++ b/mysql-test/main/negation_elimination.result @@ -4,7 +4,7 @@ insert into t1 values (NULL), (0), (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11), (12), (13), (14), (15), (16), (17), (18), (19); explain select * from t1 where not(not(a)); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 20 Using where; Using index +1 SIMPLE t1 index a a 5 NULL 21 Using where; Using index select * from t1 where not(not(a)); a 1 @@ -28,7 +28,7 @@ a 19 explain select * from t1 where not(not(not(a > 10))); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 10 Using where; Using index +1 SIMPLE t1 range a a 5 NULL 11 Using where; Using index select * from t1 where not(not(not(a > 10))); a 0 @@ -44,7 +44,7 @@ a 10 explain select * from t1 where not(not(not(a < 5) and not(a > 10))); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 5 Using where; Using index +1 SIMPLE t1 range a a 5 NULL 6 Using where; Using index select * from t1 where not(not(not(a < 5) and not(a > 10))); a 5 @@ -55,7 +55,7 @@ a 10 explain select * from t1 where not(a = 10); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 19 Using where; Using index +1 SIMPLE t1 index a a 5 NULL 21 Using where; Using index select * from t1 where not(a = 10); a 0 @@ -85,7 +85,7 @@ a 1 explain select * from t1 where not(a < 10); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 11 Using where; Using index +1 SIMPLE t1 range a a 5 NULL 10 Using where; Using index select * from t1 where not(a < 10); a 10 @@ -100,7 +100,7 @@ a 19 explain select * from t1 where not(a >= 10); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 9 Using where; Using index +1 SIMPLE t1 range a a 5 NULL 10 Using where; Using index select * from t1 where not(a >= 10); a 0 @@ -115,7 +115,7 @@ a 9 explain select * from t1 where not(a > 10); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 10 Using where; Using index +1 SIMPLE t1 range a a 5 NULL 11 Using where; Using index select * from t1 where not(a > 10); a 0 @@ -131,7 +131,7 @@ a 10 explain select * from t1 where not(a <= 10); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 10 Using where; Using index +1 SIMPLE t1 range a a 5 NULL 9 Using where; Using index select * from t1 where not(a <= 10); a 11 @@ -145,7 +145,7 @@ a 19 explain select * from t1 where not(a is null); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 20 Using where; Using index +1 SIMPLE t1 index a a 5 NULL 21 Using where; Using index select * from t1 where not(a is null); a 0 @@ -176,7 +176,7 @@ a NULL explain select * from t1 where not(a < 5 or a > 15); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 10 Using where; Using index +1 SIMPLE t1 range a a 5 NULL 11 Using where; Using index select * from t1 where not(a < 5 or a > 15); a 5 @@ -192,7 +192,7 @@ a 15 explain select * from t1 where not(a < 15 and a > 5); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 12 Using where; Using index +1 SIMPLE t1 range a a 5 NULL 11 Using where; Using index select * from t1 where not(a < 15 and a > 5); a 0 @@ -208,7 +208,7 @@ a 19 explain select * from t1 where a = 2 or not(a < 10); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 12 Using where; Using index +1 SIMPLE t1 range a a 5 NULL 11 Using where; Using index select * from t1 where a = 2 or not(a < 10); a 2 @@ -224,7 +224,7 @@ a 19 explain select * from t1 where a > 5 and not(a > 10); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 4 Using where; Using index +1 SIMPLE t1 range a a 5 NULL 5 Using where; Using index select * from t1 where a > 5 and not(a > 10); a 6 @@ -255,7 +255,7 @@ a 19 explain select * from t1 where a = 2 or not(a < 5 or a > 15); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 11 Using where; Using index +1 SIMPLE t1 range a a 5 NULL 12 Using where; Using index select * from t1 where a = 2 or not(a < 5 or a > 15); a 2 @@ -272,7 +272,7 @@ a 15 explain select * from t1 where a = 7 or not(a < 15 and a > 5); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 13 Using where; Using index +1 SIMPLE t1 index a a 5 NULL 21 Using where; Using index select * from t1 where a = 7 or not(a < 15 and a > 5); a 0 @@ -289,7 +289,7 @@ a 19 explain select * from t1 where NULL or not(a < 15 and a > 5); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 12 Using where; Using index +1 SIMPLE t1 range a a 5 NULL 11 Using where; Using index select * from t1 where NULL or not(a < 15 and a > 5); a 0 @@ -327,7 +327,7 @@ a 0 explain select * from t1 where not((a < 5 or a < 10) and (not(a > 16) or a > 17)); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 11 Using where; Using index +1 SIMPLE t1 range a a 5 NULL 10 Using where; Using index select * from t1 where not((a < 5 or a < 10) and (not(a > 16) or a > 17)); a 10 @@ -362,7 +362,7 @@ a 19 explain select * from t1 where ((a between 5 and 15) and (not(a like 10))); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 10 Using where; Using index +1 SIMPLE t1 range a a 5 NULL 11 Using where; Using index select * from t1 where ((a between 5 and 15) and (not(a like 10))); a 5 @@ -500,7 +500,7 @@ NULL NULL 3 1 explain extended select a, not(not(a)), not(a <= 2 and not(a)), not(a not like "1"), not (a not in (1,2)), not(a != 2) from t1 where not(not(a)) having not(not(a)); id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 range a a 5 NULL 4 100.00 Using where; Using index +1 SIMPLE t1 index a a 5 NULL 5 80.00 Using where; Using index Warnings: Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`a` <> 0 AS `not(not(a))`,`test`.`t1`.`a` > 2 or `test`.`t1`.`a` <> 0 AS `not(a <= 2 and not(a))`,`test`.`t1`.`a` like '1' AS `not(a not like "1")`,`test`.`t1`.`a` in (1,2) AS `not (a not in (1,2))`,`test`.`t1`.`a` = 2 AS `not(a != 2)` from `test`.`t1` where `test`.`t1`.`a` <> 0 having `test`.`t1`.`a` <> 0 drop table t1; diff --git a/mysql-test/main/null.result b/mysql-test/main/null.result index 6601c5e1ed4..fc29f68baf0 100644 --- a/mysql-test/main/null.result +++ b/mysql-test/main/null.result @@ -187,7 +187,7 @@ Warnings: Warning 1265 Data truncated for column 'i' at row 513 explain select * from t1 where i=2 or i is null; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref i i 4 const 7 Using index +1 SIMPLE t1 ref i i 4 const 8 Using index select count(*) from t1 where i=2 or i is null; count(*) 9 diff --git a/mysql-test/main/null_key.result b/mysql-test/main/null_key.result index 4b4a4b80dee..525a12100e5 100644 --- a/mysql-test/main/null_key.result +++ b/mysql-test/main/null_key.result @@ -18,9 +18,9 @@ id select_type table type possible_keys key key_len ref rows Extra explain select * from t1 where a<=>b limit 2; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index NULL a 9 NULL 12 Using where; Using index -explain select * from t1 where (a is null or a > 0 and a < 3) and b < 5 limit 3; +explain select * from t1 where (a is null or a > 0 and a < 2) and b < 5 limit 3; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a,b a 9 NULL 3 Using where; Using index +1 SIMPLE t1 range a,b a 9 NULL 2 Using where; Using index explain select * from t1 where (a is null or a = 7) and b=7; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref_or_null a,b a 9 const,const 2 Using where; Using index @@ -257,10 +257,11 @@ uniq_id int(10) unsigned default NULL, PRIMARY KEY (id) ) ENGINE=MyISAM; INSERT INTO t1 VALUES (1,NULL),(2,NULL),(3,1),(4,2),(5,NULL),(6,NULL),(7,3),(8,4),(9,NULL),(10,NULL); +INSERT INTO t1 VALUES (11,5),(12,6),(13,7),(14,8),(15,9); INSERT INTO t2 VALUES (1,NULL),(2,NULL),(3,1),(4,2),(5,NULL),(6,NULL),(7,3),(8,4),(9,NULL),(10,NULL); explain select id from t1 where uniq_id is null; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref idx1 idx1 5 const 5 Using index condition +1 SIMPLE t1 ref idx1 idx1 5 const 6 Using index condition explain select id from t1 where uniq_id =1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 const idx1 idx1 5 const 1 @@ -290,6 +291,11 @@ id uniq_id 4 2 7 3 8 4 +11 5 +12 6 +13 7 +14 8 +15 9 SELECT * FROM t2 ORDER BY uniq_id, id; id uniq_id 3 1 diff --git a/mysql-test/main/null_key.test b/mysql-test/main/null_key.test index c3ebc6f5b94..a5781cc8524 100644 --- a/mysql-test/main/null_key.test +++ b/mysql-test/main/null_key.test @@ -12,7 +12,7 @@ explain select * from t1 where a is null and b = 2; explain select * from t1 where a is null and b = 7; explain select * from t1 where a=2 and b = 2; explain select * from t1 where a<=>b limit 2; -explain select * from t1 where (a is null or a > 0 and a < 3) and b < 5 limit 3; +explain select * from t1 where (a is null or a > 0 and a < 2) and b < 5 limit 3; explain select * from t1 where (a is null or a = 7) and b=7; explain select * from t1 where (a is null or a = 7) and b=7 order by a; explain select * from t1 where (a is null and b>a) or a is null and b=7 limit 2; @@ -103,8 +103,8 @@ CREATE TABLE t2 ( ) ENGINE=MyISAM; INSERT INTO t1 VALUES (1,NULL),(2,NULL),(3,1),(4,2),(5,NULL),(6,NULL),(7,3),(8,4),(9,NULL),(10,NULL); +INSERT INTO t1 VALUES (11,5),(12,6),(13,7),(14,8),(15,9); INSERT INTO t2 VALUES (1,NULL),(2,NULL),(3,1),(4,2),(5,NULL),(6,NULL),(7,3),(8,4),(9,NULL),(10,NULL); - # # Check IS NULL optimization # diff --git a/mysql-test/main/order_by.result b/mysql-test/main/order_by.result index e2b05ccec9e..6e1518f327c 100644 --- a/mysql-test/main/order_by.result +++ b/mysql-test/main/order_by.result @@ -294,81 +294,108 @@ member_id nickname voornaam drop table t1; create table t1 (a int not null, b int, c varchar(10), key (a, b, c)); insert into t1 values (1, NULL, NULL), (1, NULL, 'b'), (1, 1, NULL), (1, 1, 'b'), (1, 1, 'b'), (2, 1, 'a'), (2, 1, 'b'), (2, 2, 'a'), (2, 2, 'b'), (2, 3, 'c'),(1,3,'b'); +insert into t1 select * from t1; explain select * from t1 where (a = 1 and b is null and c = 'b') or (a > 2) order by a desc; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 22 NULL 2 Using where; Using index +1 SIMPLE t1 range a a 22 NULL 3 Using where; Using index select * from t1 where (a = 1 and b is null and c = 'b') or (a > 2) order by a desc; a b c 1 NULL b +1 NULL b explain select * from t1 where a >= 1 and a < 3 order by a desc; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 4 NULL 10 Using where; Using index +1 SIMPLE t1 range a a 4 NULL 22 Using where; Using index select * from t1 where a >= 1 and a < 3 order by a desc; a b c 2 3 c +2 3 c +2 2 b 2 2 b 2 2 a +2 2 a +2 1 b 2 1 b 2 1 a +2 1 a 1 3 b +1 3 b +1 1 b +1 1 b 1 1 b 1 1 b 1 1 NULL +1 1 NULL +1 NULL b 1 NULL b 1 NULL NULL +1 NULL NULL explain select * from t1 where a = 1 order by a desc, b desc; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref a a 4 const 5 Using where; Using index +1 SIMPLE t1 ref a a 4 const 12 Using where; Using index select * from t1 where a = 1 order by a desc, b desc; a b c 1 3 b +1 3 b +1 1 b 1 1 b 1 1 b +1 1 b +1 1 NULL 1 1 NULL 1 NULL b +1 NULL b +1 NULL NULL 1 NULL NULL explain select * from t1 where a = 1 and b is null order by a desc, b desc; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref a a 9 const,const 2 Using where; Using index; Using filesort +1 SIMPLE t1 ref a a 9 const,const 4 Using where; Using index; Using filesort select * from t1 where a = 1 and b is null order by a desc, b desc; a b c 1 NULL NULL +1 NULL NULL +1 NULL b 1 NULL b explain select * from t1 where a >= 1 and a < 3 and b >0 order by a desc,b desc; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 9 NULL 8 Using where; Using index +1 SIMPLE t1 range a a 9 NULL 18 Using where; Using index explain select * from t1 where a = 2 and b >0 order by a desc,b desc; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 9 NULL 5 Using where; Using index +1 SIMPLE t1 range a a 9 NULL 10 Using where; Using index explain select * from t1 where a = 2 and b is null order by a desc,b desc; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref a a 9 const,const 1 Using where; Using index; Using filesort explain select * from t1 where a = 2 and (b is null or b > 0) order by a desc,b desc; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 9 NULL 6 Using where; Using index +1 SIMPLE t1 range a a 9 NULL 11 Using where; Using index explain select * from t1 where a = 2 and b > 0 order by a desc,b desc; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 9 NULL 5 Using where; Using index +1 SIMPLE t1 range a a 9 NULL 10 Using where; Using index explain select * from t1 where a = 2 and b < 2 order by a desc,b desc; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 9 NULL 2 Using where; Using index +1 SIMPLE t1 range a a 9 NULL 4 Using where; Using index explain select * from t1 where a = 1 order by b desc; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref a a 4 const 5 Using where; Using index +1 SIMPLE t1 ref a a 4 const 12 Using where; Using index explain select * from t1 where a = 2 and b > 0 order by a desc,b desc,b,a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 9 NULL 5 Using where; Using index +1 SIMPLE t1 range a a 9 NULL 10 Using where; Using index explain select * from t1 where a = 2 and b < 2 order by a desc,a,b desc,a,b; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 9 NULL 2 Using where; Using index +1 SIMPLE t1 range a a 9 NULL 4 Using where; Using index select * from t1 where a = 1 order by b desc; a b c 1 3 b +1 3 b 1 1 b 1 1 b +1 1 b +1 1 b +1 1 NULL 1 1 NULL 1 NULL b +1 NULL b +1 NULL NULL 1 NULL NULL SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR alter table t1 modify b int not null, modify c varchar(10) not null; @@ -377,91 +404,146 @@ Warning 1265 Data truncated for column 'b' at row 1 Warning 1265 Data truncated for column 'c' at row 1 Warning 1265 Data truncated for column 'b' at row 2 Warning 1265 Data truncated for column 'c' at row 3 +Warning 1265 Data truncated for column 'b' at row 12 +Warning 1265 Data truncated for column 'c' at row 12 +Warning 1265 Data truncated for column 'b' at row 13 +Warning 1265 Data truncated for column 'c' at row 14 explain select * from t1 order by a, b, c; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL a 20 NULL 11 Using index +1 SIMPLE t1 index NULL a 20 NULL 22 Using index select * from t1 order by a, b, c; a b c 1 0 +1 0 +1 0 b 1 0 b 1 1 +1 1 +1 1 b +1 1 b 1 1 b 1 1 b 1 3 b +1 3 b +2 1 a 2 1 a 2 1 b +2 1 b 2 2 a +2 2 a +2 2 b 2 2 b 2 3 c +2 3 c explain select * from t1 order by a desc, b desc, c desc; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL a 20 NULL 11 Using index +1 SIMPLE t1 index NULL a 20 NULL 22 Using index select * from t1 order by a desc, b desc, c desc; a b c 2 3 c +2 3 c +2 2 b 2 2 b 2 2 a +2 2 a +2 1 b 2 1 b 2 1 a +2 1 a +1 3 b 1 3 b 1 1 b 1 1 b +1 1 b +1 1 b +1 1 1 1 1 0 b +1 0 b +1 0 1 0 explain select * from t1 where (a = 1 and b = 1 and c = 'b') or (a > 2) order by a desc; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 20 NULL 3 Using where; Using index +1 SIMPLE t1 range a a 20 NULL 5 Using where; Using index select * from t1 where (a = 1 and b = 1 and c = 'b') or (a > 2) order by a desc; a b c 1 1 b 1 1 b +1 1 b +1 1 b explain select * from t1 where a < 2 and b <= 1 order by a desc, b desc; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 4 NULL 6 Using where; Using index +1 SIMPLE t1 range a a 4 NULL 12 Using where; Using index select * from t1 where a < 2 and b <= 1 order by a desc, b desc; a b c 1 1 b 1 1 b +1 1 b +1 1 b 1 1 +1 1 +1 0 b 1 0 b 1 0 +1 0 select count(*) from t1 where a < 5 and b > 0; count(*) -9 +18 select * from t1 where a < 5 and b > 0 order by a desc,b desc; a b c 2 3 c +2 3 c +2 2 b 2 2 b 2 2 a +2 2 a 2 1 b +2 1 b +2 1 a 2 1 a 1 3 b +1 3 b +1 1 b +1 1 b 1 1 b 1 1 b 1 1 +1 1 explain select * from t1 where a between 1 and 3 and b <= 1 order by a desc, b desc; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 8 NULL 10 Using where; Using index +1 SIMPLE t1 range a a 8 NULL 22 Using where; Using index select * from t1 where a between 1 and 3 and b <= 1 order by a desc, b desc; a b c 2 1 b +2 1 b 2 1 a +2 1 a +1 1 b +1 1 b 1 1 b 1 1 b 1 1 +1 1 +1 0 b 1 0 b 1 0 +1 0 explain select * from t1 where a between 0 and 1 order by a desc, b desc; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 4 NULL 5 Using where; Using index +1 SIMPLE t1 range a a 4 NULL 12 Using where; Using index select * from t1 where a between 0 and 1 order by a desc, b desc; a b c 1 3 b +1 3 b +1 1 b 1 1 b 1 1 b +1 1 b +1 1 1 1 1 0 b +1 0 b +1 0 1 0 drop table t1; CREATE TABLE t1 ( @@ -621,10 +703,10 @@ DS-MRR: use two IGNORE INDEX queries, otherwise we get cost races, because DS-MRR: records_in_range/read_time return the same numbers for all three indexes EXPLAIN SELECT * FROM t1 IGNORE INDEX (LongField, StringField) WHERE FieldKey > '2' ORDER BY LongVal; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range FieldKey FieldKey 38 NULL 4 Using index condition; Using filesort +1 SIMPLE t1 range FieldKey FieldKey 38 NULL 3 Using index condition; Using filesort EXPLAIN SELECT * FROM t1 IGNORE INDEX (FieldKey, LongField) WHERE FieldKey > '2' ORDER BY LongVal; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range StringField StringField 38 NULL 4 Using where; Using filesort +1 SIMPLE t1 range StringField StringField 38 NULL 3 Using where; Using filesort SELECT * FROM t1 WHERE FieldKey > '2' ORDER BY LongVal; FieldKey LongVal StringVal 3 1 2 @@ -632,7 +714,7 @@ FieldKey LongVal StringVal 3 3 3 EXPLAIN SELECT * FROM t1 WHERE FieldKey > '2' ORDER BY FieldKey, LongVal; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range FieldKey,LongField,StringField LongField 38 NULL 4 Using where +1 SIMPLE t1 range FieldKey,LongField,StringField LongField 38 NULL 3 Using where SELECT * FROM t1 WHERE FieldKey > '2' ORDER BY FieldKey, LongVal; FieldKey LongVal StringVal 3 1 2 @@ -663,7 +745,7 @@ a b 4 NULL explain select * from t1 where b=2 or b is null order by a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref_or_null b b 5 const 3 Using index condition; Using where; Using filesort +1 SIMPLE t1 ref_or_null b b 5 const 4 Using index condition; Using where; Using filesort select * from t1 where b=2 or b is null order by a; a b 3 NULL @@ -784,8 +866,6 @@ key `wnid` (`wnid`) ) engine=myisam default charset=latin1; insert into t1 (`sid`, `wnid`) values ('10100','01019000000'),('37986','01019000000'),('37987','01019010000'), -('39560','01019090000'),('37989','01019000000'),('37990','01019011000'), -('37991','01019011000'),('37992','01019019000'),('37993','01019030000'), ('37994','01019090000'),('475','02070000000'),('25253','02071100000'), ('25255','02071100000'),('25256','02071110000'),('25258','02071130000'), ('25259','02071190000'),('25260','02071200000'),('25261','02071210000'), @@ -800,18 +880,12 @@ insert into t1 (`sid`, `wnid`) values ('25295','02071491000'),('25296','02071491000'),('25297','02071499000'); explain select * from t1 where wnid like '0101%' order by wnid; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range wnid14,wnid wnid 13 NULL 10 Using where +1 SIMPLE t1 range wnid14,wnid wnid 13 NULL 4 Using where select * from t1 where wnid like '0101%' order by wnid; sid wnid 10100 01019000000 37986 01019000000 -37989 01019000000 37987 01019010000 -37990 01019011000 -37991 01019011000 -37992 01019019000 -37993 01019030000 -39560 01019090000 37994 01019090000 drop table t1; CREATE TABLE t1 (a int); @@ -2851,7 +2925,7 @@ explain select b, count(*) num_cnt from t1 where a > 9750 group by b order by num_cnt; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range idx1 idx1 5 NULL 502 Using where; Using index; Using temporary; Using filesort +1 SIMPLE t1 range idx1 idx1 5 NULL 503 Using where; Using index; Using temporary; Using filesort flush status; select b, count(*) num_cnt from t1 where a > 9750 group by b order by num_cnt; @@ -2870,7 +2944,7 @@ explain select b, count(*) num_cnt from t1 where a > 9750 group by b order by num_cnt limit 1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range idx1 idx1 5 NULL 502 Using where; Using index; Using temporary; Using filesort +1 SIMPLE t1 range idx1 idx1 5 NULL 503 Using where; Using index; Using temporary; Using filesort flush status; select b, count(*) num_cnt from t1 where a > 9750 group by b order by num_cnt limit 1; @@ -3034,15 +3108,17 @@ KEY id_234_date (id2,id3,id4,date) ) ENGINE=MyISAM DEFAULT CHARSET=latin1; # t2 has a "good" index declaration order INSERT INTO t1 (id2,id3,id4) VALUES (1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,0,1),(1,2,1),(1,3,1); +INSERT INTO t1 (id2,id3,id4) VALUES (1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,0,1),(1,2,1),(1,3,1); +INSERT INTO t2 (id2,id3,id4) VALUES (1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,0,1),(1,2,1),(1,3,1); INSERT INTO t2 (id2,id3,id4) VALUES (1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,0,1),(1,2,1),(1,3,1); # The following two must both use id_23_date and no "using filesort": EXPLAIN SELECT id1 FROM t1 WHERE id2=1 AND id3=1 ORDER BY date DESC LIMIT 0,4; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range id_234_date,id_23_date id_23_date 2 NULL 3 Using where +1 SIMPLE t1 range id_234_date,id_23_date id_23_date 2 NULL 8 Using where # See above query EXPLAIN SELECT id1 FROM t2 WHERE id2=1 AND id3=1 ORDER BY date DESC LIMIT 0,4; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ref id_23_date,id_234_date id_23_date 2 const,const 3 Using where +1 SIMPLE t2 ref id_23_date,id_234_date id_23_date 2 const,const 8 Using where drop table t1,t2; # # MDEV-8989: ORDER BY optimizer ignores equality propagation @@ -3246,9 +3322,9 @@ WHERE books.library_id = 8663 AND books.scheduled_for_removal=0 ) ORDER BY wings.id; id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 1 100.00 Using temporary; Using filesort +1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 2 100.00 Using temporary; Using filesort 1 PRIMARY wings eq_ref PRIMARY PRIMARY 4 test.books.wings_id 1 100.00 -2 MATERIALIZED books ref library_idx library_idx 4 const 1 100.00 Using where +2 MATERIALIZED books ref library_idx library_idx 4 const 2 100.00 Using where Warnings: Note 1003 select `test`.`wings`.`id` AS `wing_id`,`test`.`wings`.`department_id` AS `department_id` from `test`.`wings` semi join (`test`.`books`) where `test`.`books`.`library_id` = 8663 and `test`.`books`.`scheduled_for_removal` = 0 and `test`.`wings`.`id` = `test`.`books`.`wings_id` order by `test`.`wings`.`id` set optimizer_switch= @save_optimizer_switch; diff --git a/mysql-test/main/order_by.test b/mysql-test/main/order_by.test index b047a31c863..e0c00aee583 100644 --- a/mysql-test/main/order_by.test +++ b/mysql-test/main/order_by.test @@ -246,6 +246,7 @@ drop table t1; create table t1 (a int not null, b int, c varchar(10), key (a, b, c)); insert into t1 values (1, NULL, NULL), (1, NULL, 'b'), (1, 1, NULL), (1, 1, 'b'), (1, 1, 'b'), (2, 1, 'a'), (2, 1, 'b'), (2, 2, 'a'), (2, 2, 'b'), (2, 3, 'c'),(1,3,'b'); +insert into t1 select * from t1; explain select * from t1 where (a = 1 and b is null and c = 'b') or (a > 2) order by a desc; select * from t1 where (a = 1 and b is null and c = 'b') or (a > 2) order by a desc; @@ -551,8 +552,6 @@ create table t1 ( insert into t1 (`sid`, `wnid`) values ('10100','01019000000'),('37986','01019000000'),('37987','01019010000'), -('39560','01019090000'),('37989','01019000000'),('37990','01019011000'), -('37991','01019011000'),('37992','01019019000'),('37993','01019030000'), ('37994','01019090000'),('475','02070000000'),('25253','02071100000'), ('25255','02071100000'),('25256','02071110000'),('25258','02071130000'), ('25259','02071190000'),('25260','02071200000'),('25261','02071210000'), @@ -2039,6 +2038,8 @@ CREATE TABLE t2 ( --echo # t2 has a "good" index declaration order INSERT INTO t1 (id2,id3,id4) VALUES (1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,0,1),(1,2,1),(1,3,1); +INSERT INTO t1 (id2,id3,id4) VALUES (1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,0,1),(1,2,1),(1,3,1); +INSERT INTO t2 (id2,id3,id4) VALUES (1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,0,1),(1,2,1),(1,3,1); INSERT INTO t2 (id2,id3,id4) VALUES (1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,0,1),(1,2,1),(1,3,1); --echo # The following two must both use id_23_date and no "using filesort": diff --git a/mysql-test/main/partition.result b/mysql-test/main/partition.result index fd76da09d78..680b0a953d1 100644 --- a/mysql-test/main/partition.result +++ b/mysql-test/main/partition.result @@ -2357,7 +2357,7 @@ b c EXPLAIN SELECT b, c FROM t1 WHERE b = 1 GROUP BY b, c; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range bc bc 10 NULL 7 Using where; Using index for group-by +1 SIMPLE t1 range bc bc 10 NULL 8 Using where; Using index for group-by DROP TABLE t1; # # Bug #45807: crash accessing partitioned table and sql_mode diff --git a/mysql-test/main/partition_innodb.result b/mysql-test/main/partition_innodb.result index d27abc07984..46353c63ce3 100644 --- a/mysql-test/main/partition_innodb.result +++ b/mysql-test/main/partition_innodb.result @@ -1,6 +1,11 @@ call mtr.add_suppression("Deadlock found when trying to get lock; try restarting transaction"); set global default_storage_engine='innodb'; set session default_storage_engine='innodb'; +set @innodb_stats_persistent_save= @@innodb_stats_persistent; +set @innodb_stats_persistent_sample_pages_save= +@@innodb_stats_persistent_sample_pages; +set global innodb_stats_persistent= 1; +set global innodb_stats_persistent_sample_pages=100; drop table if exists t1, t2; # # Bug#13694811: THE OPTIMIZER WRONGLY USES THE FIRST @@ -24,12 +29,15 @@ INSERT INTO t1 VALUES (0, 'Mod Zero'), (1, 'One'), (2, 'Two'), (3, 'Three'), (20, '0'), (21, '1'), (22, '2'), (23, '3'), (4, '4'), (5, '5'), (6, '6'), (7, '7'), (8, '8'), (9, '9'); INSERT INTO t1 SELECT a + 30, b FROM t1 WHERE a >= 0; +INSERT INTO t1 SELECT a + 60, b FROM t1 WHERE a >= 0; +INSERT INTO t1 SELECT a + 120, b FROM t1 WHERE a >= 0; +INSERT INTO t1 SELECT a + 240, b FROM t1 WHERE a >= 0; ANALYZE TABLE t1; Table Op Msg_type Msg_text test.t1 analyze status OK EXPLAIN SELECT b FROM t1 WHERE b between 'L' and 'N' AND a > -100; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY,b b 67 NULL 34 Using where; Using index +1 SIMPLE t1 range PRIMARY,b b 67 NULL 90 Using where; Using index DROP TABLE t1; # # Bug#13007154: Crash in keys_to_use_for_scanning with ORDER BY @@ -663,7 +671,7 @@ EXPLAIN SELECT * FROM t1 WHERE col1 = 1 AND col2 = 2 AND col3 BETWEEN '2013-03-08 00:00:00' AND '2013-03-12 12:00:00' GROUP BY 1, 2, 3; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY,col1,col2 PRIMARY 5 NULL # Using where; Using filesort +1 SIMPLE t1 ref PRIMARY,col1,col2 col1 8 const # Using where; Using filesort SELECT * FROM t1 USE INDEX () WHERE col1 = 1 AND col2 = 2 AND col3 BETWEEN '2013-03-08 00:00:00' AND '2013-03-12 12:00:00' GROUP BY 1, 2, 3; @@ -696,9 +704,11 @@ insert into t1 select 10+A.a + 10*B.a + 100*C.a + 1000*D.a, 10+A.a + 10*B.a + 100*C.a + 1000*D.a, 2000 + A.a + 10*B.a + 100*C.a + 1000*D.a from t2 A, t2 B, t2 C ,t2 D; +set statement optimizer_switch='rowid_filter=off' for explain select * from t1 where a=1 and b=2 and pk between 1 and 999999 ; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index_merge PRIMARY,a,b b,a 4,4 NULL # Using intersect(b,a); Using where; Using index +set statement optimizer_switch='rowid_filter=off' for create temporary table t3 as select * from t1 where a=1 and b=2 and pk between 1 and 999 ; select count(*) from t3; @@ -925,3 +935,6 @@ test_jfg test_jfg11 test_jfg test_jfg12#P#p1000 test_jfg test_jfg12#P#pmax DROP DATABASE test_jfg; +set global innodb_stats_persistent= @innodb_stats_persistent_save; +set global innodb_stats_persistent_sample_pages= +@innodb_stats_persistent_sample_pages_save; diff --git a/mysql-test/main/partition_innodb.test b/mysql-test/main/partition_innodb.test index 49430414913..a8bbb7ceed5 100644 --- a/mysql-test/main/partition_innodb.test +++ b/mysql-test/main/partition_innodb.test @@ -7,6 +7,13 @@ call mtr.add_suppression("Deadlock found when trying to get lock; try restarting set global default_storage_engine='innodb'; set session default_storage_engine='innodb'; +set @innodb_stats_persistent_save= @@innodb_stats_persistent; +set @innodb_stats_persistent_sample_pages_save= + @@innodb_stats_persistent_sample_pages; + +set global innodb_stats_persistent= 1; +set global innodb_stats_persistent_sample_pages=100; + --disable_warnings drop table if exists t1, t2; --enable_warnings @@ -38,6 +45,9 @@ INSERT INTO t1 VALUES (0, 'Mod Zero'), (1, 'One'), (2, 'Two'), (3, 'Three'), (20, '0'), (21, '1'), (22, '2'), (23, '3'), (4, '4'), (5, '5'), (6, '6'), (7, '7'), (8, '8'), (9, '9'); INSERT INTO t1 SELECT a + 30, b FROM t1 WHERE a >= 0; +INSERT INTO t1 SELECT a + 60, b FROM t1 WHERE a >= 0; +INSERT INTO t1 SELECT a + 120, b FROM t1 WHERE a >= 0; +INSERT INTO t1 SELECT a + 240, b FROM t1 WHERE a >= 0; ANALYZE TABLE t1; EXPLAIN SELECT b FROM t1 WHERE b between 'L' and 'N' AND a > -100; DROP TABLE t1; @@ -772,8 +782,10 @@ insert into t1 select 10+A.a + 10*B.a + 100*C.a + 1000*D.a, # This should show index_merge, using intersect --replace_column 9 # +set statement optimizer_switch='rowid_filter=off' for explain select * from t1 where a=1 and b=2 and pk between 1 and 999999 ; # 794 rows in output +set statement optimizer_switch='rowid_filter=off' for create temporary table t3 as select * from t1 where a=1 and b=2 and pk between 1 and 999 ; select count(*) from t3; @@ -1015,3 +1027,7 @@ SELECT database_name, table_name FROM mysql.innodb_table_stats WHERE database_name = 'test_jfg'; DROP DATABASE test_jfg; + +set global innodb_stats_persistent= @innodb_stats_persistent_save; +set global innodb_stats_persistent_sample_pages= + @innodb_stats_persistent_sample_pages_save; diff --git a/mysql-test/main/partition_pruning.result b/mysql-test/main/partition_pruning.result index 00bd24101d6..14e076b0e68 100644 --- a/mysql-test/main/partition_pruning.result +++ b/mysql-test/main/partition_pruning.result @@ -18,7 +18,7 @@ id select_type table partitions type possible_keys key key_len ref rows Extra # # # # # # # # # 3 # EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 7; id select_type table partitions type possible_keys key key_len ref rows Extra -# # # # # # # # # 9 # +# # # # # # # # # 10 # EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 1; id select_type table partitions type possible_keys key key_len ref rows Extra # # # # # # # # # 3 # @@ -105,7 +105,7 @@ a 6 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 7; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0,p1,p2,p3,p4,p5,max range PRIMARY PRIMARY 4 NULL 9 Using where; Using index +1 SIMPLE t1 p0,p1,p2,p3,p4,p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index SELECT * FROM t1 WHERE a <= 1; a -1 @@ -168,7 +168,7 @@ a 6 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 6; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0,p1,p2,p3,p4,p5,max range PRIMARY PRIMARY 4 NULL 9 Using where; Using index +1 SIMPLE t1 p0,p1,p2,p3,p4,p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index SELECT * FROM t1 WHERE a <= 7; a -1 @@ -182,7 +182,7 @@ a 7 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 7; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0,p1,p2,p3,p4,p5,max range PRIMARY PRIMARY 4 NULL 9 Using where; Using index +1 SIMPLE t1 p0,p1,p2,p3,p4,p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index SELECT * FROM t1 WHERE a = 1; a 1 @@ -424,7 +424,7 @@ a 5 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 6; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0,p1,p2,p3,p4,max range PRIMARY PRIMARY 4 NULL 8 Using where; Using index +1 SIMPLE t1 p0,p1,p2,p3,p4,max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index SELECT * FROM t1 WHERE a <= 1; a -1 @@ -474,7 +474,7 @@ a 5 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 5; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0,p1,p2,p3,p4,max range PRIMARY PRIMARY 4 NULL 8 Using where; Using index +1 SIMPLE t1 p0,p1,p2,p3,p4,max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index SELECT * FROM t1 WHERE a <= 6; a -1 @@ -487,7 +487,7 @@ a 6 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 6; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0,p1,p2,p3,p4,max range PRIMARY PRIMARY 4 NULL 8 Using where; Using index +1 SIMPLE t1 p0,p1,p2,p3,p4,max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index SELECT * FROM t1 WHERE a = 1; a 1 @@ -744,41 +744,41 @@ a 1001-01-01 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 range a a 4 NULL 3 Using where; Using index +1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 index a a 4 NULL 6 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 range a a 4 NULL 3 Using where; Using index +1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 index a a 4 NULL 6 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 range a a 4 NULL 4 Using where; Using index +1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 index a a 4 NULL 5 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pNULL,p2001-01-01 range a a 4 NULL 3 Using where; Using index +1 SIMPLE t1 pNULL,p2001-01-01 index a a 4 NULL 4 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 p1001-01-01 system a NULL NULL NULL 1 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 range a a 4 NULL 3 Using where; Using index +1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 index a a 4 NULL 6 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 range a a 4 NULL 3 Using where; Using index +1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 index a a 4 NULL 6 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 range a a 4 NULL 4 Using where; Using index +1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 index a a 4 NULL 5 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 range a a 4 NULL 4 Using where; Using index +1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 index a a 4 NULL 5 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 pNULL ref a a 4 const 1 Using index # Disabling warnings for the invalid date EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1999-02-31'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01,p2001-01-01 range a a 4 NULL 5 Using where; Using index +1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01,p2001-01-01 index a a 4 NULL 7 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= '1999-02-31'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01,p2001-01-01 range a a 4 NULL 5 Using where; Using index +1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01,p2001-01-01 index a a 4 NULL 7 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1999-02-31'; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 pNULL,p2001-01-01 index a a 4 NULL 4 Using where; Using index @@ -790,16 +790,16 @@ id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 pNULL ref a a 4 const 1 Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1002-00-00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01,p2001-01-01 range a a 4 NULL 5 Using where; Using index +1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01,p2001-01-01 index a a 4 NULL 7 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 range a a 4 NULL 3 Using where; Using index +1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 index a a 4 NULL 6 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0001-01-02' AND '1002-00-00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 range a a 4 NULL 3 Using where; Using index +1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 index a a 4 NULL 5 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0001-01-01' AND '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 range a a 4 NULL 3 Using where; Using index +1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 index a a 4 NULL 6 Using where; Using index # test without index ALTER TABLE t1 DROP KEY a; SELECT * FROM t1 WHERE a < '1001-01-01'; @@ -1073,41 +1073,41 @@ a 1001-01-01 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 range a a 4 NULL 3 Using where; Using index +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 index a a 4 NULL 5 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 4 Using where; Using index +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 index a a 4 NULL 6 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 range a a 4 NULL 4 Using where; Using index +1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 index a a 4 NULL 5 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p2001-01-01,pNULL range a a 4 NULL 3 Using where; Using index +1 SIMPLE t1 p2001-01-01,pNULL index a a 4 NULL 4 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 p1001-01-01 system a NULL NULL NULL 1 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 range a a 4 NULL 3 Using where; Using index +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 index a a 4 NULL 5 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 range a a 4 NULL 3 Using where; Using index +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 index a a 4 NULL 5 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 range a a 4 NULL 4 Using where; Using index +1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 index a a 4 NULL 5 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 range a a 4 NULL 4 Using where; Using index +1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 index a a 4 NULL 5 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 pNULL ref a a 4 const 1 Using index # Disabling warnings for the invalid date EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1999-02-31'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 5 Using where; Using index +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 index a a 4 NULL 6 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= '1999-02-31'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 5 Using where; Using index +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 index a a 4 NULL 6 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1999-02-31'; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 p2001-01-01,pNULL index a a 4 NULL 4 Using where; Using index @@ -1119,16 +1119,16 @@ id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 pNULL ref a a 4 const 1 Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1002-00-00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 5 Using where; Using index +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 index a a 4 NULL 6 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 4 Using where; Using index +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 index a a 4 NULL 6 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0001-01-02' AND '1002-00-00'; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 pNULL,p1001-01-01 index a a 4 NULL 4 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0001-01-01' AND '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0001-01-01,pNULL,p1001-01-01 range a a 4 NULL 3 Using where; Using index +1 SIMPLE t1 p0001-01-01,pNULL,p1001-01-01 index a a 4 NULL 5 Using where; Using index # test without index ALTER TABLE t1 DROP KEY a; SELECT * FROM t1 WHERE a < '1001-01-01'; @@ -1402,41 +1402,41 @@ a 1001-01-01 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 range a a 4 NULL 3 Using where; Using index +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 index a a 4 NULL 5 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 4 Using where; Using index +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 index a a 4 NULL 6 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 range a a 4 NULL 4 Using where; Using index +1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 index a a 4 NULL 5 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p2001-01-01,pNULL range a a 4 NULL 3 Using where; Using index +1 SIMPLE t1 p2001-01-01,pNULL index a a 4 NULL 4 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 p1001-01-01 system a NULL NULL NULL 1 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 range a a 4 NULL 3 Using where; Using index +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 index a a 4 NULL 5 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 range a a 4 NULL 3 Using where; Using index +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 index a a 4 NULL 5 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 range a a 4 NULL 4 Using where; Using index +1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 index a a 4 NULL 5 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 range a a 4 NULL 4 Using where; Using index +1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 index a a 4 NULL 5 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 pNULL ref a a 4 const 1 Using index # Disabling warnings for the invalid date EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1999-02-31'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 5 Using where; Using index +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 index a a 4 NULL 6 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= '1999-02-31'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 5 Using where; Using index +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 index a a 4 NULL 6 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1999-02-31'; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 p2001-01-01,pNULL index a a 4 NULL 4 Using where; Using index @@ -1448,16 +1448,16 @@ id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 pNULL ref a a 4 const 1 Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1002-00-00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 5 Using where; Using index +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 index a a 4 NULL 6 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 4 Using where; Using index +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 index a a 4 NULL 6 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0001-01-02' AND '1002-00-00'; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 pNULL,p1001-01-01 index a a 4 NULL 4 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0001-01-01' AND '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0001-01-01,pNULL,p1001-01-01 range a a 4 NULL 3 Using where; Using index +1 SIMPLE t1 p0001-01-01,pNULL,p1001-01-01 index a a 4 NULL 5 Using where; Using index # test without index ALTER TABLE t1 DROP KEY a; SELECT * FROM t1 WHERE a < '1001-01-01'; @@ -2670,12 +2670,14 @@ create table t1 (a int not null, b int not null, key(a), key(b)) partition by hash(a) partitions 4; insert into t1 values (1,1),(2,2),(3,3),(4,4); insert into t1 values (5,5),(6,6),(7,7),(8,8); +insert into t1 values (9,9),(10,10),(11,11),(12,12); +insert into t1 values (13,13),(14,14),(15,15),(16,16); explain partitions select * from t1 X, t1 Y where X.b = Y.b and (X.a=1 or X.a=2) and (Y.a=2 or Y.a=3); id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE X p1,p2 range a,b a 4 NULL 4 Using where -1 SIMPLE Y p2,p3 ref a,b b 4 test.X.b 2 Using where +1 SIMPLE Y p2,p3 ref|filter a,b b|a 4|4 test.X.b 2 (50%) Using where; Using filter explain partitions select * from t1 X, t1 Y where X.a = Y.a and (X.a=1 or X.a=2); id select_type table partitions type possible_keys key key_len ref rows Extra @@ -2867,15 +2869,15 @@ id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t2 p0,p1,p2 ALL NULL NULL NULL NULL 510 Using where explain partitions select * from t2 where b = 4; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t2 p0,p1,p2,p3,p4 ref b b 5 const 76 +1 SIMPLE t2 p0,p1,p2,p3,p4 ref b b 5 const 77 explain extended select * from t2 where b = 6; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 ref b b 5 const 76 100.00 +1 SIMPLE t2 ref b b 5 const 77 100.00 Warnings: Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where `test`.`t2`.`b` = 6 explain partitions select * from t2 where b = 6; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t2 p0,p1,p2,p3,p4 ref b b 5 const 76 +1 SIMPLE t2 p0,p1,p2,p3,p4 ref b b 5 const 77 explain extended select * from t2 where b in (1,3,5); id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 ALL b NULL NULL NULL 910 40.66 Using where @@ -2886,7 +2888,7 @@ id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t2 p0,p1,p2,p3,p4 ALL b NULL NULL NULL 910 Using where explain extended select * from t2 where b in (2,4,6); id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 ALL b NULL NULL NULL 910 25.05 Using where +1 SIMPLE t2 ALL b NULL NULL NULL 910 25.38 Using where Warnings: Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where `test`.`t2`.`b` in (2,4,6) explain partitions select * from t2 where b in (2,4,6); @@ -2894,7 +2896,7 @@ id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t2 p0,p1,p2,p3,p4 ALL b NULL NULL NULL 910 Using where explain extended select * from t2 where b in (7,8,9); id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 ALL b NULL NULL NULL 910 36.70 Using where +1 SIMPLE t2 ALL b NULL NULL NULL 910 36.81 Using where Warnings: Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where `test`.`t2`.`b` in (7,8,9) explain partitions select * from t2 where b in (7,8,9); @@ -2902,7 +2904,7 @@ id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t2 p0,p1,p2,p3,p4 ALL b NULL NULL NULL 910 Using where explain extended select * from t2 where b > 5; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 ALL b NULL NULL NULL 910 44.84 Using where +1 SIMPLE t2 ALL b NULL NULL NULL 910 44.62 Using where Warnings: Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where `test`.`t2`.`b` > 5 explain partitions select * from t2 where b > 5; @@ -2910,7 +2912,7 @@ id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t2 p0,p1,p2,p3,p4 ALL b NULL NULL NULL 910 Using where explain extended select * from t2 where b > 5 and b < 8; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 ALL b NULL NULL NULL 910 22.09 Using where +1 SIMPLE t2 ALL b NULL NULL NULL 910 22.20 Using where Warnings: Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where `test`.`t2`.`b` > 5 and `test`.`t2`.`b` < 8 explain partitions select * from t2 where b > 5 and b < 8; @@ -2918,15 +2920,15 @@ id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t2 p0,p1,p2,p3,p4 ALL b NULL NULL NULL 910 Using where explain extended select * from t2 where b > 5 and b < 7; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 range b b 5 NULL 76 100.00 Using where +1 SIMPLE t2 range b b 5 NULL 77 100.00 Using where Warnings: Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where `test`.`t2`.`b` > 5 and `test`.`t2`.`b` < 7 explain partitions select * from t2 where b > 5 and b < 7; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t2 p0,p1,p2,p3,p4 range b b 5 NULL 76 Using where +1 SIMPLE t2 p0,p1,p2,p3,p4 range b b 5 NULL 77 Using where explain extended select * from t2 where b > 0 and b < 5; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 ALL b NULL NULL NULL 910 41.65 Using where +1 SIMPLE t2 ALL b NULL NULL NULL 910 41.87 Using where Warnings: Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where `test`.`t2`.`b` > 0 and `test`.`t2`.`b` < 5 explain partitions select * from t2 where b > 0 and b < 5; @@ -3376,16 +3378,16 @@ id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 p1 const PRIMARY PRIMARY 8 const,const 1 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 1 AND c2 >= 1; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p1,p2 range PRIMARY PRIMARY 8 NULL 2 Using where +1 SIMPLE t1 p1,p2 range PRIMARY PRIMARY 8 NULL 3 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 1 AND c2 > 1; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 p1,p2 range PRIMARY PRIMARY 8 NULL 2 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 1 AND c2 < 3; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p1 range PRIMARY PRIMARY 8 NULL 1 Using where +1 SIMPLE t1 p1 range PRIMARY PRIMARY 8 NULL 2 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 1 AND c2 <= 3; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p1,p2 range PRIMARY PRIMARY 8 NULL 2 Using where +1 SIMPLE t1 p1,p2 range PRIMARY PRIMARY 8 NULL 3 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 <= 3; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 p1,p2 range PRIMARY PRIMARY 8 NULL 2 Using where @@ -3394,7 +3396,7 @@ id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 p2 const PRIMARY PRIMARY 8 const,const 1 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 >= 3; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p2 range PRIMARY PRIMARY 8 NULL 1 Using where +1 SIMPLE t1 p2 range PRIMARY PRIMARY 8 NULL 2 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 > 3; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 p2 range PRIMARY PRIMARY 8 NULL 1 Using where @@ -3403,7 +3405,7 @@ id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 p1,p2 range PRIMARY PRIMARY 8 NULL 2 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 <= 4; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p1,p2 range PRIMARY PRIMARY 8 NULL 2 Using where +1 SIMPLE t1 p1,p2 range PRIMARY PRIMARY 8 NULL 3 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 = 4; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 p2 const PRIMARY PRIMARY 8 const,const 1 @@ -3463,7 +3465,7 @@ select * from t1 where company_id = 1000 and dept_id in (select dept_id from t2 where COMPANY_ID = 1000); id select_type table partitions type possible_keys key key_len ref rows Extra -1 PRIMARY t2 p_1000 ref PRIMARY PRIMARY 8 const 2 Using index +1 PRIMARY t2 p_1000 ref PRIMARY PRIMARY 8 const 3 Using index 1 PRIMARY t1 p_1000 ALL PRIMARY NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join) drop table t1,t2; # diff --git a/mysql-test/main/partition_pruning.test b/mysql-test/main/partition_pruning.test index 2879b0eae6c..ecf794ca214 100644 --- a/mysql-test/main/partition_pruning.test +++ b/mysql-test/main/partition_pruning.test @@ -892,6 +892,8 @@ create table t1 (a int not null, b int not null, key(a), key(b)) partition by hash(a) partitions 4; insert into t1 values (1,1),(2,2),(3,3),(4,4); insert into t1 values (5,5),(6,6),(7,7),(8,8); +insert into t1 values (9,9),(10,10),(11,11),(12,12); +insert into t1 values (13,13),(14,14),(15,15),(16,16); explain partitions select * from t1 X, t1 Y diff --git a/mysql-test/main/partition_range.result b/mysql-test/main/partition_range.result index 7ae029d488c..2a79e01566d 100644 --- a/mysql-test/main/partition_range.result +++ b/mysql-test/main/partition_range.result @@ -958,13 +958,17 @@ INSERT INTO t1 SELECT a + 10, b + 10 FROM t1; INSERT INTO t1 SELECT a + 20, b + 20 FROM t1; INSERT INTO t1 SELECT a + 40, b + 40 FROM t1; INSERT INTO t2 SELECT * FROM t1; +ANALYZE TABLE t1,t2; +Table Op Msg_type Msg_text +test.t1 analyze status OK +test.t2 analyze status Table is already up to date # plans should be identical EXPLAIN SELECT a, MAX(b) FROM t1 WHERE a IN (10,100) GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range a a 5 NULL 2 Using where; Using index EXPLAIN SELECT a, MAX(b) FROM t2 WHERE a IN (10,100) GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range a a 5 NULL 2 Using where; Using index for group-by +1 SIMPLE t2 range a a 5 NULL 2 Using where; Using index FLUSH status; SELECT a, MAX(b) FROM t1 WHERE a IN (10, 100) GROUP BY a; a MAX(b) @@ -980,5 +984,5 @@ a MAX(b) # Should be no more than 4 reads. SHOW status LIKE 'handler_read_key'; Variable_name Value -Handler_read_key 4 +Handler_read_key 2 DROP TABLE t1, t2; diff --git a/mysql-test/main/partition_range.test b/mysql-test/main/partition_range.test index 3ff03248d88..7f637f83ed9 100644 --- a/mysql-test/main/partition_range.test +++ b/mysql-test/main/partition_range.test @@ -957,6 +957,8 @@ INSERT INTO t1 SELECT a + 40, b + 40 FROM t1; INSERT INTO t2 SELECT * FROM t1; +ANALYZE TABLE t1,t2; + --echo # plans should be identical EXPLAIN SELECT a, MAX(b) FROM t1 WHERE a IN (10,100) GROUP BY a; EXPLAIN SELECT a, MAX(b) FROM t2 WHERE a IN (10,100) GROUP BY a; diff --git a/mysql-test/main/preload.result b/mysql-test/main/preload.result index 7ed0c62f33a..529c7ac2690 100644 --- a/mysql-test/main/preload.result +++ b/mysql-test/main/preload.result @@ -55,14 +55,14 @@ count(*) 4181 show status like "key_read%"; Variable_name Value -Key_read_requests 294 +Key_read_requests 297 Key_reads 60 select count(*) from t1 where b = 'test1'; count(*) 4181 show status like "key_read%"; Variable_name Value -Key_read_requests 588 +Key_read_requests 594 Key_reads 60 flush tables; flush status; @@ -81,7 +81,7 @@ count(*) 4181 show status like "key_read%"; Variable_name Value -Key_read_requests 1068 +Key_read_requests 1071 Key_reads 774 flush tables; flush status; @@ -105,7 +105,7 @@ count(*) 4181 show status like "key_read%"; Variable_name Value -Key_read_requests 311 +Key_read_requests 314 Key_reads 75 flush tables; flush status; @@ -133,7 +133,7 @@ count(*) 2584 show status like "key_read%"; Variable_name Value -Key_read_requests 1266 +Key_read_requests 1272 Key_reads 821 flush tables; flush status; diff --git a/mysql-test/main/ps_1general.result b/mysql-test/main/ps_1general.result index 035372a1359..2ef5571cdca 100644 --- a/mysql-test/main/ps_1general.result +++ b/mysql-test/main/ps_1general.result @@ -451,7 +451,7 @@ def possible_keys 253 4_OR_8_K 0 Y 0 39 8 def key 253 64 0 Y 0 39 8 def key_len 253 4_OR_8_K 0 Y 0 39 8 def ref 253 2048 0 Y 0 39 8 -def rows 8 10 1 Y 32928 0 63 +def rows 253 64 1 Y 0 39 8 def Extra 253 255 14 N 1 39 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using filesort @@ -462,15 +462,15 @@ Catalog Database Table Table_alias Column Column_alias Type Length Max length Is def id 8 3 1 Y 32928 0 63 def select_type 253 19 6 N 1 39 8 def table 253 64 2 Y 0 39 8 -def type 253 10 5 Y 0 39 8 +def type 253 10 3 Y 0 39 8 def possible_keys 253 4_OR_8_K 7 Y 0 39 8 -def key 253 64 7 Y 0 39 8 -def key_len 253 4_OR_8_K 1 Y 0 39 8 +def key 253 64 0 Y 0 39 8 +def key_len 253 4_OR_8_K 0 Y 0 39 8 def ref 253 2048 0 Y 0 39 8 -def rows 8 10 1 Y 32928 0 63 -def Extra 253 255 37 N 1 39 8 +def rows 253 64 1 Y 0 39 8 +def Extra 253 255 27 N 1 39 8 id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 Using index condition; Using filesort +1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 4 Using where; Using filesort drop table if exists t2; create table t2 (id smallint, name varchar(20)) ; prepare stmt1 from ' insert into t2 values(?, ?) ' ; diff --git a/mysql-test/main/ps_2myisam.result b/mysql-test/main/ps_2myisam.result index 3906875da92..c85abaad051 100644 --- a/mysql-test/main/ps_2myisam.result +++ b/mysql-test/main/ps_2myisam.result @@ -1161,7 +1161,7 @@ def possible_keys 253 4_OR_8_K 0 Y 0 39 8 def key 253 64 0 Y 0 39 8 def key_len 253 4_OR_8_K 0 Y 0 39 8 def ref 253 2048 0 Y 0 39 8 -def rows 8 10 1 Y 32928 0 63 +def rows 253 64 1 Y 0 39 8 def Extra 253 255 0 N 1 39 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t9 ALL NULL NULL NULL NULL 2 diff --git a/mysql-test/main/ps_3innodb.result b/mysql-test/main/ps_3innodb.result index 9f5c8956dd8..53f736f41a3 100644 --- a/mysql-test/main/ps_3innodb.result +++ b/mysql-test/main/ps_3innodb.result @@ -1161,7 +1161,7 @@ def possible_keys 253 4_OR_8_K 0 Y 0 39 8 def key 253 64 0 Y 0 39 8 def key_len 253 4_OR_8_K 0 Y 0 39 8 def ref 253 2048 0 Y 0 39 8 -def rows 8 10 1 Y 32928 0 63 +def rows 253 64 1 Y 0 39 8 def Extra 253 255 0 N 1 39 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t9 ALL NULL NULL NULL NULL 2 diff --git a/mysql-test/main/ps_4heap.result b/mysql-test/main/ps_4heap.result index 46b4d9c58e5..0cf1ed13cba 100644 --- a/mysql-test/main/ps_4heap.result +++ b/mysql-test/main/ps_4heap.result @@ -1162,7 +1162,7 @@ def possible_keys 253 4_OR_8_K 0 Y 0 39 8 def key 253 64 0 Y 0 39 8 def key_len 253 4_OR_8_K 0 Y 0 39 8 def ref 253 2048 0 Y 0 39 8 -def rows 8 10 1 Y 32928 0 63 +def rows 253 64 1 Y 0 39 8 def Extra 253 255 0 N 1 39 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t9 ALL NULL NULL NULL NULL 2 diff --git a/mysql-test/main/ps_5merge.result b/mysql-test/main/ps_5merge.result index cc2f0f88b2a..49155394e2a 100644 --- a/mysql-test/main/ps_5merge.result +++ b/mysql-test/main/ps_5merge.result @@ -1205,7 +1205,7 @@ def possible_keys 253 4_OR_8_K 0 Y 0 39 8 def key 253 64 0 Y 0 39 8 def key_len 253 4_OR_8_K 0 Y 0 39 8 def ref 253 2048 0 Y 0 39 8 -def rows 8 10 1 Y 32928 0 63 +def rows 253 64 1 Y 0 39 8 def Extra 253 255 0 N 1 39 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t9 ALL NULL NULL NULL NULL 2 @@ -4573,7 +4573,7 @@ def possible_keys 253 4_OR_8_K 0 Y 0 39 8 def key 253 64 0 Y 0 39 8 def key_len 253 4_OR_8_K 0 Y 0 39 8 def ref 253 2048 0 Y 0 39 8 -def rows 8 10 1 Y 32928 0 63 +def rows 253 64 1 Y 0 39 8 def Extra 253 255 0 N 1 39 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t9 ALL NULL NULL NULL NULL 2 diff --git a/mysql-test/main/range.result b/mysql-test/main/range.result index 50de308045b..83237a9d2d4 100644 --- a/mysql-test/main/range.result +++ b/mysql-test/main/range.result @@ -1,3 +1,8 @@ +set @innodb_stats_persistent_save= @@innodb_stats_persistent; +set @innodb_stats_persistent_sample_pages_save= +@@innodb_stats_persistent_sample_pages; +set global innodb_stats_persistent= 1; +set global innodb_stats_persistent_sample_pages=100; CREATE TABLE t1 ( event_date date DEFAULT '0000-00-00' NOT NULL, type int(11) DEFAULT '0' NOT NULL, @@ -244,7 +249,7 @@ id select_type table type possible_keys key key_len ref rows Extra explain select count(*) from t1 where x in (1); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref x x 5 const 1 Using index -explain select count(*) from t1 where x in (1,2); +explain select count(*) from t1 where x in (1,2,3,4); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index x x 5 NULL 9 Using where; Using index drop table t1; @@ -420,19 +425,19 @@ test.t1 analyze status OK test.t2 analyze status Table is already up to date explain select * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range uid_index uid_index 4 NULL 112 Using index condition +1 SIMPLE t1 range uid_index uid_index 4 NULL 111 Using index condition 1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 38 explain select * from t1, t2 where t1.uid=t2.uid AND t2.uid > 0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range uid_index uid_index 4 NULL 112 Using index condition +1 SIMPLE t1 range uid_index uid_index 4 NULL 111 Using index condition 1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 38 explain select * from t1, t2 where t1.uid=t2.uid AND t1.uid != 0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range uid_index uid_index 4 NULL 113 Using index condition +1 SIMPLE t1 range uid_index uid_index 4 NULL 112 Using index condition 1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 38 explain select * from t1, t2 where t1.uid=t2.uid AND t2.uid != 0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range uid_index uid_index 4 NULL 113 Using index condition +1 SIMPLE t1 range uid_index uid_index 4 NULL 112 Using index condition 1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 38 select * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0; id name uid id name uid @@ -715,7 +720,7 @@ WHERE v.oxrootid ='d8c4177d09f8b11f5.52725521' AND s.oxleft > v.oxleft AND s.oxleft < v.oxright; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE v ref OXLEFT,OXRIGHT,OXROOTID OXROOTID 34 const 5 Using index condition +1 SIMPLE v ref OXLEFT,OXRIGHT,OXROOTID OXROOTID 34 const 6 Using index condition 1 SIMPLE s ALL OXLEFT NULL NULL NULL 12 Range checked for each record (index map: 0x4) SELECT s.oxid FROM t1 v, t1 s WHERE @@ -892,12 +897,13 @@ INSERT INTO t1 VALUES (43,'A'), (44,'A'), (45,'A'), (46,'A'), (47,'A'), (48,'A'), (49,'A'), (50,'A'), (51,'A'), (52,'A'), (53,'C'), (54,'C'), (55,'C'), (56,'C'), (57,'C'), (58,'C'), (59,'C'), (60,'C'); +INSERT INTO t1(status) SELECT status FROM t1; EXPLAIN SELECT * FROM t1 WHERE status <> 'A' AND status <> 'B'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range status status 23 NULL 11 Using index condition +1 SIMPLE t1 range status status 23 NULL 18 Using index condition EXPLAIN SELECT * FROM t1 WHERE status NOT IN ('A','B'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range status status 23 NULL 11 Using index condition +1 SIMPLE t1 range status status 23 NULL 18 Using index condition SELECT * FROM t1 WHERE status <> 'A' AND status <> 'B'; id status 53 C @@ -908,6 +914,14 @@ id status 58 C 59 C 60 C +113 C +114 C +115 C +116 C +117 C +118 C +119 C +120 C SELECT * FROM t1 WHERE status NOT IN ('A','B'); id status 53 C @@ -918,18 +932,26 @@ id status 58 C 59 C 60 C +113 C +114 C +115 C +116 C +117 C +118 C +119 C +120 C EXPLAIN SELECT status FROM t1 WHERE status <> 'A' AND status <> 'B'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range status status 23 NULL 11 Using where; Using index +1 SIMPLE t1 range status status 23 NULL 18 Using where; Using index EXPLAIN SELECT status FROM t1 WHERE status NOT IN ('A','B'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range status status 23 NULL 11 Using where; Using index +1 SIMPLE t1 range status status 23 NULL 18 Using where; Using index EXPLAIN SELECT * FROM t1 WHERE status NOT BETWEEN 'A' AND 'B'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range status status 23 NULL 10 Using index condition +1 SIMPLE t1 range status status 23 NULL 17 Using index condition EXPLAIN SELECT * FROM t1 WHERE status < 'A' OR status > 'B'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range status status 23 NULL 10 Using index condition; Using where +1 SIMPLE t1 range status status 23 NULL 17 Using index condition; Using where SELECT * FROM t1 WHERE status NOT BETWEEN 'A' AND 'B'; id status 53 C @@ -940,6 +962,14 @@ id status 58 C 59 C 60 C +113 C +114 C +115 C +116 C +117 C +118 C +119 C +120 C SELECT * FROM t1 WHERE status < 'A' OR status > 'B'; id status 53 C @@ -950,6 +980,14 @@ id status 58 C 59 C 60 C +113 C +114 C +115 C +116 C +117 C +118 C +119 C +120 C DROP TABLE t1; CREATE TABLE t1 (a int, b int, primary key(a,b)); INSERT INTO t1 VALUES @@ -957,16 +995,16 @@ INSERT INTO t1 VALUES CREATE VIEW v1 as SELECT a,b FROM t1 WHERE b=3; EXPLAIN SELECT a,b FROM t1 WHERE a < 2 and b=3; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using where; Using index +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 Using where; Using index EXPLAIN SELECT a,b FROM v1 WHERE a < 2 and b=3; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using where; Using index +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 Using where; Using index EXPLAIN SELECT a,b FROM t1 WHERE a < 2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using where; Using index +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 Using where; Using index EXPLAIN SELECT a,b FROM v1 WHERE a < 2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using where; Using index +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 Using where; Using index SELECT a,b FROM t1 WHERE a < 2 and b=3; a b 1 3 @@ -1006,10 +1044,10 @@ INSERT INTO `t1` VALUES ,(13,2),(14,2),(15,3),(16,3),(17,3),(18,3),(19,3); explain select * from t1 where a in (3,4) and b in (1,2,3); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 8 NULL # Using where; Using index +1 SIMPLE t1 index PRIMARY PRIMARY 8 NULL # Using where; Using index explain select * from v1 where a in (3,4) and b in (1,2,3); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 8 NULL # Using where; Using index +1 SIMPLE t1 index PRIMARY PRIMARY 8 NULL # Using where; Using index explain select * from t1 where a between 3 and 4 and b between 1 and 2; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range PRIMARY PRIMARY 8 NULL # Using where; Using index @@ -1065,10 +1103,10 @@ id b c 0 3 4 EXPLAIN SELECT * FROM t1 WHERE b<=3 AND 3<=c; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range idx1,idx2 idx2 4 NULL 3 Using index condition; Using where +1 SIMPLE t1 range idx1,idx2 idx2 4 NULL 2 Using index condition; Using where EXPLAIN SELECT * FROM t1 WHERE 3 BETWEEN b AND c; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range idx1,idx2 idx2 4 NULL 3 Using where +1 SIMPLE t1 range idx1,idx2 idx2 4 NULL 2 Using where SELECT * FROM t1 WHERE 0 < b OR 0 > c; id b c 0 3 4 @@ -1079,10 +1117,10 @@ id b c 0 3 4 EXPLAIN SELECT * FROM t1 WHERE 0 < b OR 0 > c; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index_merge idx1,idx2 idx1,idx2 4,4 NULL 4 Using sort_union(idx1,idx2); Using where +1 SIMPLE t1 index_merge idx1,idx2 idx1,idx2 4,4 NULL 3 Using sort_union(idx1,idx2); Using where EXPLAIN SELECT * FROM t1 WHERE 0 NOT BETWEEN b AND c; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index_merge idx1,idx2 idx1,idx2 4,4 NULL 4 Using sort_union(idx1,idx2); Using where +1 SIMPLE t1 index_merge idx1,idx2 idx1,idx2 4,4 NULL 3 Using sort_union(idx1,idx2); Using where DROP TABLE t1; CREATE TABLE t1 ( item char(20) NOT NULL default '', @@ -1097,7 +1135,7 @@ INSERT INTO t1 VALUES ('A2','2005-12-01 08:00:00',1000); EXPLAIN SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref PRIMARY PRIMARY 20 const 2 Using index condition +1 SIMPLE t1 ref PRIMARY PRIMARY 20 const 3 Using index condition SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00'; item started price Warnings: @@ -1141,7 +1179,7 @@ CREATE TABLE t1 ( a varchar(32), index (a) ) DEFAULT CHARSET=latin1 COLLATE=latin1_bin; INSERT INTO t1 VALUES -('B'), ('A'), ('A'), ('C'), ('B'), ('A'), ('A'); +('B'), ('A'), ('A'), ('C'), ('B'), ('A'), ('A'), ('C'), ('A'); SELECT a FROM t1 WHERE a='b' OR a='B'; a B @@ -1201,13 +1239,15 @@ Z In following EXPLAIN the access method should be ref, #rows~=500 (and not 2) explain select * from t2 where a=1000 and b<11; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ref a a 5 const 502 Using index condition +1 SIMPLE t2 ref a a 5 const 503 Using index condition drop table t1, t2; CREATE TABLE t1( a INT, b INT, KEY( a, b ) ); CREATE TABLE t2( a INT, b INT, KEY( a, b ) ); CREATE TABLE t3( a INT, b INT, KEY( a, b ) ); -INSERT INTO t1( a, b ) -VALUES (0, 1), (1, 2), (1, 4), (2, 3), (5, 0), (9, 7); +INSERT INTO t1( a, b ) VALUES +(0, 1), (1, 2), (1, 4), (2, 3), (5, 0), (9, 7), +(10, 11), (11,12), (11, 14), (12, 13), (15, 10), (19, 17), +(20, 21), (21,22), (21, 24), (22, 23), (25, 20), (29, 27); INSERT INTO t2( a, b ) VALUES ( 1, 1), ( 2, 1), ( 3, 1), ( 4, 1), ( 5, 1), ( 6, 1), ( 7, 1), ( 8, 1), ( 9, 1), (10, 1), @@ -1218,65 +1258,67 @@ INSERT INTO t2 SELECT a, 3 FROM t2 WHERE b = 1; INSERT INTO t2 SELECT -1, -1 FROM t2; INSERT INTO t2 SELECT -1, -1 FROM t2; INSERT INTO t2 SELECT -1, -1 FROM t2; -INSERT INTO t3 -VALUES (1, 0), (2, 0), (3, 0), (4, 0), (5, 0), -(6, 0), (7, 0), (8, 0), (9, 0), (10, 0); +INSERT INTO t3 VALUES +(1, 0), (2, 0), (3, 0), (4, 0), (5, 0), +(6, 0), (7, 0), (8, 0), (9, 0), (10, 0), +(11, 0), (12, 0), (13, 0), (14, 0), (15, 0), +(16, 0), (17, 0), (18, 0), (19, 0), (20, 0); INSERT INTO t3 SELECT * FROM t3 WHERE a = 10; INSERT INTO t3 SELECT * FROM t3 WHERE a = 10; SELECT * FROM t1 WHERE -3 <= a AND a < 5 OR -5 < a AND b = 3 OR -3 <= a; +23 <= a AND a < 25 OR +25 < a AND b = 23 OR +23 <= a; a b -5 0 -9 7 +25 20 +29 27 EXPLAIN SELECT * FROM t1 WHERE -3 <= a AND a < 5 OR -5 < a AND b = 3 OR -3 <= a; +23 <= a AND a < 25 OR +25 < a AND b = 23 OR +23 <= a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 3 Using where; Using index +1 SIMPLE t1 range a a 5 NULL 2 Using where; Using index SELECT * FROM t1 WHERE -3 <= a AND a < 5 OR -5 <= a AND b = 3 OR -3 <= a; +23 <= a AND a < 25 OR +25 <= a AND b = 23 OR +23 <= a; a b -5 0 -9 7 +25 20 +29 27 EXPLAIN SELECT * FROM t1 WHERE -3 <= a AND a < 5 OR -5 <= a AND b = 3 OR -3 <= a; +23 <= a AND a < 25 OR +25 <= a AND b = 23 OR +23 <= a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 4 Using where; Using index +1 SIMPLE t1 range a a 5 NULL 3 Using where; Using index SELECT * FROM t1 WHERE -3 <= a AND a <= 5 OR -5 <= a AND b = 3 OR -3 <= a; +23 <= a AND a <= 25 OR +25 <= a AND b = 23 OR +23 <= a; a b -5 0 -9 7 +25 20 +29 27 EXPLAIN SELECT * FROM t1 WHERE -3 <= a AND a <= 5 OR -5 <= a AND b = 3 OR -3 <= a; +23 <= a AND a <= 25 OR +25 <= a AND b = 23 OR +23 <= a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 3 Using where; Using index +1 SIMPLE t1 range a a 5 NULL 2 Using where; Using index SELECT * FROM t1 WHERE -3 <= a AND a <= 5 OR -3 <= a; +23 <= a AND a <= 25 OR +23 <= a; a b -5 0 -9 7 +25 20 +29 27 EXPLAIN SELECT * FROM t1 WHERE -3 <= a AND a <= 5 OR -3 <= a; +23 <= a AND a <= 25 OR +23 <= a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 3 Using where; Using index +1 SIMPLE t1 range a a 5 NULL 2 Using where; Using index SELECT * FROM t2 WHERE 5 <= a AND a < 10 AND b = 1 OR 15 <= a AND a < 20 AND b = 3 @@ -1315,7 +1357,7 @@ SELECT * FROM t2 WHERE OR 1 <= a AND b = 1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range a a 10 NULL 50 Using where; Using index +1 SIMPLE t2 range a a 10 NULL 49 Using where; Using index SELECT * FROM t2 WHERE 5 <= a AND a < 10 AND b = 2 OR 15 <= a AND a < 20 AND b = 3 @@ -1359,7 +1401,7 @@ SELECT * FROM t2 WHERE OR 1 <= a AND b = 1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range a a 10 NULL 50 Using where; Using index +1 SIMPLE t2 range a a 10 NULL 49 Using where; Using index SELECT * FROM t3 WHERE 5 <= a AND a < 10 AND b = 3 OR a < 5 OR @@ -1380,7 +1422,7 @@ SELECT * FROM t3 WHERE a < 5 OR a < 10; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t3 range a a 5 NULL 8 Using where; Using index +1 SIMPLE t3 range a a 5 NULL 9 Using where; Using index DROP TABLE t1, t2, t3; # # Bug #47123: Endless 100% CPU loop with STRAIGHT_JOIN @@ -1398,10 +1440,16 @@ CREATE TABLE t2 ( a DATETIME, KEY ( a ) ); # Make optimizer choose range scan INSERT INTO t1 VALUES ('2009-09-22'), ('2009-09-22'), ('2009-09-22'); INSERT INTO t1 VALUES ('2009-09-23'), ('2009-09-23'), ('2009-09-23'); +INSERT INTO t1 VALUES ('2009-09-20'), ('2009-09-20'), ('2009-09-20'); +INSERT INTO t1 VALUES ('2009-09-21'), ('2009-09-21'), ('2009-09-21'); INSERT INTO t2 VALUES ('2009-09-22 12:00:00'), ('2009-09-22 12:00:00'), ('2009-09-22 12:00:00'); INSERT INTO t2 VALUES ('2009-09-23 12:00:00'), ('2009-09-23 12:00:00'), ('2009-09-23 12:00:00'); +INSERT INTO t2 VALUES ('2009-09-20 12:00:00'), ('2009-09-20 12:00:00'), +('2009-09-20 12:00:00'); +INSERT INTO t2 VALUES ('2009-09-21 12:00:00'), ('2009-09-21 12:00:00'), +('2009-09-21 12:00:00'); # DATE vs DATE EXPLAIN SELECT * FROM t1 WHERE a >= '2009/09/23'; @@ -1656,7 +1704,8 @@ DROP TABLE t1; # CREATE TABLE t1(pk INT PRIMARY KEY, i4 INT); CREATE UNIQUE INDEX i4_uq ON t1(i4); -INSERT INTO t1 VALUES (1,10), (2,20), (3,30); +INSERT INTO t1 VALUES +(1,10), (2,20), (3,30), (4,40), (5,50), (6,60), (7,70), (8,80); EXPLAIN SELECT * FROM t1 WHERE i4 BETWEEN 10 AND 10; id select_type table type possible_keys key key_len ref rows Extra @@ -1672,14 +1721,13 @@ SELECT * FROM t1 WHERE 10 BETWEEN i4 AND i4; pk i4 1 10 EXPLAIN -SELECT * FROM t1 WHERE 10 BETWEEN 10 AND i4; +SELECT * FROM t1 WHERE 70 BETWEEN 70 AND i4; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range i4_uq i4_uq 5 NULL 3 Using index condition -SELECT * FROM t1 WHERE 10 BETWEEN 10 AND i4; +1 SIMPLE t1 range i4_uq i4_uq 5 NULL 2 Using index condition +SELECT * FROM t1 WHERE 70 BETWEEN 70 AND i4; pk i4 -1 10 -2 20 -3 30 +7 70 +8 80 EXPLAIN SELECT * FROM t1 WHERE 10 BETWEEN i4 AND 10; id select_type table type possible_keys key key_len ref rows Extra @@ -1690,12 +1738,17 @@ pk i4 EXPLAIN SELECT * FROM t1 WHERE 10 BETWEEN 10 AND 10; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 3 +1 SIMPLE t1 ALL NULL NULL NULL NULL 8 SELECT * FROM t1 WHERE 10 BETWEEN 10 AND 10; pk i4 1 10 2 20 3 30 +4 40 +5 50 +6 60 +7 70 +8 80 EXPLAIN SELECT * FROM t1 WHERE 10 BETWEEN 11 AND 11; id select_type table type possible_keys key key_len ref rows Extra @@ -1715,14 +1768,13 @@ id select_type table type possible_keys key key_len ref rows Extra SELECT * FROM t1 WHERE i4 BETWEEN 100 AND 0; pk i4 EXPLAIN -SELECT * FROM t1 WHERE i4 BETWEEN 10 AND 99999999999999999; +SELECT * FROM t1 WHERE i4 BETWEEN 70 AND 99999999999999999; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range i4_uq i4_uq 5 NULL 2 Using index condition -SELECT * FROM t1 WHERE i4 BETWEEN 10 AND 99999999999999999; +SELECT * FROM t1 WHERE i4 BETWEEN 70 AND 99999999999999999; pk i4 -1 10 -2 20 -3 30 +7 70 +8 80 EXPLAIN SELECT * FROM t1 WHERE i4 BETWEEN 999999999999999 AND 30; id select_type table type possible_keys key key_len ref rows Extra @@ -1732,7 +1784,7 @@ pk i4 EXPLAIN SELECT * FROM t1 WHERE i4 BETWEEN 10 AND '20'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range i4_uq i4_uq 5 NULL 1 Using index condition +1 SIMPLE t1 range i4_uq i4_uq 5 NULL 2 Using index condition SELECT * FROM t1 WHERE i4 BETWEEN 10 AND '20'; pk i4 1 10 @@ -1740,14 +1792,14 @@ pk i4 EXPLAIN SELECT * FROM t1, t1 as t2 WHERE t2.pk BETWEEN t1.i4 AND t1.i4; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL i4_uq NULL NULL NULL 3 +1 SIMPLE t1 ALL i4_uq NULL NULL NULL 8 1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.i4 1 Using index condition SELECT * FROM t1, t1 as t2 WHERE t2.pk BETWEEN t1.i4 AND t1.i4; pk i4 pk i4 EXPLAIN SELECT * FROM t1, t1 as t2 WHERE t1.i4 BETWEEN t2.pk AND t2.pk; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL i4_uq NULL NULL NULL 3 +1 SIMPLE t1 ALL i4_uq NULL NULL NULL 8 1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.i4 1 Using index condition SELECT * FROM t1, t1 as t2 WHERE t1.i4 BETWEEN t2.pk AND t2.pk; pk i4 pk i4 @@ -1893,19 +1945,23 @@ insert into t2 select a+16 from t2; insert into t2 select a+32 from t2; insert into t2 select a+64 from t2; explain -select count(*) from t2 left join t1 on (t1.key1 < 3 or t1.key1 > 1020) and t1.key2 < 1000; +select count(*) from t2 left join t1 +on (t1.key1 < 3 or t1.key1 between 920 and 930) and t1.key2 < 1000; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 64 -1 SIMPLE t1 range i1,i2 i1 4 NULL 78 Using where; Using join buffer (flat, BNL join) -select count(*) from t2 left join t1 on (t1.key1 < 3 or t1.key1 > 1020) and t1.key2 < 1000; +1 SIMPLE t1 range i1,i2 i1 4 NULL 12 Using where; Using join buffer (flat, BNL join) +select count(*) from t2 left join t1 +on (t1.key1 < 3 or t1.key1 between 920 and 930) and t1.key2 < 1000; count(*) -128 +832 explain -select count(*) from t2 left join t1 on (t1.key1 < 3 or t1.key1 > 1020) and t1.key2 < t2.a; +select count(*) from t2 left join t1 +on (t1.key1 < 3 or t1.key1 between 920 and 930) and t1.key2 < t2.a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 64 -1 SIMPLE t1 range i1,i2 i1 4 NULL 78 Using where; Using join buffer (flat, BNL join) -select count(*) from t2 left join t1 on (t1.key1 < 3 or t1.key1 > 1020) and t1.key2 < t2.a; +1 SIMPLE t1 range i1,i2 i1 4 NULL 12 Using where; Using join buffer (flat, BNL join) +select count(*) from t2 left join t1 +on (t1.key1 < 3 or t1.key1 between 920 and 930) and t1.key2 < t2.a; count(*) 126 drop table t1,t2; @@ -1919,7 +1975,7 @@ insert into t1 values (0,0,0), (2,2,0), (1,1,1), (2,2,1); explain select * from t1 force index (idx) where a >=1 and c <= 1 and a=b and b > 1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range idx idx 5 NULL 3 Using where; Using index +1 SIMPLE t1 index idx idx 15 NULL 4 Using where; Using index select * from t1 force index (idx) where a >=1 and c <= 1 and a=b and b > 1; a b c 2 2 0 @@ -1949,7 +2005,7 @@ INSERT INTO t100(I,J) VALUES(8,26); EXPLAIN SELECT * FROM t100 WHERE I <> 6 OR (I <> 8 AND J = 5); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t100 range I I 10 NULL 4 Using index condition; Using where +1 SIMPLE t100 range I I 10 NULL 3 Using index condition; Using where SELECT * FROM t100 WHERE I <> 6 OR (I <> 8 AND J = 5); K I J @@ -2272,10 +2328,10 @@ CREATE TABLE t1 (a INT, b INT, KEY(a)); INSERT INTO t1 (a) VALUES (10),(10),(10),(10),(10),(10),(10),(10),(10),(10),(70); EXPLAIN SELECT * FROM t1 WHERE a<>10; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 3 Using index condition +1 SIMPLE t1 range a a 5 NULL 2 Using index condition EXPLAIN SELECT * FROM t1 WHERE 10<>a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 3 Using index condition +1 SIMPLE t1 range a a 5 NULL 2 Using index condition SELECT * FROM t1 WHERE a<>10; a b 70 NULL @@ -2333,7 +2389,7 @@ insert into t1 values # range access to t1 by 2-component keys for index idx explain select * from t1 where (a,b) IN ((2, 3),(3,3),(8,8),(7,7)); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range idx idx 10 NULL 7 Using where +1 SIMPLE t1 range idx idx 10 NULL 6 Using where explain format=json select * from t1 where (a,b) IN ((2, 3),(3,3),(8,8),(7,7)); EXPLAIN { @@ -2346,7 +2402,7 @@ EXPLAIN "key": "idx", "key_length": "10", "used_key_parts": ["a", "b"], - "rows": 7, + "rows": 6, "filtered": 100, "attached_condition": "(t1.a,t1.b) in (<cache>((2,3)),<cache>((3,3)),<cache>((8,8)),<cache>((7,7)))" } @@ -2530,7 +2586,7 @@ explain select * from t1,t2 where a = d and (a,e) in ((3,3),(7,7),(8,8)) and length(f) = 1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range idx idx 5 NULL 6 Using index condition -1 SIMPLE t2 ref idx1,idx2 idx1 5 test.t1.a 12 Using where +1 SIMPLE t2 ref|filter idx1,idx2 idx1|idx2 5|5 test.t1.a 12 (14%) Using where; Using filter explain format=json select * from t1,t2 where a = d and (a,e) in ((3,3),(7,7),(8,8)) and length(f) = 1; EXPLAIN @@ -2556,6 +2612,14 @@ EXPLAIN "key_length": "5", "used_key_parts": ["d"], "ref": ["test.t1.a"], + "rowid_filter": { + "range": { + "key": "idx2", + "used_key_parts": ["e"] + }, + "rows": 15, + "selectivity_pct": 14.423 + }, "rows": 12, "filtered": 100, "attached_condition": "(t1.a,t2.e) in (<cache>((3,3)),<cache>((7,7)),<cache>((8,8))) and octet_length(t2.f) = 1" @@ -2626,7 +2690,7 @@ insert into t1 select * from t1; explain select * from t1,t2 where a = d and (a,e) in ((4,4),(7,7),(8,8)) and length(f) = 1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range idx1,idx2 idx2 5 NULL 6 Using where +1 SIMPLE t2 range|filter idx1,idx2 idx1|idx2 5|5 NULL 7 (7%) Using index condition; Using where; Using filter 1 SIMPLE t1 ref idx idx 5 test.t2.d 11 explain format=json select * from t1,t2 where a = d and (a,e) in ((4,4),(7,7),(8,8)) and length(f) = 1; @@ -2638,12 +2702,21 @@ EXPLAIN "table_name": "t2", "access_type": "range", "possible_keys": ["idx1", "idx2"], - "key": "idx2", + "key": "idx1", "key_length": "5", - "used_key_parts": ["e"], - "rows": 6, + "used_key_parts": ["d"], + "rowid_filter": { + "range": { + "key": "idx2", + "used_key_parts": ["e"] + }, + "rows": 7, + "selectivity_pct": 6.7308 + }, + "rows": 7, "filtered": 100, - "attached_condition": "(t2.d,t2.e) in (<cache>((4,4)),<cache>((7,7)),<cache>((8,8))) and octet_length(t2.f) = 1 and t2.d is not null" + "index_condition": "t2.d is not null", + "attached_condition": "(t2.d,t2.e) in (<cache>((4,4)),<cache>((7,7)),<cache>((8,8))) and octet_length(t2.f) = 1" }, "table": { "table_name": "t1", @@ -2828,7 +2901,7 @@ explain select * from t1,t2 where a = d and (a,2) in ((2,2),(7,7),(8,8)) and length(c) = 1 and length(f) = 1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range idx idx 5 NULL 13 Using index condition; Using where +1 SIMPLE t1 range idx idx 5 NULL 12 Using index condition; Using where 1 SIMPLE t2 ref idx3 idx3 5 test.t1.a 3 Using where explain format=json select * from t1,t2 where a = d and (a,2) in ((2,2),(7,7),(8,8)) and @@ -2844,7 +2917,7 @@ EXPLAIN "key": "idx", "key_length": "5", "used_key_parts": ["a"], - "rows": 13, + "rows": 12, "filtered": 100, "index_condition": "t1.a is not null", "attached_condition": "(t1.a,2) in (<cache>((2,2)),<cache>((7,7)),<cache>((8,8))) and octet_length(t1.c) = 1" @@ -2904,7 +2977,7 @@ where id = 1 and a = d and length(c) = 1 and length(f) = 1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t3 const PRIMARY PRIMARY 4 const 1 -1 SIMPLE t1 range idx idx 5 NULL 13 Using index condition; Using where +1 SIMPLE t1 range idx idx 5 NULL 12 Using index condition; Using where 1 SIMPLE t2 ref idx3 idx3 5 test.t1.a 3 Using where explain format=json select * from t1,t2,t3 where id = 1 and a = d and @@ -2932,7 +3005,7 @@ EXPLAIN "key": "idx", "key_length": "5", "used_key_parts": ["a"], - "rows": 13, + "rows": 12, "filtered": 100, "index_condition": "t1.a is not null", "attached_condition": "(t1.a,1 + 1) in (<cache>((2,2)),<cache>((7,7)),<cache>((8,8))) and octet_length(t1.c) = 1" @@ -3024,3 +3097,6 @@ drop table t1; # # End of 10.2 tests # +set global innodb_stats_persistent= @innodb_stats_persistent_save; +set global innodb_stats_persistent_sample_pages= +@innodb_stats_persistent_sample_pages_save; diff --git a/mysql-test/main/range.test b/mysql-test/main/range.test index bd2299bac5f..9edb3f39ae3 100644 --- a/mysql-test/main/range.test +++ b/mysql-test/main/range.test @@ -3,6 +3,13 @@ # --source include/have_innodb.inc +set @innodb_stats_persistent_save= @@innodb_stats_persistent; +set @innodb_stats_persistent_sample_pages_save= + @@innodb_stats_persistent_sample_pages; + +set global innodb_stats_persistent= 1; +set global innodb_stats_persistent_sample_pages=100; + CREATE TABLE t1 ( event_date date DEFAULT '0000-00-00' NOT NULL, type int(11) DEFAULT '0' NOT NULL, @@ -188,7 +195,7 @@ explain select * from t1, t1 t2 where t1.y = 2 and t2.x between 0 and t1.y; explain select * from t1, t1 t2 where t1.y = 2 and t2.x >= 0 and t2.x <= t1.y; # testing IN explain select count(*) from t1 where x in (1); -explain select count(*) from t1 where x in (1,2); +explain select count(*) from t1 where x in (1,2,3,4); drop table t1; # @@ -745,6 +752,7 @@ INSERT INTO t1 VALUES (43,'A'), (44,'A'), (45,'A'), (46,'A'), (47,'A'), (48,'A'), (49,'A'), (50,'A'), (51,'A'), (52,'A'), (53,'C'), (54,'C'), (55,'C'), (56,'C'), (57,'C'), (58,'C'), (59,'C'), (60,'C'); +INSERT INTO t1(status) SELECT status FROM t1; EXPLAIN SELECT * FROM t1 WHERE status <> 'A' AND status <> 'B'; EXPLAIN SELECT * FROM t1 WHERE status NOT IN ('A','B'); @@ -950,7 +958,7 @@ CREATE TABLE t1 ( ) DEFAULT CHARSET=latin1 COLLATE=latin1_bin; INSERT INTO t1 VALUES - ('B'), ('A'), ('A'), ('C'), ('B'), ('A'), ('A'); + ('B'), ('A'), ('A'), ('C'), ('B'), ('A'), ('A'), ('C'), ('A'); SELECT a FROM t1 WHERE a='b' OR a='B'; EXPLAIN SELECT a FROM t1 WHERE a='b' OR a='B'; @@ -1040,8 +1048,10 @@ CREATE TABLE t2( a INT, b INT, KEY( a, b ) ); CREATE TABLE t3( a INT, b INT, KEY( a, b ) ); -INSERT INTO t1( a, b ) -VALUES (0, 1), (1, 2), (1, 4), (2, 3), (5, 0), (9, 7); +INSERT INTO t1( a, b ) VALUES + (0, 1), (1, 2), (1, 4), (2, 3), (5, 0), (9, 7), + (10, 11), (11,12), (11, 14), (12, 13), (15, 10), (19, 17), + (20, 21), (21,22), (21, 24), (22, 23), (25, 20), (29, 27); INSERT INTO t2( a, b ) VALUES ( 1, 1), ( 2, 1), ( 3, 1), ( 4, 1), ( 5, 1), @@ -1057,9 +1067,11 @@ INSERT INTO t2 SELECT -1, -1 FROM t2; INSERT INTO t2 SELECT -1, -1 FROM t2; INSERT INTO t2 SELECT -1, -1 FROM t2; -INSERT INTO t3 -VALUES (1, 0), (2, 0), (3, 0), (4, 0), (5, 0), - (6, 0), (7, 0), (8, 0), (9, 0), (10, 0); +INSERT INTO t3 VALUES + (1, 0), (2, 0), (3, 0), (4, 0), (5, 0), + (6, 0), (7, 0), (8, 0), (9, 0), (10, 0), + (11, 0), (12, 0), (13, 0), (14, 0), (15, 0), + (16, 0), (17, 0), (18, 0), (19, 0), (20, 0); # To make range scan compelling to the optimizer INSERT INTO t3 SELECT * FROM t3 WHERE a = 10; @@ -1071,47 +1083,47 @@ INSERT INTO t3 SELECT * FROM t3 WHERE a = 10; # With one exception, they are independent of Problem#2. # SELECT * FROM t1 WHERE -3 <= a AND a < 5 OR -5 < a AND b = 3 OR -3 <= a; +23 <= a AND a < 25 OR +25 < a AND b = 23 OR +23 <= a; EXPLAIN SELECT * FROM t1 WHERE -3 <= a AND a < 5 OR -5 < a AND b = 3 OR -3 <= a; +23 <= a AND a < 25 OR +25 < a AND b = 23 OR +23 <= a; # Query below: Tests both Problem#1 and Problem#2 (EXPLAIN differs as well) SELECT * FROM t1 WHERE -3 <= a AND a < 5 OR -5 <= a AND b = 3 OR -3 <= a; +23 <= a AND a < 25 OR +25 <= a AND b = 23 OR +23 <= a; EXPLAIN SELECT * FROM t1 WHERE -3 <= a AND a < 5 OR -5 <= a AND b = 3 OR -3 <= a; +23 <= a AND a < 25 OR +25 <= a AND b = 23 OR +23 <= a; SELECT * FROM t1 WHERE -3 <= a AND a <= 5 OR -5 <= a AND b = 3 OR -3 <= a; +23 <= a AND a <= 25 OR +25 <= a AND b = 23 OR +23 <= a; EXPLAIN SELECT * FROM t1 WHERE -3 <= a AND a <= 5 OR -5 <= a AND b = 3 OR -3 <= a; +23 <= a AND a <= 25 OR +25 <= a AND b = 23 OR +23 <= a; SELECT * FROM t1 WHERE -3 <= a AND a <= 5 OR -3 <= a; +23 <= a AND a <= 25 OR +23 <= a; EXPLAIN SELECT * FROM t1 WHERE -3 <= a AND a <= 5 OR -3 <= a; +23 <= a AND a <= 25 OR +23 <= a; # # Problem#2 Test queries. @@ -1175,11 +1187,17 @@ CREATE TABLE t2 ( a DATETIME, KEY ( a ) ); --echo # Make optimizer choose range scan INSERT INTO t1 VALUES ('2009-09-22'), ('2009-09-22'), ('2009-09-22'); INSERT INTO t1 VALUES ('2009-09-23'), ('2009-09-23'), ('2009-09-23'); +INSERT INTO t1 VALUES ('2009-09-20'), ('2009-09-20'), ('2009-09-20'); +INSERT INTO t1 VALUES ('2009-09-21'), ('2009-09-21'), ('2009-09-21'); INSERT INTO t2 VALUES ('2009-09-22 12:00:00'), ('2009-09-22 12:00:00'), ('2009-09-22 12:00:00'); INSERT INTO t2 VALUES ('2009-09-23 12:00:00'), ('2009-09-23 12:00:00'), ('2009-09-23 12:00:00'); +INSERT INTO t2 VALUES ('2009-09-20 12:00:00'), ('2009-09-20 12:00:00'), + ('2009-09-20 12:00:00'); +INSERT INTO t2 VALUES ('2009-09-21 12:00:00'), ('2009-09-21 12:00:00'), + ('2009-09-21 12:00:00'); --echo # DATE vs DATE --replace_column 1 X 2 X 3 X 7 X 8 X 9 X 10 X @@ -1320,7 +1338,9 @@ DROP TABLE t1; CREATE TABLE t1(pk INT PRIMARY KEY, i4 INT); CREATE UNIQUE INDEX i4_uq ON t1(i4); -INSERT INTO t1 VALUES (1,10), (2,20), (3,30); +INSERT INTO t1 VALUES + (1,10), (2,20), (3,30), (4,40), (5,50), (6,60), (7,70), (8,80); + EXPLAIN SELECT * FROM t1 WHERE i4 BETWEEN 10 AND 10; @@ -1331,8 +1351,8 @@ SELECT * FROM t1 WHERE 10 BETWEEN i4 AND i4; SELECT * FROM t1 WHERE 10 BETWEEN i4 AND i4; EXPLAIN -SELECT * FROM t1 WHERE 10 BETWEEN 10 AND i4; -SELECT * FROM t1 WHERE 10 BETWEEN 10 AND i4; +SELECT * FROM t1 WHERE 70 BETWEEN 70 AND i4; +SELECT * FROM t1 WHERE 70 BETWEEN 70 AND i4; EXPLAIN SELECT * FROM t1 WHERE 10 BETWEEN i4 AND 10; @@ -1355,8 +1375,8 @@ SELECT * FROM t1 WHERE i4 BETWEEN 100 AND 0; SELECT * FROM t1 WHERE i4 BETWEEN 100 AND 0; EXPLAIN -SELECT * FROM t1 WHERE i4 BETWEEN 10 AND 99999999999999999; -SELECT * FROM t1 WHERE i4 BETWEEN 10 AND 99999999999999999; +SELECT * FROM t1 WHERE i4 BETWEEN 70 AND 99999999999999999; +SELECT * FROM t1 WHERE i4 BETWEEN 70 AND 99999999999999999; EXPLAIN SELECT * FROM t1 WHERE i4 BETWEEN 999999999999999 AND 30; @@ -1479,11 +1499,15 @@ insert into t2 select a+32 from t2; insert into t2 select a+64 from t2; explain -select count(*) from t2 left join t1 on (t1.key1 < 3 or t1.key1 > 1020) and t1.key2 < 1000; -select count(*) from t2 left join t1 on (t1.key1 < 3 or t1.key1 > 1020) and t1.key2 < 1000; +select count(*) from t2 left join t1 + on (t1.key1 < 3 or t1.key1 between 920 and 930) and t1.key2 < 1000; +select count(*) from t2 left join t1 + on (t1.key1 < 3 or t1.key1 between 920 and 930) and t1.key2 < 1000; explain -select count(*) from t2 left join t1 on (t1.key1 < 3 or t1.key1 > 1020) and t1.key2 < t2.a; -select count(*) from t2 left join t1 on (t1.key1 < 3 or t1.key1 > 1020) and t1.key2 < t2.a; +select count(*) from t2 left join t1 + on (t1.key1 < 3 or t1.key1 between 920 and 930) and t1.key2 < t2.a; +select count(*) from t2 left join t1 + on (t1.key1 < 3 or t1.key1 between 920 and 930) and t1.key2 < t2.a; drop table t1,t2; @@ -2053,3 +2077,7 @@ drop table t1; --echo # --echo # End of 10.2 tests --echo # + +set global innodb_stats_persistent= @innodb_stats_persistent_save; +set global innodb_stats_persistent_sample_pages= + @innodb_stats_persistent_sample_pages_save; diff --git a/mysql-test/main/range_mrr_icp.result b/mysql-test/main/range_mrr_icp.result index a6c57378f9c..a4a64dd1bbe 100644 --- a/mysql-test/main/range_mrr_icp.result +++ b/mysql-test/main/range_mrr_icp.result @@ -1,5 +1,11 @@ set @mrr_icp_extra_tmp=@@optimizer_switch; set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; +set optimizer_switch='rowid_filter=off'; +set @innodb_stats_persistent_save= @@innodb_stats_persistent; +set @innodb_stats_persistent_sample_pages_save= +@@innodb_stats_persistent_sample_pages; +set global innodb_stats_persistent= 1; +set global innodb_stats_persistent_sample_pages=100; CREATE TABLE t1 ( event_date date DEFAULT '0000-00-00' NOT NULL, type int(11) DEFAULT '0' NOT NULL, @@ -246,7 +252,7 @@ id select_type table type possible_keys key key_len ref rows Extra explain select count(*) from t1 where x in (1); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref x x 5 const 1 Using index -explain select count(*) from t1 where x in (1,2); +explain select count(*) from t1 where x in (1,2,3,4); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index x x 5 NULL 9 Using where; Using index drop table t1; @@ -422,19 +428,19 @@ test.t1 analyze status OK test.t2 analyze status Table is already up to date explain select * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range uid_index uid_index 4 NULL 112 Using index condition; Rowid-ordered scan +1 SIMPLE t1 range uid_index uid_index 4 NULL 111 Using index condition; Rowid-ordered scan 1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 38 explain select * from t1, t2 where t1.uid=t2.uid AND t2.uid > 0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range uid_index uid_index 4 NULL 112 Using index condition; Rowid-ordered scan +1 SIMPLE t1 range uid_index uid_index 4 NULL 111 Using index condition; Rowid-ordered scan 1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 38 explain select * from t1, t2 where t1.uid=t2.uid AND t1.uid != 0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range uid_index uid_index 4 NULL 113 Using index condition; Rowid-ordered scan +1 SIMPLE t1 range uid_index uid_index 4 NULL 112 Using index condition; Rowid-ordered scan 1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 38 explain select * from t1, t2 where t1.uid=t2.uid AND t2.uid != 0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range uid_index uid_index 4 NULL 113 Using index condition; Rowid-ordered scan +1 SIMPLE t1 range uid_index uid_index 4 NULL 112 Using index condition; Rowid-ordered scan 1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 38 select * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0; id name uid id name uid @@ -717,7 +723,7 @@ WHERE v.oxrootid ='d8c4177d09f8b11f5.52725521' AND s.oxleft > v.oxleft AND s.oxleft < v.oxright; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE v ref OXLEFT,OXRIGHT,OXROOTID OXROOTID 34 const 5 Using index condition +1 SIMPLE v ref OXLEFT,OXRIGHT,OXROOTID OXROOTID 34 const 6 Using index condition 1 SIMPLE s ALL OXLEFT NULL NULL NULL 12 Range checked for each record (index map: 0x4) SELECT s.oxid FROM t1 v, t1 s WHERE @@ -894,12 +900,13 @@ INSERT INTO t1 VALUES (43,'A'), (44,'A'), (45,'A'), (46,'A'), (47,'A'), (48,'A'), (49,'A'), (50,'A'), (51,'A'), (52,'A'), (53,'C'), (54,'C'), (55,'C'), (56,'C'), (57,'C'), (58,'C'), (59,'C'), (60,'C'); +INSERT INTO t1(status) SELECT status FROM t1; EXPLAIN SELECT * FROM t1 WHERE status <> 'A' AND status <> 'B'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range status status 23 NULL 11 Using index condition; Rowid-ordered scan +1 SIMPLE t1 range status status 23 NULL 18 Using index condition; Rowid-ordered scan EXPLAIN SELECT * FROM t1 WHERE status NOT IN ('A','B'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range status status 23 NULL 11 Using index condition; Rowid-ordered scan +1 SIMPLE t1 range status status 23 NULL 18 Using index condition; Rowid-ordered scan SELECT * FROM t1 WHERE status <> 'A' AND status <> 'B'; id status 53 C @@ -910,6 +917,14 @@ id status 58 C 59 C 60 C +113 C +114 C +115 C +116 C +117 C +118 C +119 C +120 C SELECT * FROM t1 WHERE status NOT IN ('A','B'); id status 53 C @@ -920,18 +935,26 @@ id status 58 C 59 C 60 C +113 C +114 C +115 C +116 C +117 C +118 C +119 C +120 C EXPLAIN SELECT status FROM t1 WHERE status <> 'A' AND status <> 'B'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range status status 23 NULL 11 Using where; Using index +1 SIMPLE t1 range status status 23 NULL 18 Using where; Using index EXPLAIN SELECT status FROM t1 WHERE status NOT IN ('A','B'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range status status 23 NULL 11 Using where; Using index +1 SIMPLE t1 range status status 23 NULL 18 Using where; Using index EXPLAIN SELECT * FROM t1 WHERE status NOT BETWEEN 'A' AND 'B'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range status status 23 NULL 10 Using index condition; Rowid-ordered scan +1 SIMPLE t1 range status status 23 NULL 17 Using index condition; Rowid-ordered scan EXPLAIN SELECT * FROM t1 WHERE status < 'A' OR status > 'B'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range status status 23 NULL 10 Using index condition; Using where; Rowid-ordered scan +1 SIMPLE t1 range status status 23 NULL 17 Using index condition; Using where; Rowid-ordered scan SELECT * FROM t1 WHERE status NOT BETWEEN 'A' AND 'B'; id status 53 C @@ -942,6 +965,14 @@ id status 58 C 59 C 60 C +113 C +114 C +115 C +116 C +117 C +118 C +119 C +120 C SELECT * FROM t1 WHERE status < 'A' OR status > 'B'; id status 53 C @@ -952,6 +983,14 @@ id status 58 C 59 C 60 C +113 C +114 C +115 C +116 C +117 C +118 C +119 C +120 C DROP TABLE t1; CREATE TABLE t1 (a int, b int, primary key(a,b)); INSERT INTO t1 VALUES @@ -959,16 +998,16 @@ INSERT INTO t1 VALUES CREATE VIEW v1 as SELECT a,b FROM t1 WHERE b=3; EXPLAIN SELECT a,b FROM t1 WHERE a < 2 and b=3; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using where; Using index +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 Using where; Using index EXPLAIN SELECT a,b FROM v1 WHERE a < 2 and b=3; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using where; Using index +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 Using where; Using index EXPLAIN SELECT a,b FROM t1 WHERE a < 2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using where; Using index +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 Using where; Using index EXPLAIN SELECT a,b FROM v1 WHERE a < 2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using where; Using index +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 Using where; Using index SELECT a,b FROM t1 WHERE a < 2 and b=3; a b 1 3 @@ -1008,10 +1047,10 @@ INSERT INTO `t1` VALUES ,(13,2),(14,2),(15,3),(16,3),(17,3),(18,3),(19,3); explain select * from t1 where a in (3,4) and b in (1,2,3); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 8 NULL # Using where; Using index +1 SIMPLE t1 index PRIMARY PRIMARY 8 NULL # Using where; Using index explain select * from v1 where a in (3,4) and b in (1,2,3); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 8 NULL # Using where; Using index +1 SIMPLE t1 index PRIMARY PRIMARY 8 NULL # Using where; Using index explain select * from t1 where a between 3 and 4 and b between 1 and 2; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range PRIMARY PRIMARY 8 NULL # Using where; Using index @@ -1067,10 +1106,10 @@ id b c 0 3 4 EXPLAIN SELECT * FROM t1 WHERE b<=3 AND 3<=c; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range idx1,idx2 idx2 4 NULL 3 Using index condition; Using where; Rowid-ordered scan +1 SIMPLE t1 range idx1,idx2 idx2 4 NULL 2 Using index condition; Using where; Rowid-ordered scan EXPLAIN SELECT * FROM t1 WHERE 3 BETWEEN b AND c; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range idx1,idx2 idx2 4 NULL 3 Using where; Rowid-ordered scan +1 SIMPLE t1 range idx1,idx2 idx2 4 NULL 2 Using where; Rowid-ordered scan SELECT * FROM t1 WHERE 0 < b OR 0 > c; id b c 0 3 4 @@ -1081,10 +1120,10 @@ id b c 0 3 4 EXPLAIN SELECT * FROM t1 WHERE 0 < b OR 0 > c; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index_merge idx1,idx2 idx1,idx2 4,4 NULL 4 Using sort_union(idx1,idx2); Using where +1 SIMPLE t1 index_merge idx1,idx2 idx1,idx2 4,4 NULL 3 Using sort_union(idx1,idx2); Using where EXPLAIN SELECT * FROM t1 WHERE 0 NOT BETWEEN b AND c; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index_merge idx1,idx2 idx1,idx2 4,4 NULL 4 Using sort_union(idx1,idx2); Using where +1 SIMPLE t1 index_merge idx1,idx2 idx1,idx2 4,4 NULL 3 Using sort_union(idx1,idx2); Using where DROP TABLE t1; CREATE TABLE t1 ( item char(20) NOT NULL default '', @@ -1099,7 +1138,7 @@ INSERT INTO t1 VALUES ('A2','2005-12-01 08:00:00',1000); EXPLAIN SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref PRIMARY PRIMARY 20 const 2 Using index condition +1 SIMPLE t1 ref PRIMARY PRIMARY 20 const 3 Using index condition SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00'; item started price Warnings: @@ -1143,7 +1182,7 @@ CREATE TABLE t1 ( a varchar(32), index (a) ) DEFAULT CHARSET=latin1 COLLATE=latin1_bin; INSERT INTO t1 VALUES -('B'), ('A'), ('A'), ('C'), ('B'), ('A'), ('A'); +('B'), ('A'), ('A'), ('C'), ('B'), ('A'), ('A'), ('C'), ('A'); SELECT a FROM t1 WHERE a='b' OR a='B'; a B @@ -1203,13 +1242,15 @@ Z In following EXPLAIN the access method should be ref, #rows~=500 (and not 2) explain select * from t2 where a=1000 and b<11; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ref a a 5 const 502 Using index condition +1 SIMPLE t2 ref a a 5 const 503 Using index condition drop table t1, t2; CREATE TABLE t1( a INT, b INT, KEY( a, b ) ); CREATE TABLE t2( a INT, b INT, KEY( a, b ) ); CREATE TABLE t3( a INT, b INT, KEY( a, b ) ); -INSERT INTO t1( a, b ) -VALUES (0, 1), (1, 2), (1, 4), (2, 3), (5, 0), (9, 7); +INSERT INTO t1( a, b ) VALUES +(0, 1), (1, 2), (1, 4), (2, 3), (5, 0), (9, 7), +(10, 11), (11,12), (11, 14), (12, 13), (15, 10), (19, 17), +(20, 21), (21,22), (21, 24), (22, 23), (25, 20), (29, 27); INSERT INTO t2( a, b ) VALUES ( 1, 1), ( 2, 1), ( 3, 1), ( 4, 1), ( 5, 1), ( 6, 1), ( 7, 1), ( 8, 1), ( 9, 1), (10, 1), @@ -1220,65 +1261,67 @@ INSERT INTO t2 SELECT a, 3 FROM t2 WHERE b = 1; INSERT INTO t2 SELECT -1, -1 FROM t2; INSERT INTO t2 SELECT -1, -1 FROM t2; INSERT INTO t2 SELECT -1, -1 FROM t2; -INSERT INTO t3 -VALUES (1, 0), (2, 0), (3, 0), (4, 0), (5, 0), -(6, 0), (7, 0), (8, 0), (9, 0), (10, 0); +INSERT INTO t3 VALUES +(1, 0), (2, 0), (3, 0), (4, 0), (5, 0), +(6, 0), (7, 0), (8, 0), (9, 0), (10, 0), +(11, 0), (12, 0), (13, 0), (14, 0), (15, 0), +(16, 0), (17, 0), (18, 0), (19, 0), (20, 0); INSERT INTO t3 SELECT * FROM t3 WHERE a = 10; INSERT INTO t3 SELECT * FROM t3 WHERE a = 10; SELECT * FROM t1 WHERE -3 <= a AND a < 5 OR -5 < a AND b = 3 OR -3 <= a; +23 <= a AND a < 25 OR +25 < a AND b = 23 OR +23 <= a; a b -5 0 -9 7 +25 20 +29 27 EXPLAIN SELECT * FROM t1 WHERE -3 <= a AND a < 5 OR -5 < a AND b = 3 OR -3 <= a; +23 <= a AND a < 25 OR +25 < a AND b = 23 OR +23 <= a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 3 Using where; Using index +1 SIMPLE t1 range a a 5 NULL 2 Using where; Using index SELECT * FROM t1 WHERE -3 <= a AND a < 5 OR -5 <= a AND b = 3 OR -3 <= a; +23 <= a AND a < 25 OR +25 <= a AND b = 23 OR +23 <= a; a b -5 0 -9 7 +25 20 +29 27 EXPLAIN SELECT * FROM t1 WHERE -3 <= a AND a < 5 OR -5 <= a AND b = 3 OR -3 <= a; +23 <= a AND a < 25 OR +25 <= a AND b = 23 OR +23 <= a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 4 Using where; Using index +1 SIMPLE t1 range a a 5 NULL 3 Using where; Using index SELECT * FROM t1 WHERE -3 <= a AND a <= 5 OR -5 <= a AND b = 3 OR -3 <= a; +23 <= a AND a <= 25 OR +25 <= a AND b = 23 OR +23 <= a; a b -5 0 -9 7 +25 20 +29 27 EXPLAIN SELECT * FROM t1 WHERE -3 <= a AND a <= 5 OR -5 <= a AND b = 3 OR -3 <= a; +23 <= a AND a <= 25 OR +25 <= a AND b = 23 OR +23 <= a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 3 Using where; Using index +1 SIMPLE t1 range a a 5 NULL 2 Using where; Using index SELECT * FROM t1 WHERE -3 <= a AND a <= 5 OR -3 <= a; +23 <= a AND a <= 25 OR +23 <= a; a b -5 0 -9 7 +25 20 +29 27 EXPLAIN SELECT * FROM t1 WHERE -3 <= a AND a <= 5 OR -3 <= a; +23 <= a AND a <= 25 OR +23 <= a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 3 Using where; Using index +1 SIMPLE t1 range a a 5 NULL 2 Using where; Using index SELECT * FROM t2 WHERE 5 <= a AND a < 10 AND b = 1 OR 15 <= a AND a < 20 AND b = 3 @@ -1317,7 +1360,7 @@ SELECT * FROM t2 WHERE OR 1 <= a AND b = 1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range a a 10 NULL 50 Using where; Using index +1 SIMPLE t2 range a a 10 NULL 49 Using where; Using index SELECT * FROM t2 WHERE 5 <= a AND a < 10 AND b = 2 OR 15 <= a AND a < 20 AND b = 3 @@ -1361,7 +1404,7 @@ SELECT * FROM t2 WHERE OR 1 <= a AND b = 1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range a a 10 NULL 50 Using where; Using index +1 SIMPLE t2 range a a 10 NULL 49 Using where; Using index SELECT * FROM t3 WHERE 5 <= a AND a < 10 AND b = 3 OR a < 5 OR @@ -1382,7 +1425,7 @@ SELECT * FROM t3 WHERE a < 5 OR a < 10; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t3 range a a 5 NULL 8 Using where; Using index +1 SIMPLE t3 range a a 5 NULL 9 Using where; Using index DROP TABLE t1, t2, t3; # # Bug #47123: Endless 100% CPU loop with STRAIGHT_JOIN @@ -1400,10 +1443,16 @@ CREATE TABLE t2 ( a DATETIME, KEY ( a ) ); # Make optimizer choose range scan INSERT INTO t1 VALUES ('2009-09-22'), ('2009-09-22'), ('2009-09-22'); INSERT INTO t1 VALUES ('2009-09-23'), ('2009-09-23'), ('2009-09-23'); +INSERT INTO t1 VALUES ('2009-09-20'), ('2009-09-20'), ('2009-09-20'); +INSERT INTO t1 VALUES ('2009-09-21'), ('2009-09-21'), ('2009-09-21'); INSERT INTO t2 VALUES ('2009-09-22 12:00:00'), ('2009-09-22 12:00:00'), ('2009-09-22 12:00:00'); INSERT INTO t2 VALUES ('2009-09-23 12:00:00'), ('2009-09-23 12:00:00'), ('2009-09-23 12:00:00'); +INSERT INTO t2 VALUES ('2009-09-20 12:00:00'), ('2009-09-20 12:00:00'), +('2009-09-20 12:00:00'); +INSERT INTO t2 VALUES ('2009-09-21 12:00:00'), ('2009-09-21 12:00:00'), +('2009-09-21 12:00:00'); # DATE vs DATE EXPLAIN SELECT * FROM t1 WHERE a >= '2009/09/23'; @@ -1658,7 +1707,8 @@ DROP TABLE t1; # CREATE TABLE t1(pk INT PRIMARY KEY, i4 INT); CREATE UNIQUE INDEX i4_uq ON t1(i4); -INSERT INTO t1 VALUES (1,10), (2,20), (3,30); +INSERT INTO t1 VALUES +(1,10), (2,20), (3,30), (4,40), (5,50), (6,60), (7,70), (8,80); EXPLAIN SELECT * FROM t1 WHERE i4 BETWEEN 10 AND 10; id select_type table type possible_keys key key_len ref rows Extra @@ -1674,14 +1724,13 @@ SELECT * FROM t1 WHERE 10 BETWEEN i4 AND i4; pk i4 1 10 EXPLAIN -SELECT * FROM t1 WHERE 10 BETWEEN 10 AND i4; +SELECT * FROM t1 WHERE 70 BETWEEN 70 AND i4; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range i4_uq i4_uq 5 NULL 3 Using index condition; Rowid-ordered scan -SELECT * FROM t1 WHERE 10 BETWEEN 10 AND i4; +1 SIMPLE t1 range i4_uq i4_uq 5 NULL 2 Using index condition; Rowid-ordered scan +SELECT * FROM t1 WHERE 70 BETWEEN 70 AND i4; pk i4 -1 10 -2 20 -3 30 +7 70 +8 80 EXPLAIN SELECT * FROM t1 WHERE 10 BETWEEN i4 AND 10; id select_type table type possible_keys key key_len ref rows Extra @@ -1692,12 +1741,17 @@ pk i4 EXPLAIN SELECT * FROM t1 WHERE 10 BETWEEN 10 AND 10; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 3 +1 SIMPLE t1 ALL NULL NULL NULL NULL 8 SELECT * FROM t1 WHERE 10 BETWEEN 10 AND 10; pk i4 1 10 2 20 3 30 +4 40 +5 50 +6 60 +7 70 +8 80 EXPLAIN SELECT * FROM t1 WHERE 10 BETWEEN 11 AND 11; id select_type table type possible_keys key key_len ref rows Extra @@ -1717,14 +1771,13 @@ id select_type table type possible_keys key key_len ref rows Extra SELECT * FROM t1 WHERE i4 BETWEEN 100 AND 0; pk i4 EXPLAIN -SELECT * FROM t1 WHERE i4 BETWEEN 10 AND 99999999999999999; +SELECT * FROM t1 WHERE i4 BETWEEN 70 AND 99999999999999999; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range i4_uq i4_uq 5 NULL 2 Using index condition; Rowid-ordered scan -SELECT * FROM t1 WHERE i4 BETWEEN 10 AND 99999999999999999; +SELECT * FROM t1 WHERE i4 BETWEEN 70 AND 99999999999999999; pk i4 -1 10 -2 20 -3 30 +7 70 +8 80 EXPLAIN SELECT * FROM t1 WHERE i4 BETWEEN 999999999999999 AND 30; id select_type table type possible_keys key key_len ref rows Extra @@ -1734,7 +1787,7 @@ pk i4 EXPLAIN SELECT * FROM t1 WHERE i4 BETWEEN 10 AND '20'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range i4_uq i4_uq 5 NULL 1 Using index condition; Rowid-ordered scan +1 SIMPLE t1 range i4_uq i4_uq 5 NULL 2 Using index condition; Rowid-ordered scan SELECT * FROM t1 WHERE i4 BETWEEN 10 AND '20'; pk i4 1 10 @@ -1742,14 +1795,14 @@ pk i4 EXPLAIN SELECT * FROM t1, t1 as t2 WHERE t2.pk BETWEEN t1.i4 AND t1.i4; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL i4_uq NULL NULL NULL 3 +1 SIMPLE t1 ALL i4_uq NULL NULL NULL 8 1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.i4 1 Using index condition SELECT * FROM t1, t1 as t2 WHERE t2.pk BETWEEN t1.i4 AND t1.i4; pk i4 pk i4 EXPLAIN SELECT * FROM t1, t1 as t2 WHERE t1.i4 BETWEEN t2.pk AND t2.pk; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL i4_uq NULL NULL NULL 3 +1 SIMPLE t1 ALL i4_uq NULL NULL NULL 8 1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.i4 1 Using index condition SELECT * FROM t1, t1 as t2 WHERE t1.i4 BETWEEN t2.pk AND t2.pk; pk i4 pk i4 @@ -1895,19 +1948,23 @@ insert into t2 select a+16 from t2; insert into t2 select a+32 from t2; insert into t2 select a+64 from t2; explain -select count(*) from t2 left join t1 on (t1.key1 < 3 or t1.key1 > 1020) and t1.key2 < 1000; +select count(*) from t2 left join t1 +on (t1.key1 < 3 or t1.key1 between 920 and 930) and t1.key2 < 1000; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 64 -1 SIMPLE t1 range i1,i2 i1 4 NULL 78 Using where; Rowid-ordered scan; Using join buffer (flat, BNL join) -select count(*) from t2 left join t1 on (t1.key1 < 3 or t1.key1 > 1020) and t1.key2 < 1000; +1 SIMPLE t1 range i1,i2 i1 4 NULL 12 Using where; Rowid-ordered scan; Using join buffer (flat, BNL join) +select count(*) from t2 left join t1 +on (t1.key1 < 3 or t1.key1 between 920 and 930) and t1.key2 < 1000; count(*) -128 +832 explain -select count(*) from t2 left join t1 on (t1.key1 < 3 or t1.key1 > 1020) and t1.key2 < t2.a; +select count(*) from t2 left join t1 +on (t1.key1 < 3 or t1.key1 between 920 and 930) and t1.key2 < t2.a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 64 -1 SIMPLE t1 range i1,i2 i1 4 NULL 78 Using where; Rowid-ordered scan; Using join buffer (flat, BNL join) -select count(*) from t2 left join t1 on (t1.key1 < 3 or t1.key1 > 1020) and t1.key2 < t2.a; +1 SIMPLE t1 range i1,i2 i1 4 NULL 12 Using where; Rowid-ordered scan; Using join buffer (flat, BNL join) +select count(*) from t2 left join t1 +on (t1.key1 < 3 or t1.key1 between 920 and 930) and t1.key2 < t2.a; count(*) 126 drop table t1,t2; @@ -1921,7 +1978,7 @@ insert into t1 values (0,0,0), (2,2,0), (1,1,1), (2,2,1); explain select * from t1 force index (idx) where a >=1 and c <= 1 and a=b and b > 1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range idx idx 5 NULL 3 Using where; Using index +1 SIMPLE t1 index idx idx 15 NULL 4 Using where; Using index select * from t1 force index (idx) where a >=1 and c <= 1 and a=b and b > 1; a b c 2 2 0 @@ -1951,7 +2008,7 @@ INSERT INTO t100(I,J) VALUES(8,26); EXPLAIN SELECT * FROM t100 WHERE I <> 6 OR (I <> 8 AND J = 5); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t100 range I I 10 NULL 4 Using index condition; Using where; Rowid-ordered scan +1 SIMPLE t100 range I I 10 NULL 3 Using index condition; Using where; Rowid-ordered scan SELECT * FROM t100 WHERE I <> 6 OR (I <> 8 AND J = 5); K I J @@ -2274,10 +2331,10 @@ CREATE TABLE t1 (a INT, b INT, KEY(a)); INSERT INTO t1 (a) VALUES (10),(10),(10),(10),(10),(10),(10),(10),(10),(10),(70); EXPLAIN SELECT * FROM t1 WHERE a<>10; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 3 Using index condition; Rowid-ordered scan +1 SIMPLE t1 range a a 5 NULL 2 Using index condition; Rowid-ordered scan EXPLAIN SELECT * FROM t1 WHERE 10<>a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 3 Using index condition; Rowid-ordered scan +1 SIMPLE t1 range a a 5 NULL 2 Using index condition; Rowid-ordered scan SELECT * FROM t1 WHERE a<>10; a b 70 NULL @@ -2335,7 +2392,7 @@ insert into t1 values # range access to t1 by 2-component keys for index idx explain select * from t1 where (a,b) IN ((2, 3),(3,3),(8,8),(7,7)); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range idx idx 10 NULL 7 Using where; Rowid-ordered scan +1 SIMPLE t1 range idx idx 10 NULL 6 Using where; Rowid-ordered scan explain format=json select * from t1 where (a,b) IN ((2, 3),(3,3),(8,8),(7,7)); EXPLAIN { @@ -2348,7 +2405,7 @@ EXPLAIN "key": "idx", "key_length": "10", "used_key_parts": ["a", "b"], - "rows": 7, + "rows": 6, "filtered": 100, "attached_condition": "(t1.a,t1.b) in (<cache>((2,3)),<cache>((3,3)),<cache>((8,8)),<cache>((7,7)))", "mrr_type": "Rowid-ordered scan" @@ -2633,7 +2690,7 @@ insert into t1 select * from t1; explain select * from t1,t2 where a = d and (a,e) in ((4,4),(7,7),(8,8)) and length(f) = 1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range idx1,idx2 idx2 5 NULL 6 Using where; Rowid-ordered scan +1 SIMPLE t2 range idx1,idx2 idx1 5 NULL 7 Using index condition; Using where; Rowid-ordered scan 1 SIMPLE t1 ref idx idx 5 test.t2.d 11 explain format=json select * from t1,t2 where a = d and (a,e) in ((4,4),(7,7),(8,8)) and length(f) = 1; @@ -2645,12 +2702,13 @@ EXPLAIN "table_name": "t2", "access_type": "range", "possible_keys": ["idx1", "idx2"], - "key": "idx2", + "key": "idx1", "key_length": "5", - "used_key_parts": ["e"], - "rows": 6, + "used_key_parts": ["d"], + "rows": 7, "filtered": 100, - "attached_condition": "(t2.d,t2.e) in (<cache>((4,4)),<cache>((7,7)),<cache>((8,8))) and octet_length(t2.f) = 1 and t2.d is not null", + "index_condition": "t2.d is not null", + "attached_condition": "(t2.d,t2.e) in (<cache>((4,4)),<cache>((7,7)),<cache>((8,8))) and octet_length(t2.f) = 1", "mrr_type": "Rowid-ordered scan" }, "table": { @@ -2838,7 +2896,7 @@ explain select * from t1,t2 where a = d and (a,2) in ((2,2),(7,7),(8,8)) and length(c) = 1 and length(f) = 1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range idx idx 5 NULL 13 Using index condition; Using where; Rowid-ordered scan +1 SIMPLE t1 range idx idx 5 NULL 12 Using index condition; Using where; Rowid-ordered scan 1 SIMPLE t2 ref idx3 idx3 5 test.t1.a 3 Using where explain format=json select * from t1,t2 where a = d and (a,2) in ((2,2),(7,7),(8,8)) and @@ -2854,7 +2912,7 @@ EXPLAIN "key": "idx", "key_length": "5", "used_key_parts": ["a"], - "rows": 13, + "rows": 12, "filtered": 100, "index_condition": "t1.a is not null", "attached_condition": "(t1.a,2) in (<cache>((2,2)),<cache>((7,7)),<cache>((8,8))) and octet_length(t1.c) = 1", @@ -2915,7 +2973,7 @@ where id = 1 and a = d and length(c) = 1 and length(f) = 1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t3 const PRIMARY PRIMARY 4 const 1 -1 SIMPLE t1 range idx idx 5 NULL 13 Using index condition; Using where; Rowid-ordered scan +1 SIMPLE t1 range idx idx 5 NULL 12 Using index condition; Using where; Rowid-ordered scan 1 SIMPLE t2 ref idx3 idx3 5 test.t1.a 3 Using where explain format=json select * from t1,t2,t3 where id = 1 and a = d and @@ -2943,7 +3001,7 @@ EXPLAIN "key": "idx", "key_length": "5", "used_key_parts": ["a"], - "rows": 13, + "rows": 12, "filtered": 100, "index_condition": "t1.a is not null", "attached_condition": "(t1.a,1 + 1) in (<cache>((2,2)),<cache>((7,7)),<cache>((8,8))) and octet_length(t1.c) = 1", @@ -3036,4 +3094,7 @@ drop table t1; # # End of 10.2 tests # +set global innodb_stats_persistent= @innodb_stats_persistent_save; +set global innodb_stats_persistent_sample_pages= +@innodb_stats_persistent_sample_pages_save; set optimizer_switch=@mrr_icp_extra_tmp; diff --git a/mysql-test/main/range_mrr_icp.test b/mysql-test/main/range_mrr_icp.test index 29e7af321db..4c6983c742f 100644 --- a/mysql-test/main/range_mrr_icp.test +++ b/mysql-test/main/range_mrr_icp.test @@ -1,5 +1,6 @@ set @mrr_icp_extra_tmp=@@optimizer_switch; set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; +set optimizer_switch='rowid_filter=off'; --source range.test diff --git a/mysql-test/main/range_vs_index_merge.result b/mysql-test/main/range_vs_index_merge.result index bc46a4fdd0b..d332156659f 100644 --- a/mysql-test/main/range_vs_index_merge.result +++ b/mysql-test/main/range_vs_index_merge.result @@ -64,7 +64,7 @@ Country IN ('CAN', 'ARG') AND ID BETWEEN 120 AND 130 OR Country <= 'ALB' AND Name LIKE 'L%' OR ID BETWEEN 3807 AND 3810; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge PRIMARY,Population,Country,Name Name,PRIMARY,Country 35,4,3 NULL 31 Using sort_union(Name,PRIMARY,Country); Using where +1 SIMPLE City index_merge PRIMARY,Population,Country,Name Name,PRIMARY,Country 35,4,3 NULL 30 Using sort_union(Name,PRIMARY,Country); Using where EXPLAIN SELECT * FROM City WHERE (Population > 101000 AND Population < 115000); @@ -175,7 +175,7 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN SELECT * FROM City WHERE (Name < 'Bb'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Name Name 35 NULL 208 Using index condition +1 SIMPLE City range Name Name 35 NULL 207 Using index condition EXPLAIN SELECT * FROM City WHERE (Country > 'A' AND Country < 'B'); id select_type table type possible_keys key key_len ref rows Extra @@ -327,11 +327,11 @@ ID Name Country Population EXPLAIN SELECT * FROM City WHERE (ID < 10) OR (ID BETWEEN 100 AND 110); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 21 Using index condition; Using where +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 20 Using index condition; Using where EXPLAIN SELECT * FROM City WHERE (ID < 200) OR (ID BETWEEN 100 AND 200); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 201 Using index condition; Using where +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 200 Using index condition; Using where EXPLAIN SELECT * FROM City WHERE (ID < 600) OR (ID BETWEEN 900 AND 1500); id select_type table type possible_keys key key_len ref rows Extra @@ -339,11 +339,11 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN SELECT * FROM City WHERE Country > 'A' AND Country < 'ARG'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Country Country 3 NULL 19 Using index condition +1 SIMPLE City range Country Country 3 NULL 20 Using index condition EXPLAIN SELECT * FROM City WHERE Name LIKE 'H%' OR Name LIKE 'P%' ; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Name Name 35 NULL 222 Using index condition; Using where +1 SIMPLE City range Name Name 35 NULL 223 Using index condition; Using where EXPLAIN SELECT * FROM City WHERE Name LIKE 'Ha%' OR Name LIKE 'Pa%' ; id select_type table type possible_keys key key_len ref rows Extra @@ -354,21 +354,21 @@ WHERE ((ID < 10) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) OR ((ID BETWEEN 100 AND 110) AND (Name LIKE 'P%' OR (Population > 103000 AND Population < 104000))); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 21 Using index condition; Using where +1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 20 Using index condition; Using where EXPLAIN SELECT * FROM City WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) OR ((ID BETWEEN 900 AND 1500) AND -(Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); +(Name LIKE 'Pa%' OR (Population > 103000 AND Population < 105000))); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge PRIMARY,Population,Country,Name Name,Country,Population 35,3,4 NULL 128 Using sort_union(Name,Country,Population); Using where +1 SIMPLE City index_merge PRIMARY,Population,Country,Name Name,Country,Population 35,3,4 NULL 151 Using sort_union(Name,Country,Population); Using where EXPLAIN SELECT * FROM City WHERE ((ID < 200) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) OR ((ID BETWEEN 100 AND 200) AND -(Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); +(Name LIKE 'Pa%' OR (Population > 103200 AND Population < 104000))); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge PRIMARY,Population,Country,Name Name,Country,Population 35,3,4 NULL 128 Using sort_union(Name,Country,Population); Using where +1 SIMPLE City index_merge PRIMARY,Population,Country,Name Name,Country,Population 35,3,4 NULL 124 Using sort_union(Name,Country,Population); Using where SELECT * FROM City USE INDEX () WHERE ((ID < 10) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) OR ((ID BETWEEN 100 AND 110) AND @@ -584,11 +584,11 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN SELECT * FROM City WHERE Country < 'C'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Country Country 3 NULL 436 Using index condition +1 SIMPLE City range Country Country 3 NULL 435 Using index condition EXPLAIN SELECT * FROM City WHERE Country < 'AGO'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Country Country 3 NULL 6 Using index condition +1 SIMPLE City range Country Country 3 NULL 5 Using index condition EXPLAIN SELECT * FROM City WHERE Name BETWEEN 'P' AND 'S'; id select_type table type possible_keys key key_len ref rows Extra @@ -616,7 +616,7 @@ WHERE ((Population > 101000 AND Population < 102000) AND ((ID BETWEEN 3400 AND 3800) AND (Country < 'AGO' OR Name LIKE 'Pa%')); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge PRIMARY,Population,Country,Name Country,Name,Population 3,35,4 NULL 84 Using sort_union(Country,Name,Population); Using where +1 SIMPLE City index_merge PRIMARY,Population,Country,Name Country,Name,Population 3,35,4 NULL 83 Using sort_union(Country,Name,Population); Using where EXPLAIN SELECT * FROM City WHERE ((Population > 101000 AND Population < 110000) AND @@ -624,7 +624,7 @@ WHERE ((Population > 101000 AND Population < 110000) AND ((ID BETWEEN 3790 AND 3800) AND (Country < 'C' OR Name LIKE 'P%')); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge PRIMARY,Population,Country,Name Country,Name,PRIMARY 3,35,4 NULL 56 Using sort_union(Country,Name,PRIMARY); Using where +1 SIMPLE City index_merge PRIMARY,Population,Country,Name Country,Name,PRIMARY 3,35,4 NULL 55 Using sort_union(Country,Name,PRIMARY); Using where SELECT * FROM City USE INDEX () WHERE ((Population > 101000 AND Population < 102000) AND (Country < 'C' OR Name BETWEEN 'P' AND 'S')) OR @@ -679,7 +679,7 @@ CREATE INDEX CountryPopulation ON City(Country,Population); EXPLAIN SELECT * FROM City WHERE Name LIKE 'Pas%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Name Name 35 NULL 5 Using index condition +1 SIMPLE City range Name Name 35 NULL 4 Using index condition EXPLAIN SELECT * FROM City WHERE Name LIKE 'P%'; id select_type table type possible_keys key key_len ref rows Extra @@ -695,19 +695,19 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN SELECT * FROM City WHERE Country='FIN'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City ref Country,CountryPopulation Country 3 const 6 Using index condition +1 SIMPLE City ref Country,CountryPopulation Country 3 const 7 Using index condition EXPLAIN SELECT * FROM City WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%') AND Country='USA'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge Population,Country,Name,CountryPopulation CountryPopulation,Name 7,35 NULL 15 Using sort_union(CountryPopulation,Name); Using where +1 SIMPLE City index_merge Population,Country,Name,CountryPopulation CountryPopulation,Name 7,35 NULL 14 Using sort_union(CountryPopulation,Name); Using where EXPLAIN SELECT * FROM City WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%') AND Country='FIN'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City ref Population,Country,Name,CountryPopulation Country 3 const 6 Using index condition; Using where +1 SIMPLE City ref Population,Country,Name,CountryPopulation Country 3 const 7 Using index condition; Using where SELECT * FROM City WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%') AND Country='USA'; @@ -1166,7 +1166,7 @@ EXPLAIN SELECT Name, Country, Population FROM City WHERE (Name='Samara' AND Country='RUS') OR (Name='Seattle' AND Country='USA'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Country,CountryPopulation,CountryName,CityName CountryName 38 NULL 29 Using index condition; Using where +1 SIMPLE City range Country,CountryPopulation,CountryName,CityName CountryName 38 NULL 28 Using index condition; Using where SELECT Name, Country, Population FROM City WHERE (Name='Manila' AND Country='PHL') OR (Name='Addis Abeba' AND Country='ETH') OR @@ -1620,7 +1620,7 @@ SELECT COUNT(*) FROM t1 WHERE c = 'i' OR b IN ( 'Arkansas' , 'd' , 'pdib' , 'can' ) OR (pk BETWEEN 120 AND 79 + 255 OR a IN ( 4 , 179 , 1 ) ) AND a > 8 ; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index_merge PRIMARY,idx1,idx2,idx3 idx3,idx2,PRIMARY,idx1 67,13,4,3 NULL 8 Using sort_union(idx3,idx2,PRIMARY,idx1); Using where +1 SIMPLE t1 index_merge PRIMARY,idx1,idx2,idx3 idx3,idx2,PRIMARY,idx1 67,13,4,3 NULL 9 Using sort_union(idx3,idx2,PRIMARY,idx1); Using where DROP TABLE t1; CREATE TABLE t1 ( f1 int, f2 int, f3 int, f4 int, f5 int, @@ -1659,7 +1659,7 @@ SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4) WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10 OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 ); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL PRIMARY,f3,f4 NULL NULL NULL 2 Using where +1 SIMPLE t1 index_merge PRIMARY,f3,f4 f3,PRIMARY,f3 5,4,5 NULL 3 Using union(f3,PRIMARY,f3); Using where SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4) WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10 OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 ); @@ -1713,6 +1713,9 @@ PRIMARY KEY(b), INDEX idx1(d), INDEX idx2(d,b,c) INSERT INTO t1 VALUES (0,58,7,7),(0,63,2,0),(0,64,186,8),(0,65,1,-2), (0,71,190,-3), (0,72,321,-7),(0,73,0,3),(0,74,5,25),(0,75,5,3); +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK SET SESSION optimizer_switch='index_merge_sort_union=off'; EXPLAIN SELECT * FROM t1 @@ -1762,7 +1765,7 @@ EXPLAIN SELECT * FROM t1 WHERE a BETWEEN 4 AND 5 AND b IN (255,4) OR a IN (2,14,25) OR a!=2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL PRIMARY,idx NULL NULL NULL 2 Using where +1 SIMPLE t1 range PRIMARY,idx PRIMARY 0 NULL 2 Using index condition; Using where SELECT * FROM t1 WHERE a BETWEEN 4 AND 5 AND b IN (255,4) OR a IN (2,14,25) OR a!=2; a b @@ -1790,12 +1793,15 @@ INSERT INTO t1 VALUES (7,'Pennsylvania','Harrisburg'), (8,'Virginia','Richmond') ; +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK EXPLAIN SELECT * FROM t1 FORCE KEY (state,capital) WHERE ( state = 'Alabama' OR state >= 'Colorado' ) AND id != 9 OR ( capital >= 'Topeka' OR state = 'Kansas' ) AND state != 'Texas'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range state,capital state 71 NULL 12 Using index condition; Using where +1 SIMPLE t1 range state,capital state 71 NULL 8 Using index condition; Using where SELECT * FROM t1 FORCE KEY (state,capital) WHERE ( state = 'Alabama' OR state >= 'Colorado' ) AND id != 9 OR ( capital >= 'Topeka' OR state = 'Kansas' ) AND state != 'Texas'; @@ -1886,6 +1892,6 @@ Country='POL' AND Name IN ('Warszawa', 'Wroclaw') OR Country='NOR' AND Name IN ('Oslo', 'Bergen') OR Country='ITA' AND Name IN ('Napoli', 'Venezia'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range CountryName,Name CountryName 38 NULL 22 Using index condition; Using where +1 SIMPLE City range CountryName,Name CountryName 38 NULL 20 Using index condition; Using where DROP DATABASE world; set session optimizer_switch='index_merge_sort_intersection=default'; diff --git a/mysql-test/main/range_vs_index_merge.test b/mysql-test/main/range_vs_index_merge.test index 84b87579e85..0cff070fe68 100644 --- a/mysql-test/main/range_vs_index_merge.test +++ b/mysql-test/main/range_vs_index_merge.test @@ -229,13 +229,13 @@ EXPLAIN SELECT * FROM City WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) OR ((ID BETWEEN 900 AND 1500) AND - (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); + (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 105000))); EXPLAIN SELECT * FROM City WHERE ((ID < 200) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) OR ((ID BETWEEN 100 AND 200) AND - (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); + (Name LIKE 'Pa%' OR (Population > 103200 AND Population < 104000))); # The following 6 queries check that the plans @@ -1158,6 +1158,8 @@ INSERT INTO t1 VALUES (0,58,7,7),(0,63,2,0),(0,64,186,8),(0,65,1,-2), (0,71,190,-3), (0,72,321,-7),(0,73,0,3),(0,74,5,25),(0,75,5,3); +ANALYZE TABLE t1; + SET SESSION optimizer_switch='index_merge_sort_union=off'; EXPLAIN SELECT * FROM t1 @@ -1230,6 +1232,8 @@ INSERT INTO t1 VALUES (7,'Pennsylvania','Harrisburg'), (8,'Virginia','Richmond') ; + +ANALYZE TABLE t1; EXPLAIN SELECT * FROM t1 FORCE KEY (state,capital) diff --git a/mysql-test/main/range_vs_index_merge_innodb.result b/mysql-test/main/range_vs_index_merge_innodb.result index ce90f522d6e..8b592c710a8 100644 --- a/mysql-test/main/range_vs_index_merge_innodb.result +++ b/mysql-test/main/range_vs_index_merge_innodb.result @@ -1,4 +1,9 @@ SET SESSION STORAGE_ENGINE='InnoDB'; +set @innodb_stats_persistent_save= @@innodb_stats_persistent; +set @innodb_stats_persistent_sample_pages_save= +@@innodb_stats_persistent_sample_pages; +set global innodb_stats_persistent= 1; +set global innodb_stats_persistent_sample_pages=100; DROP TABLE IF EXISTS t1,t2,t3,t4; DROP DATABASE IF EXISTS world; set names utf8; @@ -360,16 +365,16 @@ EXPLAIN SELECT * FROM City WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) OR ((ID BETWEEN 900 AND 1500) AND -(Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); +(Name LIKE 'Pa%' OR (Population > 103000 AND Population < 105000))); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City index_merge PRIMARY,Population,Country,Name Name,Country,PRIMARY 39,3,4 NULL 683 Using sort_union(Name,Country,PRIMARY); Using where EXPLAIN SELECT * FROM City WHERE ((ID < 200) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) OR ((ID BETWEEN 100 AND 200) AND -(Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); +(Name LIKE 'Pa%' OR (Population > 103200 AND Population < 104000))); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge PRIMARY,Population,Country,Name Name,Population,PRIMARY 39,4,4 NULL 307 Using sort_union(Name,Population,PRIMARY); Using where +1 SIMPLE City index_merge PRIMARY,Population,Country,Name Name,Population,PRIMARY 39,4,4 NULL 302 Using sort_union(Name,Population,PRIMARY); Using where SELECT * FROM City USE INDEX () WHERE ((ID < 10) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) OR ((ID BETWEEN 100 AND 110) AND @@ -1080,7 +1085,7 @@ EXPLAIN SELECT Name, Country, Population FROM City WHERE (Name='Samara' AND Country='RUS') OR (Name='Seattle' AND Country='USA'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Country,CountryPopulation,CountryName,CityName CountryName 38 NULL 27 Using index condition; Using where +1 SIMPLE City index_merge Country,CountryPopulation,CountryName,CityName CountryName,CityName 38,35 NULL 27 Using sort_union(CountryName,CityName); Using where SELECT Name, Country, Population FROM City WHERE (Name='Manila' AND Country='PHL') OR (Name='Addis Abeba' AND Country='ETH') OR @@ -1110,33 +1115,33 @@ SELECT Name, Country, Population FROM City WHERE (Name='Samara' AND Country='RUS') OR (Name='Seattle' AND Country='USA'); Name Country Population -Toronto CAN 688275 -Vancouver CAN 514008 -Basel CHE 166700 -Peking CHN 7472000 -Praha CZE 1181126 -Dresden DEU 476668 Addis Abeba ETH 2495000 -Paris FRA 2125246 +Manila PHL 1581082 Jakarta IDN 9604900 -Bangalore IND 2660088 Delhi IND 7206704 +Bangalore IND 2660088 Teheran IRN 6758845 Roma ITA 2643581 Venezia ITA 277305 Tokyo JPN 7980230 +Toronto CAN 688275 +Vancouver CAN 514008 +Peking CHN 7472000 Seoul KOR 9981619 Kaunas LTU 412639 Rabat MAR 623457 Tijuana MEX 1212232 Lagos NGA 1518000 -Manila PHL 1581082 -Samara RUS 1156100 +Paris FRA 2125246 +Dresden DEU 476668 Dakar SEN 785071 +Basel CHE 166700 +Praha CZE 1181126 Ankara TUR 3038159 Lugansk UKR 469000 -Seattle USA 563374 Caracas VEN 1975294 +Samara RUS 1156100 +Seattle USA 563374 set optimizer_switch='index_merge=off'; EXPLAIN SELECT Name, Country, Population FROM City WHERE (Name='Manila' AND Country='PHL') OR @@ -1167,7 +1172,7 @@ EXPLAIN SELECT Name, Country, Population FROM City WHERE (Name='Samara' AND Country='RUS') OR (Name='Seattle' AND Country='USA'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Country,CountryPopulation,CountryName,CityName CountryName 38 NULL 27 Using index condition; Using where +1 SIMPLE City range Country,CountryPopulation,CountryName,CityName CityName 35 NULL 28 Using index condition; Using where SELECT Name, Country, Population FROM City WHERE (Name='Manila' AND Country='PHL') OR (Name='Addis Abeba' AND Country='ETH') OR @@ -1197,33 +1202,33 @@ SELECT Name, Country, Population FROM City WHERE (Name='Samara' AND Country='RUS') OR (Name='Seattle' AND Country='USA'); Name Country Population -Toronto CAN 688275 -Vancouver CAN 514008 -Basel CHE 166700 -Peking CHN 7472000 -Praha CZE 1181126 -Dresden DEU 476668 Addis Abeba ETH 2495000 -Paris FRA 2125246 -Jakarta IDN 9604900 +Ankara TUR 3038159 Bangalore IND 2660088 +Basel CHE 166700 +Caracas VEN 1975294 +Dakar SEN 785071 Delhi IND 7206704 -Teheran IRN 6758845 -Roma ITA 2643581 -Venezia ITA 277305 -Tokyo JPN 7980230 -Seoul KOR 9981619 +Dresden DEU 476668 +Jakarta IDN 9604900 Kaunas LTU 412639 -Rabat MAR 623457 -Tijuana MEX 1212232 Lagos NGA 1518000 +Lugansk UKR 469000 Manila PHL 1581082 +Paris FRA 2125246 +Peking CHN 7472000 +Praha CZE 1181126 +Rabat MAR 623457 +Roma ITA 2643581 Samara RUS 1156100 -Dakar SEN 785071 -Ankara TUR 3038159 -Lugansk UKR 469000 Seattle USA 563374 -Caracas VEN 1975294 +Seoul KOR 9981619 +Teheran IRN 6758845 +Tijuana MEX 1212232 +Tokyo JPN 7980230 +Toronto CAN 688275 +Vancouver CAN 514008 +Venezia ITA 277305 set optimizer_switch=@save_optimizer_switch; # # Bug mdev-585: range vs index-merge with ORDER BY ... LIMIT n @@ -1714,6 +1719,9 @@ PRIMARY KEY(b), INDEX idx1(d), INDEX idx2(d,b,c) INSERT INTO t1 VALUES (0,58,7,7),(0,63,2,0),(0,64,186,8),(0,65,1,-2), (0,71,190,-3), (0,72,321,-7),(0,73,0,3),(0,74,5,25),(0,75,5,3); +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK SET SESSION optimizer_switch='index_merge_sort_union=off'; EXPLAIN SELECT * FROM t1 @@ -1751,7 +1759,7 @@ SELECT * FROM t1 WHERE t1.a>300 AND t1.c!=0 AND t1.b>=350 AND t1.b<=400 AND (t1.c=0 OR t1.a=500); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY,idx PRIMARY 4 NULL 1 Using where +1 SIMPLE t1 index PRIMARY,idx idx 10 NULL 2 Using where; Using index SELECT * FROM t1 WHERE t1.a>300 AND t1.c!=0 AND t1.b>=350 AND t1.b<=400 AND (t1.c=0 OR t1.a=500); @@ -1791,12 +1799,15 @@ INSERT INTO t1 VALUES (7,'Pennsylvania','Harrisburg'), (8,'Virginia','Richmond') ; +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK EXPLAIN SELECT * FROM t1 FORCE KEY (state,capital) WHERE ( state = 'Alabama' OR state >= 'Colorado' ) AND id != 9 OR ( capital >= 'Topeka' OR state = 'Kansas' ) AND state != 'Texas'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range state,capital state 71 NULL 12 Using index condition; Using where +1 SIMPLE t1 range state,capital state 71 NULL 8 Using index condition; Using where SELECT * FROM t1 FORCE KEY (state,capital) WHERE ( state = 'Alabama' OR state >= 'Colorado' ) AND id != 9 OR ( capital >= 'Topeka' OR state = 'Kansas' ) AND state != 'Texas'; @@ -1890,4 +1901,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City range CountryName,Name CountryName 38 NULL 20 Using index condition; Using where DROP DATABASE world; set session optimizer_switch='index_merge_sort_intersection=default'; +set global innodb_stats_persistent= @innodb_stats_persistent_save; +set global innodb_stats_persistent_sample_pages= +@innodb_stats_persistent_sample_pages_save; SET SESSION STORAGE_ENGINE=DEFAULT; diff --git a/mysql-test/main/range_vs_index_merge_innodb.test b/mysql-test/main/range_vs_index_merge_innodb.test index 31870ccd9c6..5117ee3668a 100644 --- a/mysql-test/main/range_vs_index_merge_innodb.test +++ b/mysql-test/main/range_vs_index_merge_innodb.test @@ -2,6 +2,15 @@ SET SESSION STORAGE_ENGINE='InnoDB'; +set @innodb_stats_persistent_save= @@innodb_stats_persistent; +set @innodb_stats_persistent_sample_pages_save= + @@innodb_stats_persistent_sample_pages; + +set global innodb_stats_persistent= 1; +set global innodb_stats_persistent_sample_pages=100; --source range_vs_index_merge.test +set global innodb_stats_persistent= @innodb_stats_persistent_save; +set global innodb_stats_persistent_sample_pages= + @innodb_stats_persistent_sample_pages_save; SET SESSION STORAGE_ENGINE=DEFAULT; diff --git a/mysql-test/main/rowid_filter.result b/mysql-test/main/rowid_filter.result new file mode 100644 index 00000000000..9420d7209a3 --- /dev/null +++ b/mysql-test/main/rowid_filter.result @@ -0,0 +1,716 @@ +DROP DATABASE IF EXISTS dbt3_s001; +CREATE DATABASE dbt3_s001; +use dbt3_s001; +CREATE INDEX i_l_quantity ON lineitem(l_quantity); +CREATE INDEX i_o_totalprice ON orders(o_totalprice); +set @save_use_stat_tables= @@use_stat_tables; +set @@use_stat_tables=preferably; +ANALYZE TABLE lineitem, orders; +show create table lineitem; +Table Create Table +lineitem CREATE TABLE `lineitem` ( + `l_orderkey` int(11) NOT NULL DEFAULT 0, + `l_partkey` int(11) DEFAULT NULL, + `l_suppkey` int(11) DEFAULT NULL, + `l_linenumber` int(11) NOT NULL DEFAULT 0, + `l_quantity` double DEFAULT NULL, + `l_extendedprice` double DEFAULT NULL, + `l_discount` double DEFAULT NULL, + `l_tax` double DEFAULT NULL, + `l_returnflag` char(1) DEFAULT NULL, + `l_linestatus` char(1) DEFAULT NULL, + `l_shipDATE` date DEFAULT NULL, + `l_commitDATE` date DEFAULT NULL, + `l_receiptDATE` date DEFAULT NULL, + `l_shipinstruct` char(25) DEFAULT NULL, + `l_shipmode` char(10) DEFAULT NULL, + `l_comment` varchar(44) DEFAULT NULL, + PRIMARY KEY (`l_orderkey`,`l_linenumber`), + KEY `i_l_shipdate` (`l_shipDATE`), + KEY `i_l_suppkey_partkey` (`l_partkey`,`l_suppkey`), + KEY `i_l_partkey` (`l_partkey`), + KEY `i_l_suppkey` (`l_suppkey`), + KEY `i_l_receiptdate` (`l_receiptDATE`), + KEY `i_l_orderkey` (`l_orderkey`), + KEY `i_l_orderkey_quantity` (`l_orderkey`,`l_quantity`), + KEY `i_l_commitdate` (`l_commitDATE`), + KEY `i_l_quantity` (`l_quantity`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +show create table orders; +Table Create Table +orders CREATE TABLE `orders` ( + `o_orderkey` int(11) NOT NULL, + `o_custkey` int(11) DEFAULT NULL, + `o_orderstatus` char(1) DEFAULT NULL, + `o_totalprice` double DEFAULT NULL, + `o_orderDATE` date DEFAULT NULL, + `o_orderpriority` char(15) DEFAULT NULL, + `o_clerk` char(15) DEFAULT NULL, + `o_shippriority` int(11) DEFAULT NULL, + `o_comment` varchar(79) DEFAULT NULL, + PRIMARY KEY (`o_orderkey`), + KEY `i_o_orderdate` (`o_orderDATE`), + KEY `i_o_custkey` (`o_custkey`), + KEY `i_o_totalprice` (`o_totalprice`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +set optimizer_use_condition_selectivity=2; +set statement optimizer_switch='rowid_filter=on' for EXPLAIN SELECT l_orderkey, l_linenumber, l_shipdate, l_quantity FROM lineitem +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE lineitem range|filter i_l_shipdate,i_l_quantity i_l_shipdate|i_l_quantity 4|9 NULL 509 (11%) Using index condition; Using where; Using filter +set statement optimizer_switch='rowid_filter=on' for EXPLAIN FORMAT=JSON SELECT l_orderkey, l_linenumber, l_shipdate, l_quantity FROM lineitem +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "lineitem", + "access_type": "range", + "possible_keys": ["i_l_shipdate", "i_l_quantity"], + "key": "i_l_shipdate", + "key_length": "4", + "used_key_parts": ["l_shipDATE"], + "rowid_filter": { + "range": { + "key": "i_l_quantity", + "used_key_parts": ["l_quantity"] + }, + "rows": 662, + "selectivity_pct": 11.024 + }, + "rows": 509, + "filtered": 11.024, + "index_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'", + "attached_condition": "lineitem.l_quantity > 45" + } + } +} +set statement optimizer_switch='rowid_filter=on' for SELECT l_orderkey, l_linenumber, l_shipdate, l_quantity FROM lineitem +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45; +l_orderkey l_linenumber l_shipdate l_quantity +1121 5 1997-04-27 47 +1121 6 1997-04-21 50 +1441 7 1997-06-07 50 +1443 1 1997-02-05 47 +1473 1 1997-05-05 50 +1568 2 1997-04-06 46 +1632 1 1997-01-25 47 +1632 3 1997-01-29 47 +1954 7 1997-06-04 49 +1959 1 1997-05-05 46 +2151 3 1997-01-20 49 +2177 5 1997-05-10 46 +2369 2 1997-01-02 47 +2469 3 1997-01-11 48 +2469 6 1997-03-03 49 +2470 2 1997-06-02 50 +260 1 1997-03-24 50 +288 2 1997-04-19 49 +289 4 1997-03-14 48 +3009 1 1997-03-19 48 +3105 3 1997-02-28 48 +3106 2 1997-02-27 49 +3429 1 1997-04-08 48 +3490 2 1997-06-27 50 +3619 1 1997-01-22 49 +3619 3 1997-01-31 46 +3969 3 1997-05-29 46 +4005 4 1997-01-31 49 +4036 1 1997-06-21 46 +4066 4 1997-02-17 49 +4098 1 1997-01-26 46 +422 3 1997-06-21 46 +4258 3 1997-01-02 46 +4421 2 1997-04-21 46 +4421 3 1997-05-25 46 +4453 3 1997-05-29 48 +4484 7 1997-03-17 50 +4609 3 1997-02-11 46 +484 1 1997-03-06 49 +484 3 1997-01-24 50 +484 5 1997-03-05 48 +485 1 1997-03-28 50 +4868 1 1997-04-29 47 +4868 3 1997-04-23 49 +4934 1 1997-05-20 48 +4967 1 1997-05-27 50 +5090 2 1997-04-05 46 +5152 2 1997-03-10 50 +5158 4 1997-04-10 49 +5606 3 1997-03-11 46 +5606 7 1997-02-01 46 +5762 4 1997-03-02 47 +581 3 1997-02-27 49 +5829 5 1997-01-31 49 +5831 4 1997-02-24 46 +5895 2 1997-04-27 47 +5895 3 1997-03-15 49 +5952 1 1997-06-30 49 +705 1 1997-04-18 46 +836 3 1997-03-21 46 +set statement optimizer_switch='rowid_filter=off' for EXPLAIN SELECT l_orderkey, l_linenumber, l_shipdate, l_quantity FROM lineitem +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE lineitem range i_l_shipdate,i_l_quantity i_l_shipdate 4 NULL 509 Using index condition; Using where +set statement optimizer_switch='rowid_filter=off' for EXPLAIN FORMAT=JSON SELECT l_orderkey, l_linenumber, l_shipdate, l_quantity FROM lineitem +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "lineitem", + "access_type": "range", + "possible_keys": ["i_l_shipdate", "i_l_quantity"], + "key": "i_l_shipdate", + "key_length": "4", + "used_key_parts": ["l_shipDATE"], + "rows": 509, + "filtered": 11.024, + "index_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'", + "attached_condition": "lineitem.l_quantity > 45" + } + } +} +set statement optimizer_switch='rowid_filter=off' for SELECT l_orderkey, l_linenumber, l_shipdate, l_quantity FROM lineitem +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45; +l_orderkey l_linenumber l_shipdate l_quantity +1121 5 1997-04-27 47 +1121 6 1997-04-21 50 +1441 7 1997-06-07 50 +1443 1 1997-02-05 47 +1473 1 1997-05-05 50 +1568 2 1997-04-06 46 +1632 1 1997-01-25 47 +1632 3 1997-01-29 47 +1954 7 1997-06-04 49 +1959 1 1997-05-05 46 +2151 3 1997-01-20 49 +2177 5 1997-05-10 46 +2369 2 1997-01-02 47 +2469 3 1997-01-11 48 +2469 6 1997-03-03 49 +2470 2 1997-06-02 50 +260 1 1997-03-24 50 +288 2 1997-04-19 49 +289 4 1997-03-14 48 +3009 1 1997-03-19 48 +3105 3 1997-02-28 48 +3106 2 1997-02-27 49 +3429 1 1997-04-08 48 +3490 2 1997-06-27 50 +3619 1 1997-01-22 49 +3619 3 1997-01-31 46 +3969 3 1997-05-29 46 +4005 4 1997-01-31 49 +4036 1 1997-06-21 46 +4066 4 1997-02-17 49 +4098 1 1997-01-26 46 +422 3 1997-06-21 46 +4258 3 1997-01-02 46 +4421 2 1997-04-21 46 +4421 3 1997-05-25 46 +4453 3 1997-05-29 48 +4484 7 1997-03-17 50 +4609 3 1997-02-11 46 +484 1 1997-03-06 49 +484 3 1997-01-24 50 +484 5 1997-03-05 48 +485 1 1997-03-28 50 +4868 1 1997-04-29 47 +4868 3 1997-04-23 49 +4934 1 1997-05-20 48 +4967 1 1997-05-27 50 +5090 2 1997-04-05 46 +5152 2 1997-03-10 50 +5158 4 1997-04-10 49 +5606 3 1997-03-11 46 +5606 7 1997-02-01 46 +5762 4 1997-03-02 47 +581 3 1997-02-27 49 +5829 5 1997-01-31 49 +5831 4 1997-02-24 46 +5895 2 1997-04-27 47 +5895 3 1997-03-15 49 +5952 1 1997-06-30 49 +705 1 1997-04-18 46 +836 3 1997-03-21 46 +set statement optimizer_switch='rowid_filter=on' for EXPLAIN SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-01-31' AND +o_totalprice between 200000 and 230000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE lineitem range PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_shipdate 4 NULL 98 Using index condition +1 SIMPLE orders eq_ref|filter PRIMARY,i_o_totalprice PRIMARY|i_o_totalprice 4|9 dbt3_s001.lineitem.l_orderkey 1 (5%) Using where; Using filter +set statement optimizer_switch='rowid_filter=on' for EXPLAIN FORMAT=JSON SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-01-31' AND +o_totalprice between 200000 and 230000; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "lineitem", + "access_type": "range", + "possible_keys": [ + "PRIMARY", + "i_l_shipdate", + "i_l_orderkey", + "i_l_orderkey_quantity" + ], + "key": "i_l_shipdate", + "key_length": "4", + "used_key_parts": ["l_shipDATE"], + "rows": 98, + "filtered": 100, + "index_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-01-31'" + }, + "table": { + "table_name": "orders", + "access_type": "eq_ref", + "possible_keys": ["PRIMARY", "i_o_totalprice"], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["o_orderkey"], + "ref": ["dbt3_s001.lineitem.l_orderkey"], + "rowid_filter": { + "range": { + "key": "i_o_totalprice", + "used_key_parts": ["o_totalprice"] + }, + "rows": 81, + "selectivity_pct": 5.4 + }, + "rows": 1, + "filtered": 5.4, + "attached_condition": "orders.o_totalprice between 200000 and 230000" + } + } +} +set statement optimizer_switch='rowid_filter=on' for SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-01-31' AND +o_totalprice between 200000 and 230000; +o_orderkey l_linenumber l_shipdate o_totalprice +1156 3 1997-01-24 217682.81 +1156 4 1997-01-18 217682.81 +1156 6 1997-01-27 217682.81 +1156 7 1997-01-01 217682.81 +2180 2 1997-01-03 208481.57 +2180 3 1997-01-03 208481.57 +3619 1 1997-01-22 222274.54 +3619 3 1997-01-31 222274.54 +3619 6 1997-01-25 222274.54 +484 3 1997-01-24 219920.62 +5606 6 1997-01-11 219959.08 +set statement optimizer_switch='rowid_filter=off' for EXPLAIN SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-01-31' AND +o_totalprice between 200000 and 230000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE lineitem range PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_shipdate 4 NULL 98 Using index condition +1 SIMPLE orders eq_ref PRIMARY,i_o_totalprice PRIMARY 4 dbt3_s001.lineitem.l_orderkey 1 Using where +set statement optimizer_switch='rowid_filter=off' for EXPLAIN FORMAT=JSON SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-01-31' AND +o_totalprice between 200000 and 230000; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "lineitem", + "access_type": "range", + "possible_keys": [ + "PRIMARY", + "i_l_shipdate", + "i_l_orderkey", + "i_l_orderkey_quantity" + ], + "key": "i_l_shipdate", + "key_length": "4", + "used_key_parts": ["l_shipDATE"], + "rows": 98, + "filtered": 100, + "index_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-01-31'" + }, + "table": { + "table_name": "orders", + "access_type": "eq_ref", + "possible_keys": ["PRIMARY", "i_o_totalprice"], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["o_orderkey"], + "ref": ["dbt3_s001.lineitem.l_orderkey"], + "rows": 1, + "filtered": 5.4, + "attached_condition": "orders.o_totalprice between 200000 and 230000" + } + } +} +set statement optimizer_switch='rowid_filter=off' for SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-01-31' AND +o_totalprice between 200000 and 230000; +o_orderkey l_linenumber l_shipdate o_totalprice +1156 3 1997-01-24 217682.81 +1156 4 1997-01-18 217682.81 +1156 6 1997-01-27 217682.81 +1156 7 1997-01-01 217682.81 +2180 2 1997-01-03 208481.57 +2180 3 1997-01-03 208481.57 +3619 1 1997-01-22 222274.54 +3619 3 1997-01-31 222274.54 +3619 6 1997-01-25 222274.54 +484 3 1997-01-24 219920.62 +5606 6 1997-01-11 219959.08 +set statement optimizer_switch='rowid_filter=on' for EXPLAIN SELECT o_orderkey, l_linenumber, l_shipdate, l_quantity, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45 AND +o_totalprice between 180000 and 230000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE lineitem range|filter PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity,i_l_quantity i_l_shipdate|i_l_quantity 4|9 NULL 509 (11%) Using index condition; Using where; Using filter +1 SIMPLE orders eq_ref|filter PRIMARY,i_o_totalprice PRIMARY|i_o_totalprice 4|9 dbt3_s001.lineitem.l_orderkey 1 (10%) Using where; Using filter +set statement optimizer_switch='rowid_filter=on' for EXPLAIN FORMAT=JSON SELECT o_orderkey, l_linenumber, l_shipdate, l_quantity, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45 AND +o_totalprice between 180000 and 230000; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "lineitem", + "access_type": "range", + "possible_keys": [ + "PRIMARY", + "i_l_shipdate", + "i_l_orderkey", + "i_l_orderkey_quantity", + "i_l_quantity" + ], + "key": "i_l_shipdate", + "key_length": "4", + "used_key_parts": ["l_shipDATE"], + "rowid_filter": { + "range": { + "key": "i_l_quantity", + "used_key_parts": ["l_quantity"] + }, + "rows": 662, + "selectivity_pct": 11.024 + }, + "rows": 509, + "filtered": 11.024, + "index_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'", + "attached_condition": "lineitem.l_quantity > 45" + }, + "table": { + "table_name": "orders", + "access_type": "eq_ref", + "possible_keys": ["PRIMARY", "i_o_totalprice"], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["o_orderkey"], + "ref": ["dbt3_s001.lineitem.l_orderkey"], + "rowid_filter": { + "range": { + "key": "i_o_totalprice", + "used_key_parts": ["o_totalprice"] + }, + "rows": 152, + "selectivity_pct": 10.133 + }, + "rows": 1, + "filtered": 10.133, + "attached_condition": "orders.o_totalprice between 180000 and 230000" + } + } +} +set statement optimizer_switch='rowid_filter=on' for SELECT o_orderkey, l_linenumber, l_shipdate, l_quantity, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45 AND +o_totalprice between 180000 and 230000; +o_orderkey l_linenumber l_shipdate l_quantity o_totalprice +1632 1 1997-01-25 47 183286.33 +1632 3 1997-01-29 47 183286.33 +2177 5 1997-05-10 46 183493.42 +2469 3 1997-01-11 48 192074.23 +2469 6 1997-03-03 49 192074.23 +3619 1 1997-01-22 49 222274.54 +3619 3 1997-01-31 46 222274.54 +484 1 1997-03-06 49 219920.62 +484 3 1997-01-24 50 219920.62 +484 5 1997-03-05 48 219920.62 +4934 1 1997-05-20 48 180478.16 +5606 3 1997-03-11 46 219959.08 +5606 7 1997-02-01 46 219959.08 +5829 5 1997-01-31 49 183734.56 +5895 2 1997-04-27 47 201419.83 +5895 3 1997-03-15 49 201419.83 +set statement optimizer_switch='rowid_filter=off' for EXPLAIN SELECT o_orderkey, l_linenumber, l_shipdate, l_quantity, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45 AND +o_totalprice between 180000 and 230000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE lineitem range PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity,i_l_quantity i_l_shipdate 4 NULL 509 Using index condition; Using where +1 SIMPLE orders eq_ref PRIMARY,i_o_totalprice PRIMARY 4 dbt3_s001.lineitem.l_orderkey 1 Using where +set statement optimizer_switch='rowid_filter=off' for EXPLAIN FORMAT=JSON SELECT o_orderkey, l_linenumber, l_shipdate, l_quantity, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45 AND +o_totalprice between 180000 and 230000; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "lineitem", + "access_type": "range", + "possible_keys": [ + "PRIMARY", + "i_l_shipdate", + "i_l_orderkey", + "i_l_orderkey_quantity", + "i_l_quantity" + ], + "key": "i_l_shipdate", + "key_length": "4", + "used_key_parts": ["l_shipDATE"], + "rows": 509, + "filtered": 11.024, + "index_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'", + "attached_condition": "lineitem.l_quantity > 45" + }, + "table": { + "table_name": "orders", + "access_type": "eq_ref", + "possible_keys": ["PRIMARY", "i_o_totalprice"], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["o_orderkey"], + "ref": ["dbt3_s001.lineitem.l_orderkey"], + "rows": 1, + "filtered": 10.133, + "attached_condition": "orders.o_totalprice between 180000 and 230000" + } + } +} +set statement optimizer_switch='rowid_filter=off' for SELECT o_orderkey, l_linenumber, l_shipdate, l_quantity, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45 AND +o_totalprice between 180000 and 230000; +o_orderkey l_linenumber l_shipdate l_quantity o_totalprice +1632 1 1997-01-25 47 183286.33 +1632 3 1997-01-29 47 183286.33 +2177 5 1997-05-10 46 183493.42 +2469 3 1997-01-11 48 192074.23 +2469 6 1997-03-03 49 192074.23 +3619 1 1997-01-22 49 222274.54 +3619 3 1997-01-31 46 222274.54 +484 1 1997-03-06 49 219920.62 +484 3 1997-01-24 50 219920.62 +484 5 1997-03-05 48 219920.62 +4934 1 1997-05-20 48 180478.16 +5606 3 1997-03-11 46 219959.08 +5606 7 1997-02-01 46 219959.08 +5829 5 1997-01-31 49 183734.56 +5895 2 1997-04-27 47 201419.83 +5895 3 1997-03-15 49 201419.83 +set statement optimizer_switch='rowid_filter=on' for EXPLAIN SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +o_totalprice between 200000 and 230000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE orders range PRIMARY,i_o_totalprice i_o_totalprice 9 NULL 81 Using index condition +1 SIMPLE lineitem ref|filter PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity PRIMARY|i_l_shipdate 4|4 dbt3_s001.orders.o_orderkey 4 (8%) Using where; Using filter +set statement optimizer_switch='rowid_filter=on' for EXPLAIN FORMAT=JSON SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +o_totalprice between 200000 and 230000; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "orders", + "access_type": "range", + "possible_keys": ["PRIMARY", "i_o_totalprice"], + "key": "i_o_totalprice", + "key_length": "9", + "used_key_parts": ["o_totalprice"], + "rows": 81, + "filtered": 100, + "index_condition": "orders.o_totalprice between 200000 and 230000" + }, + "table": { + "table_name": "lineitem", + "access_type": "ref", + "possible_keys": [ + "PRIMARY", + "i_l_shipdate", + "i_l_orderkey", + "i_l_orderkey_quantity" + ], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["l_orderkey"], + "ref": ["dbt3_s001.orders.o_orderkey"], + "rowid_filter": { + "range": { + "key": "i_l_shipdate", + "used_key_parts": ["l_shipDATE"] + }, + "rows": 509, + "selectivity_pct": 8.4763 + }, + "rows": 4, + "filtered": 8.4763, + "attached_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'" + } + } +} +set statement optimizer_switch='rowid_filter=on' for SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +o_totalprice between 200000 and 230000; +o_orderkey l_linenumber l_shipdate o_totalprice +1156 3 1997-01-24 217682.81 +1156 4 1997-01-18 217682.81 +1156 6 1997-01-27 217682.81 +1156 7 1997-01-01 217682.81 +1890 1 1997-04-02 202364.58 +1890 3 1997-02-09 202364.58 +1890 4 1997-04-08 202364.58 +1890 5 1997-04-15 202364.58 +1890 6 1997-02-13 202364.58 +2180 2 1997-01-03 208481.57 +2180 3 1997-01-03 208481.57 +3619 1 1997-01-22 222274.54 +3619 3 1997-01-31 222274.54 +3619 4 1997-03-18 222274.54 +3619 6 1997-01-25 222274.54 +453 1 1997-06-30 216826.73 +453 2 1997-06-30 216826.73 +484 1 1997-03-06 219920.62 +484 2 1997-04-09 219920.62 +484 3 1997-01-24 219920.62 +484 4 1997-04-29 219920.62 +484 5 1997-03-05 219920.62 +484 6 1997-04-06 219920.62 +5606 2 1997-02-23 219959.08 +5606 3 1997-03-11 219959.08 +5606 4 1997-02-06 219959.08 +5606 6 1997-01-11 219959.08 +5606 7 1997-02-01 219959.08 +5859 2 1997-05-15 210643.96 +5859 5 1997-05-28 210643.96 +5859 6 1997-06-15 210643.96 +5895 1 1997-04-05 201419.83 +5895 2 1997-04-27 201419.83 +5895 3 1997-03-15 201419.83 +5895 4 1997-03-03 201419.83 +5895 5 1997-04-30 201419.83 +5895 6 1997-04-19 201419.83 +set statement optimizer_switch='rowid_filter=off' for EXPLAIN SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +o_totalprice between 200000 and 230000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE orders range PRIMARY,i_o_totalprice i_o_totalprice 9 NULL 81 Using index condition +1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity PRIMARY 4 dbt3_s001.orders.o_orderkey 4 Using where +set statement optimizer_switch='rowid_filter=off' for EXPLAIN FORMAT=JSON SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +o_totalprice between 200000 and 230000; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "orders", + "access_type": "range", + "possible_keys": ["PRIMARY", "i_o_totalprice"], + "key": "i_o_totalprice", + "key_length": "9", + "used_key_parts": ["o_totalprice"], + "rows": 81, + "filtered": 100, + "index_condition": "orders.o_totalprice between 200000 and 230000" + }, + "table": { + "table_name": "lineitem", + "access_type": "ref", + "possible_keys": [ + "PRIMARY", + "i_l_shipdate", + "i_l_orderkey", + "i_l_orderkey_quantity" + ], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["l_orderkey"], + "ref": ["dbt3_s001.orders.o_orderkey"], + "rows": 4, + "filtered": 8.4763, + "attached_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'" + } + } +} +set statement optimizer_switch='rowid_filter=off' for SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +o_totalprice between 200000 and 230000; +o_orderkey l_linenumber l_shipdate o_totalprice +1156 3 1997-01-24 217682.81 +1156 4 1997-01-18 217682.81 +1156 6 1997-01-27 217682.81 +1156 7 1997-01-01 217682.81 +1890 1 1997-04-02 202364.58 +1890 3 1997-02-09 202364.58 +1890 4 1997-04-08 202364.58 +1890 5 1997-04-15 202364.58 +1890 6 1997-02-13 202364.58 +2180 2 1997-01-03 208481.57 +2180 3 1997-01-03 208481.57 +3619 1 1997-01-22 222274.54 +3619 3 1997-01-31 222274.54 +3619 4 1997-03-18 222274.54 +3619 6 1997-01-25 222274.54 +453 1 1997-06-30 216826.73 +453 2 1997-06-30 216826.73 +484 1 1997-03-06 219920.62 +484 2 1997-04-09 219920.62 +484 3 1997-01-24 219920.62 +484 4 1997-04-29 219920.62 +484 5 1997-03-05 219920.62 +484 6 1997-04-06 219920.62 +5606 2 1997-02-23 219959.08 +5606 3 1997-03-11 219959.08 +5606 4 1997-02-06 219959.08 +5606 6 1997-01-11 219959.08 +5606 7 1997-02-01 219959.08 +5859 2 1997-05-15 210643.96 +5859 5 1997-05-28 210643.96 +5859 6 1997-06-15 210643.96 +5895 1 1997-04-05 201419.83 +5895 2 1997-04-27 201419.83 +5895 3 1997-03-15 201419.83 +5895 4 1997-03-03 201419.83 +5895 5 1997-04-30 201419.83 +5895 6 1997-04-19 201419.83 +DROP DATABASE dbt3_s001; +set @@use_stat_tables=@save_use_stat_tables; diff --git a/mysql-test/main/rowid_filter.test b/mysql-test/main/rowid_filter.test index 4f41c408d94..6e378a7e93d 100644 --- a/mysql-test/main/rowid_filter.test +++ b/mysql-test/main/rowid_filter.test @@ -14,129 +14,96 @@ use dbt3_s001; --enable_result_log --enable_query_log ---echo # lineitem : {i_l_receiptdate, i_l_shipdate} -> i_l_receiptdate -EXPLAIN SELECT * -FROM orders JOIN lineitem ON o_orderkey=l_orderkey -WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-02-01' AND - l_receiptdate BETWEEN '1997-01-10' AND '1997-01-25'; - ---echo # lineitem : {i_l_receiptdate, i_l_shipdate} -> i_l_receiptdate ---echo # orders : {i_o_orderdate} -> i_o_orderdate -EXPLAIN SELECT * -FROM orders JOIN lineitem ON o_orderkey=l_orderkey -WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-02-01' AND - l_receiptdate BETWEEN '1997-01-10' AND '1997-01-25' AND - o_orderdate > '1997-01-15'; - ---echo # lineitem : {i_l_receiptdate, i_l_shipdate, ---echo # i_l_commitdate} -> i_l_receiptdate -EXPLAIN SELECT * -FROM orders JOIN lineitem ON o_orderkey=l_orderkey -WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-02-01' AND - l_receiptdate BETWEEN '1997-01-10' AND '1997-01-25' AND - l_commitdate BETWEEN '1997-01-05' AND '1997-01-25'; - ---echo # lineitem : {i_l_receiptdate, i_l_shipdate, ---echo # i_l_commitdate} -> i_l_commitdate -EXPLAIN SELECT * -FROM orders JOIN lineitem ON o_orderkey=l_orderkey -WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-02-01' AND - l_receiptdate BETWEEN '1997-01-01' AND '1997-01-25' AND - l_commitdate BETWEEN '1997-01-15' AND '1997-01-25'; - -CREATE INDEX i_l_extendedprice ON lineitem(l_extendedprice); - ---echo # lineitem : {i_l_receiptdate, i_l_shipdate, i_l_commitdate, ---echo # i_l_extendedprice} -> i_l_extendedprice -EXPLAIN SELECT * -FROM orders JOIN lineitem ON o_orderkey=l_orderkey -WHERE l_shipdate BETWEEN '1996-11-01' AND '1997-01-21' AND - l_receiptdate BETWEEN '1996-11-21' AND '1997-01-25' AND - l_commitdate BETWEEN '1996-11-25' AND '1997-01-20' AND - l_extendedprice BETWEEN 26000 AND 27000; - ---echo # lineitem : {i_l_shipdate, i_l_extendedprice} -> i_l_shipdate -EXPLAIN SELECT * -FROM orders JOIN lineitem ON o_orderkey=l_orderkey -WHERE l_shipdate BETWEEN '1997-01-11' AND '1997-01-21' AND - l_extendedprice BETWEEN 26000 AND 27000; - ---echo # lineitem : {i_l_shipdate, i_l_extendedprice} -> i_l_extendedprice ---echo # intersection point in the I quadrant -EXPLAIN SELECT * -FROM orders JOIN lineitem ON o_orderkey=l_orderkey -WHERE (l_shipdate BETWEEN '1997-01-11' AND '1997-01-26' OR - l_shipdate BETWEEN '1995-02-01' AND '1995-02-14' OR - l_shipdate BETWEEN '1994-12-12' AND '1994-12-28' - ) AND l_extendedprice BETWEEN 26000 AND 27000; - ---echo # lineitem : {i_l_shipdate, i_l_extendedprice} -> i_l_shipdate ---echo # parallel lines -EXPLAIN SELECT * -FROM orders JOIN lineitem ON o_orderkey=l_orderkey -WHERE (l_shipdate BETWEEN '1997-01-11' AND '1997-01-26' OR - l_shipdate BETWEEN '1995-02-01' AND '1995-02-16' OR - l_shipdate BETWEEN '1994-12-12' AND '1994-12-27' - ) AND l_extendedprice BETWEEN 26000 AND 27000; - - -CREATE INDEX i_l_discount ON lineitem(l_discount); -CREATE INDEX i_l_tax ON lineitem(l_tax); - ---echo # lineitem : {i_l_receiptdate, i_l_shipdate, i_l_commitdate, ---echo # i_l_extendedprice, i_l_discount, i_l_tax} ---echo # -> {i_l_extendedprice} -EXPLAIN SELECT * -FROM orders JOIN lineitem ON o_orderkey=l_orderkey -WHERE l_shipdate BETWEEN '1996-11-01' AND '1997-01-21' AND - l_receiptdate BETWEEN '1996-11-21' AND '1997-01-25' AND - l_commitdate BETWEEN '1996-11-25' AND '1997-01-20' AND - l_extendedprice BETWEEN 26000 AND 27000 AND - l_discount BETWEEN 0 AND 0.01 AND - l_tax BETWEEN 0.03 AND 0.04; - -DROP INDEX i_l_extendedprice on lineitem; -DROP INDEX i_l_discount on lineitem; -DROP INDEX i_l_tax on lineitem; - -SET max_rowid_filter_size= 1024; - ---echo # lineitem : {i_l_shipdate, i_l_receiptdate, i_l_commitdate} ---echo # -> i_l_shipdate ---echo # i_l_commitdate isn't in-memory -> isn't used -EXPLAIN SELECT * -FROM orders JOIN lineitem ON o_orderkey=l_orderkey -WHERE l_shipdate BETWEEN '1996-12-28' AND '1997-01-20' AND - l_receiptdate BETWEEN '1996-12-21' AND '1997-01-25' AND - l_commitdate BETWEEN '1996-12-01' AND '1997-01-25'; - -SET max_rowid_filter_size= DEFAULT; - ---echo # lineitem : {i_l_shipdate, i_l_commitdate} -> i_l_commitdate -EXPLAIN SELECT * -FROM orders JOIN lineitem ON o_orderkey=l_orderkey -WHERE l_shipdate BETWEEN '1993-01-01' AND '1997-01-30' AND - l_commitdate BETWEEN '1997-01-10' AND '1997-01-12'; - ---echo # lineitem : {i_l_shipdate, i_l_commitdate} -> i_l_commitdate -EXPLAIN SELECT * -FROM orders JOIN lineitem ON o_orderkey=l_orderkey -WHERE l_shipdate BETWEEN '1993-01-01' AND '1997-01-30' AND - l_commitdate BETWEEN '1993-01-10' AND '1997-01-12'; - ---echo # lineitem : {i_l_shipdate, i_l_commitdate, i_l_receiptdate} ---echo # -> i_l_receiptdate -EXPLAIN SELECT * -FROM orders JOIN lineitem ON o_orderkey=l_orderkey -WHERE l_shipdate BETWEEN '1993-01-01' AND '1997-01-30' AND - l_commitdate BETWEEN '1993-01-10' AND '1997-01-12' AND - l_receiptdate BETWEEN '1997-01-10' AND '1997-01-12'; - ---echo # lineitem : {i_l_shipdate, i_l_receiptdate} -> i_l_receiptdate ---echo # indexes with high selectivity -EXPLAIN SELECT * -FROM orders JOIN lineitem ON o_orderkey=l_orderkey -WHERE l_shipdate BETWEEN '1997-01-09' AND '1997-01-10' AND - l_receiptdate BETWEEN '1997-01-09' AND '1997-01-10'; +CREATE INDEX i_l_quantity ON lineitem(l_quantity); + +CREATE INDEX i_o_totalprice ON orders(o_totalprice); + +set @save_use_stat_tables= @@use_stat_tables; + +set @@use_stat_tables=preferably; + +--disable_result_log +--disable_warnings +ANALYZE TABLE lineitem, orders; +--enable_warnings +--enable_result_log + +show create table lineitem; +show create table orders; + +set optimizer_use_condition_selectivity=2; + +let $with_filter= +set statement optimizer_switch='rowid_filter=on' for; + +let $without_filter= +set statement optimizer_switch='rowid_filter=off' for; + +let $q1= +SELECT l_orderkey, l_linenumber, l_shipdate, l_quantity FROM lineitem + WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND + l_quantity > 45; + +eval $with_filter EXPLAIN $q1; +eval $with_filter EXPLAIN FORMAT=JSON $q1; +--sorted_result +eval $with_filter $q1; + +eval $without_filter EXPLAIN $q1; +eval $without_filter EXPLAIN FORMAT=JSON $q1; +--sorted_result +eval $without_filter $q1; + +let $q2= +SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice + FROM orders JOIN lineitem ON o_orderkey=l_orderkey + WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-01-31' AND + o_totalprice between 200000 and 230000; + +eval $with_filter EXPLAIN $q2; +eval $with_filter EXPLAIN FORMAT=JSON $q2; +--sorted_result +eval $with_filter $q2; + +eval $without_filter EXPLAIN $q2; +eval $without_filter EXPLAIN FORMAT=JSON $q2; +--sorted_result +eval $without_filter $q2; + +let $q3= +SELECT o_orderkey, l_linenumber, l_shipdate, l_quantity, o_totalprice + FROM orders JOIN lineitem ON o_orderkey=l_orderkey + WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND + l_quantity > 45 AND + o_totalprice between 180000 and 230000; + +eval $with_filter EXPLAIN $q3; +eval $with_filter EXPLAIN FORMAT=JSON $q3; +--sorted_result +eval $with_filter $q3; + +eval $without_filter EXPLAIN $q3; +eval $without_filter EXPLAIN FORMAT=JSON $q3; +--sorted_result +eval $without_filter $q3; + +let $q4= +SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice + FROM orders JOIN lineitem ON o_orderkey=l_orderkey + WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND + o_totalprice between 200000 and 230000; + +eval $with_filter EXPLAIN $q4; +eval $with_filter EXPLAIN FORMAT=JSON $q4; +--sorted_result +eval $with_filter $q4; + +eval $without_filter EXPLAIN $q4; +eval $without_filter EXPLAIN FORMAT=JSON $q4; +--sorted_result +eval $without_filter $q4; DROP DATABASE dbt3_s001; + +set @@use_stat_tables=@save_use_stat_tables; + diff --git a/mysql-test/main/rowid_filter_innodb.result b/mysql-test/main/rowid_filter_innodb.result new file mode 100644 index 00000000000..04414a7a5bc --- /dev/null +++ b/mysql-test/main/rowid_filter_innodb.result @@ -0,0 +1,690 @@ +SET SESSION STORAGE_ENGINE='InnoDB'; +DROP DATABASE IF EXISTS dbt3_s001; +CREATE DATABASE dbt3_s001; +use dbt3_s001; +CREATE INDEX i_l_quantity ON lineitem(l_quantity); +CREATE INDEX i_o_totalprice ON orders(o_totalprice); +set @save_use_stat_tables= @@use_stat_tables; +set @@use_stat_tables=preferably; +ANALYZE TABLE lineitem, orders; +show create table lineitem; +Table Create Table +lineitem CREATE TABLE `lineitem` ( + `l_orderkey` int(11) NOT NULL DEFAULT 0, + `l_partkey` int(11) DEFAULT NULL, + `l_suppkey` int(11) DEFAULT NULL, + `l_linenumber` int(11) NOT NULL DEFAULT 0, + `l_quantity` double DEFAULT NULL, + `l_extendedprice` double DEFAULT NULL, + `l_discount` double DEFAULT NULL, + `l_tax` double DEFAULT NULL, + `l_returnflag` char(1) DEFAULT NULL, + `l_linestatus` char(1) DEFAULT NULL, + `l_shipDATE` date DEFAULT NULL, + `l_commitDATE` date DEFAULT NULL, + `l_receiptDATE` date DEFAULT NULL, + `l_shipinstruct` char(25) DEFAULT NULL, + `l_shipmode` char(10) DEFAULT NULL, + `l_comment` varchar(44) DEFAULT NULL, + PRIMARY KEY (`l_orderkey`,`l_linenumber`), + KEY `i_l_shipdate` (`l_shipDATE`), + KEY `i_l_suppkey_partkey` (`l_partkey`,`l_suppkey`), + KEY `i_l_partkey` (`l_partkey`), + KEY `i_l_suppkey` (`l_suppkey`), + KEY `i_l_receiptdate` (`l_receiptDATE`), + KEY `i_l_orderkey` (`l_orderkey`), + KEY `i_l_orderkey_quantity` (`l_orderkey`,`l_quantity`), + KEY `i_l_commitdate` (`l_commitDATE`), + KEY `i_l_quantity` (`l_quantity`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +show create table orders; +Table Create Table +orders CREATE TABLE `orders` ( + `o_orderkey` int(11) NOT NULL, + `o_custkey` int(11) DEFAULT NULL, + `o_orderstatus` char(1) DEFAULT NULL, + `o_totalprice` double DEFAULT NULL, + `o_orderDATE` date DEFAULT NULL, + `o_orderpriority` char(15) DEFAULT NULL, + `o_clerk` char(15) DEFAULT NULL, + `o_shippriority` int(11) DEFAULT NULL, + `o_comment` varchar(79) DEFAULT NULL, + PRIMARY KEY (`o_orderkey`), + KEY `i_o_orderdate` (`o_orderDATE`), + KEY `i_o_custkey` (`o_custkey`), + KEY `i_o_totalprice` (`o_totalprice`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +set optimizer_use_condition_selectivity=2; +set statement optimizer_switch='rowid_filter=on' for EXPLAIN SELECT l_orderkey, l_linenumber, l_shipdate, l_quantity FROM lineitem +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE lineitem range|filter i_l_shipdate,i_l_quantity i_l_shipdate|i_l_quantity 4|9 NULL 510 (10%) Using index condition; Using where; Using filter +set statement optimizer_switch='rowid_filter=on' for EXPLAIN FORMAT=JSON SELECT l_orderkey, l_linenumber, l_shipdate, l_quantity FROM lineitem +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "lineitem", + "access_type": "range", + "possible_keys": ["i_l_shipdate", "i_l_quantity"], + "key": "i_l_shipdate", + "key_length": "4", + "used_key_parts": ["l_shipDATE"], + "rowid_filter": { + "range": { + "key": "i_l_quantity", + "used_key_parts": ["l_quantity"] + }, + "rows": 605, + "selectivity_pct": 10.075 + }, + "rows": 510, + "filtered": 10.075, + "index_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'", + "attached_condition": "lineitem.l_quantity > 45" + } + } +} +set statement optimizer_switch='rowid_filter=on' for SELECT l_orderkey, l_linenumber, l_shipdate, l_quantity FROM lineitem +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45; +l_orderkey l_linenumber l_shipdate l_quantity +1121 5 1997-04-27 47 +1121 6 1997-04-21 50 +1441 7 1997-06-07 50 +1443 1 1997-02-05 47 +1473 1 1997-05-05 50 +1568 2 1997-04-06 46 +1632 1 1997-01-25 47 +1632 3 1997-01-29 47 +1954 7 1997-06-04 49 +1959 1 1997-05-05 46 +2151 3 1997-01-20 49 +2177 5 1997-05-10 46 +2369 2 1997-01-02 47 +2469 3 1997-01-11 48 +2469 6 1997-03-03 49 +2470 2 1997-06-02 50 +260 1 1997-03-24 50 +288 2 1997-04-19 49 +289 4 1997-03-14 48 +3009 1 1997-03-19 48 +3105 3 1997-02-28 48 +3106 2 1997-02-27 49 +3429 1 1997-04-08 48 +3490 2 1997-06-27 50 +3619 1 1997-01-22 49 +3619 3 1997-01-31 46 +3969 3 1997-05-29 46 +4005 4 1997-01-31 49 +4036 1 1997-06-21 46 +4066 4 1997-02-17 49 +4098 1 1997-01-26 46 +422 3 1997-06-21 46 +4258 3 1997-01-02 46 +4421 2 1997-04-21 46 +4421 3 1997-05-25 46 +4453 3 1997-05-29 48 +4484 7 1997-03-17 50 +4609 3 1997-02-11 46 +484 1 1997-03-06 49 +484 3 1997-01-24 50 +484 5 1997-03-05 48 +485 1 1997-03-28 50 +4868 1 1997-04-29 47 +4868 3 1997-04-23 49 +4934 1 1997-05-20 48 +4967 1 1997-05-27 50 +5090 2 1997-04-05 46 +5152 2 1997-03-10 50 +5158 4 1997-04-10 49 +5606 3 1997-03-11 46 +5606 7 1997-02-01 46 +5762 4 1997-03-02 47 +581 3 1997-02-27 49 +5829 5 1997-01-31 49 +5831 4 1997-02-24 46 +5895 2 1997-04-27 47 +5895 3 1997-03-15 49 +5952 1 1997-06-30 49 +705 1 1997-04-18 46 +836 3 1997-03-21 46 +set statement optimizer_switch='rowid_filter=off' for EXPLAIN SELECT l_orderkey, l_linenumber, l_shipdate, l_quantity FROM lineitem +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE lineitem range i_l_shipdate,i_l_quantity i_l_shipdate 4 NULL 510 Using index condition; Using where +set statement optimizer_switch='rowid_filter=off' for EXPLAIN FORMAT=JSON SELECT l_orderkey, l_linenumber, l_shipdate, l_quantity FROM lineitem +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "lineitem", + "access_type": "range", + "possible_keys": ["i_l_shipdate", "i_l_quantity"], + "key": "i_l_shipdate", + "key_length": "4", + "used_key_parts": ["l_shipDATE"], + "rows": 510, + "filtered": 10.075, + "index_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'", + "attached_condition": "lineitem.l_quantity > 45" + } + } +} +set statement optimizer_switch='rowid_filter=off' for SELECT l_orderkey, l_linenumber, l_shipdate, l_quantity FROM lineitem +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45; +l_orderkey l_linenumber l_shipdate l_quantity +1121 5 1997-04-27 47 +1121 6 1997-04-21 50 +1441 7 1997-06-07 50 +1443 1 1997-02-05 47 +1473 1 1997-05-05 50 +1568 2 1997-04-06 46 +1632 1 1997-01-25 47 +1632 3 1997-01-29 47 +1954 7 1997-06-04 49 +1959 1 1997-05-05 46 +2151 3 1997-01-20 49 +2177 5 1997-05-10 46 +2369 2 1997-01-02 47 +2469 3 1997-01-11 48 +2469 6 1997-03-03 49 +2470 2 1997-06-02 50 +260 1 1997-03-24 50 +288 2 1997-04-19 49 +289 4 1997-03-14 48 +3009 1 1997-03-19 48 +3105 3 1997-02-28 48 +3106 2 1997-02-27 49 +3429 1 1997-04-08 48 +3490 2 1997-06-27 50 +3619 1 1997-01-22 49 +3619 3 1997-01-31 46 +3969 3 1997-05-29 46 +4005 4 1997-01-31 49 +4036 1 1997-06-21 46 +4066 4 1997-02-17 49 +4098 1 1997-01-26 46 +422 3 1997-06-21 46 +4258 3 1997-01-02 46 +4421 2 1997-04-21 46 +4421 3 1997-05-25 46 +4453 3 1997-05-29 48 +4484 7 1997-03-17 50 +4609 3 1997-02-11 46 +484 1 1997-03-06 49 +484 3 1997-01-24 50 +484 5 1997-03-05 48 +485 1 1997-03-28 50 +4868 1 1997-04-29 47 +4868 3 1997-04-23 49 +4934 1 1997-05-20 48 +4967 1 1997-05-27 50 +5090 2 1997-04-05 46 +5152 2 1997-03-10 50 +5158 4 1997-04-10 49 +5606 3 1997-03-11 46 +5606 7 1997-02-01 46 +5762 4 1997-03-02 47 +581 3 1997-02-27 49 +5829 5 1997-01-31 49 +5831 4 1997-02-24 46 +5895 2 1997-04-27 47 +5895 3 1997-03-15 49 +5952 1 1997-06-30 49 +705 1 1997-04-18 46 +836 3 1997-03-21 46 +set statement optimizer_switch='rowid_filter=on' for EXPLAIN SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-01-31' AND +o_totalprice between 200000 and 230000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE lineitem range PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_shipdate 4 NULL 98 Using where; Using index +1 SIMPLE orders eq_ref PRIMARY,i_o_totalprice PRIMARY 4 dbt3_s001.lineitem.l_orderkey 1 Using where +set statement optimizer_switch='rowid_filter=on' for EXPLAIN FORMAT=JSON SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-01-31' AND +o_totalprice between 200000 and 230000; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "lineitem", + "access_type": "range", + "possible_keys": [ + "PRIMARY", + "i_l_shipdate", + "i_l_orderkey", + "i_l_orderkey_quantity" + ], + "key": "i_l_shipdate", + "key_length": "4", + "used_key_parts": ["l_shipDATE"], + "rows": 98, + "filtered": 100, + "attached_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-01-31'", + "using_index": true + }, + "table": { + "table_name": "orders", + "access_type": "eq_ref", + "possible_keys": ["PRIMARY", "i_o_totalprice"], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["o_orderkey"], + "ref": ["dbt3_s001.lineitem.l_orderkey"], + "rows": 1, + "filtered": 4.7333, + "attached_condition": "orders.o_totalprice between 200000 and 230000" + } + } +} +set statement optimizer_switch='rowid_filter=on' for SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-01-31' AND +o_totalprice between 200000 and 230000; +o_orderkey l_linenumber l_shipdate o_totalprice +1156 3 1997-01-24 217682.81 +1156 4 1997-01-18 217682.81 +1156 6 1997-01-27 217682.81 +1156 7 1997-01-01 217682.81 +2180 2 1997-01-03 208481.57 +2180 3 1997-01-03 208481.57 +3619 1 1997-01-22 222274.54 +3619 3 1997-01-31 222274.54 +3619 6 1997-01-25 222274.54 +484 3 1997-01-24 219920.62 +5606 6 1997-01-11 219959.08 +set statement optimizer_switch='rowid_filter=off' for EXPLAIN SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-01-31' AND +o_totalprice between 200000 and 230000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE lineitem range PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_shipdate 4 NULL 98 Using where; Using index +1 SIMPLE orders eq_ref PRIMARY,i_o_totalprice PRIMARY 4 dbt3_s001.lineitem.l_orderkey 1 Using where +set statement optimizer_switch='rowid_filter=off' for EXPLAIN FORMAT=JSON SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-01-31' AND +o_totalprice between 200000 and 230000; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "lineitem", + "access_type": "range", + "possible_keys": [ + "PRIMARY", + "i_l_shipdate", + "i_l_orderkey", + "i_l_orderkey_quantity" + ], + "key": "i_l_shipdate", + "key_length": "4", + "used_key_parts": ["l_shipDATE"], + "rows": 98, + "filtered": 100, + "attached_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-01-31'", + "using_index": true + }, + "table": { + "table_name": "orders", + "access_type": "eq_ref", + "possible_keys": ["PRIMARY", "i_o_totalprice"], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["o_orderkey"], + "ref": ["dbt3_s001.lineitem.l_orderkey"], + "rows": 1, + "filtered": 4.7333, + "attached_condition": "orders.o_totalprice between 200000 and 230000" + } + } +} +set statement optimizer_switch='rowid_filter=off' for SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-01-31' AND +o_totalprice between 200000 and 230000; +o_orderkey l_linenumber l_shipdate o_totalprice +1156 3 1997-01-24 217682.81 +1156 4 1997-01-18 217682.81 +1156 6 1997-01-27 217682.81 +1156 7 1997-01-01 217682.81 +2180 2 1997-01-03 208481.57 +2180 3 1997-01-03 208481.57 +3619 1 1997-01-22 222274.54 +3619 3 1997-01-31 222274.54 +3619 6 1997-01-25 222274.54 +484 3 1997-01-24 219920.62 +5606 6 1997-01-11 219959.08 +set statement optimizer_switch='rowid_filter=on' for EXPLAIN SELECT o_orderkey, l_linenumber, l_shipdate, l_quantity, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45 AND +o_totalprice between 180000 and 230000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE orders range PRIMARY,i_o_totalprice i_o_totalprice 9 NULL 144 Using where; Using index +1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity,i_l_quantity PRIMARY 4 dbt3_s001.orders.o_orderkey 4 Using where +set statement optimizer_switch='rowid_filter=on' for EXPLAIN FORMAT=JSON SELECT o_orderkey, l_linenumber, l_shipdate, l_quantity, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45 AND +o_totalprice between 180000 and 230000; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "orders", + "access_type": "range", + "possible_keys": ["PRIMARY", "i_o_totalprice"], + "key": "i_o_totalprice", + "key_length": "9", + "used_key_parts": ["o_totalprice"], + "rows": 144, + "filtered": 100, + "attached_condition": "orders.o_totalprice between 180000 and 230000", + "using_index": true + }, + "table": { + "table_name": "lineitem", + "access_type": "ref", + "possible_keys": [ + "PRIMARY", + "i_l_shipdate", + "i_l_orderkey", + "i_l_orderkey_quantity", + "i_l_quantity" + ], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["l_orderkey"], + "ref": ["dbt3_s001.orders.o_orderkey"], + "rows": 4, + "filtered": 0.8557, + "attached_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30' and lineitem.l_quantity > 45" + } + } +} +set statement optimizer_switch='rowid_filter=on' for SELECT o_orderkey, l_linenumber, l_shipdate, l_quantity, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45 AND +o_totalprice between 180000 and 230000; +o_orderkey l_linenumber l_shipdate l_quantity o_totalprice +1632 1 1997-01-25 47 183286.33 +1632 3 1997-01-29 47 183286.33 +2177 5 1997-05-10 46 183493.42 +2469 3 1997-01-11 48 192074.23 +2469 6 1997-03-03 49 192074.23 +3619 1 1997-01-22 49 222274.54 +3619 3 1997-01-31 46 222274.54 +484 1 1997-03-06 49 219920.62 +484 3 1997-01-24 50 219920.62 +484 5 1997-03-05 48 219920.62 +4934 1 1997-05-20 48 180478.16 +5606 3 1997-03-11 46 219959.08 +5606 7 1997-02-01 46 219959.08 +5829 5 1997-01-31 49 183734.56 +5895 2 1997-04-27 47 201419.83 +5895 3 1997-03-15 49 201419.83 +set statement optimizer_switch='rowid_filter=off' for EXPLAIN SELECT o_orderkey, l_linenumber, l_shipdate, l_quantity, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45 AND +o_totalprice between 180000 and 230000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE orders range PRIMARY,i_o_totalprice i_o_totalprice 9 NULL 144 Using where; Using index +1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity,i_l_quantity PRIMARY 4 dbt3_s001.orders.o_orderkey 4 Using where +set statement optimizer_switch='rowid_filter=off' for EXPLAIN FORMAT=JSON SELECT o_orderkey, l_linenumber, l_shipdate, l_quantity, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45 AND +o_totalprice between 180000 and 230000; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "orders", + "access_type": "range", + "possible_keys": ["PRIMARY", "i_o_totalprice"], + "key": "i_o_totalprice", + "key_length": "9", + "used_key_parts": ["o_totalprice"], + "rows": 144, + "filtered": 100, + "attached_condition": "orders.o_totalprice between 180000 and 230000", + "using_index": true + }, + "table": { + "table_name": "lineitem", + "access_type": "ref", + "possible_keys": [ + "PRIMARY", + "i_l_shipdate", + "i_l_orderkey", + "i_l_orderkey_quantity", + "i_l_quantity" + ], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["l_orderkey"], + "ref": ["dbt3_s001.orders.o_orderkey"], + "rows": 4, + "filtered": 0.8557, + "attached_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30' and lineitem.l_quantity > 45" + } + } +} +set statement optimizer_switch='rowid_filter=off' for SELECT o_orderkey, l_linenumber, l_shipdate, l_quantity, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45 AND +o_totalprice between 180000 and 230000; +o_orderkey l_linenumber l_shipdate l_quantity o_totalprice +1632 1 1997-01-25 47 183286.33 +1632 3 1997-01-29 47 183286.33 +2177 5 1997-05-10 46 183493.42 +2469 3 1997-01-11 48 192074.23 +2469 6 1997-03-03 49 192074.23 +3619 1 1997-01-22 49 222274.54 +3619 3 1997-01-31 46 222274.54 +484 1 1997-03-06 49 219920.62 +484 3 1997-01-24 50 219920.62 +484 5 1997-03-05 48 219920.62 +4934 1 1997-05-20 48 180478.16 +5606 3 1997-03-11 46 219959.08 +5606 7 1997-02-01 46 219959.08 +5829 5 1997-01-31 49 183734.56 +5895 2 1997-04-27 47 201419.83 +5895 3 1997-03-15 49 201419.83 +set statement optimizer_switch='rowid_filter=on' for EXPLAIN SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +o_totalprice between 200000 and 230000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE orders range PRIMARY,i_o_totalprice i_o_totalprice 9 NULL 71 Using where; Using index +1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity PRIMARY 4 dbt3_s001.orders.o_orderkey 4 Using where +set statement optimizer_switch='rowid_filter=on' for EXPLAIN FORMAT=JSON SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +o_totalprice between 200000 and 230000; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "orders", + "access_type": "range", + "possible_keys": ["PRIMARY", "i_o_totalprice"], + "key": "i_o_totalprice", + "key_length": "9", + "used_key_parts": ["o_totalprice"], + "rows": 71, + "filtered": 100, + "attached_condition": "orders.o_totalprice between 200000 and 230000", + "using_index": true + }, + "table": { + "table_name": "lineitem", + "access_type": "ref", + "possible_keys": [ + "PRIMARY", + "i_l_shipdate", + "i_l_orderkey", + "i_l_orderkey_quantity" + ], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["l_orderkey"], + "ref": ["dbt3_s001.orders.o_orderkey"], + "rows": 4, + "filtered": 8.4929, + "attached_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'" + } + } +} +set statement optimizer_switch='rowid_filter=on' for SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +o_totalprice between 200000 and 230000; +o_orderkey l_linenumber l_shipdate o_totalprice +1156 3 1997-01-24 217682.81 +1156 4 1997-01-18 217682.81 +1156 6 1997-01-27 217682.81 +1156 7 1997-01-01 217682.81 +1890 1 1997-04-02 202364.58 +1890 3 1997-02-09 202364.58 +1890 4 1997-04-08 202364.58 +1890 5 1997-04-15 202364.58 +1890 6 1997-02-13 202364.58 +2180 2 1997-01-03 208481.57 +2180 3 1997-01-03 208481.57 +3619 1 1997-01-22 222274.54 +3619 3 1997-01-31 222274.54 +3619 4 1997-03-18 222274.54 +3619 6 1997-01-25 222274.54 +453 1 1997-06-30 216826.73 +453 2 1997-06-30 216826.73 +484 1 1997-03-06 219920.62 +484 2 1997-04-09 219920.62 +484 3 1997-01-24 219920.62 +484 4 1997-04-29 219920.62 +484 5 1997-03-05 219920.62 +484 6 1997-04-06 219920.62 +5606 2 1997-02-23 219959.08 +5606 3 1997-03-11 219959.08 +5606 4 1997-02-06 219959.08 +5606 6 1997-01-11 219959.08 +5606 7 1997-02-01 219959.08 +5859 2 1997-05-15 210643.96 +5859 5 1997-05-28 210643.96 +5859 6 1997-06-15 210643.96 +5895 1 1997-04-05 201419.83 +5895 2 1997-04-27 201419.83 +5895 3 1997-03-15 201419.83 +5895 4 1997-03-03 201419.83 +5895 5 1997-04-30 201419.83 +5895 6 1997-04-19 201419.83 +set statement optimizer_switch='rowid_filter=off' for EXPLAIN SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +o_totalprice between 200000 and 230000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE orders range PRIMARY,i_o_totalprice i_o_totalprice 9 NULL 71 Using where; Using index +1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity PRIMARY 4 dbt3_s001.orders.o_orderkey 4 Using where +set statement optimizer_switch='rowid_filter=off' for EXPLAIN FORMAT=JSON SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +o_totalprice between 200000 and 230000; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "orders", + "access_type": "range", + "possible_keys": ["PRIMARY", "i_o_totalprice"], + "key": "i_o_totalprice", + "key_length": "9", + "used_key_parts": ["o_totalprice"], + "rows": 71, + "filtered": 100, + "attached_condition": "orders.o_totalprice between 200000 and 230000", + "using_index": true + }, + "table": { + "table_name": "lineitem", + "access_type": "ref", + "possible_keys": [ + "PRIMARY", + "i_l_shipdate", + "i_l_orderkey", + "i_l_orderkey_quantity" + ], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["l_orderkey"], + "ref": ["dbt3_s001.orders.o_orderkey"], + "rows": 4, + "filtered": 8.4929, + "attached_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'" + } + } +} +set statement optimizer_switch='rowid_filter=off' for SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +o_totalprice between 200000 and 230000; +o_orderkey l_linenumber l_shipdate o_totalprice +1156 3 1997-01-24 217682.81 +1156 4 1997-01-18 217682.81 +1156 6 1997-01-27 217682.81 +1156 7 1997-01-01 217682.81 +1890 1 1997-04-02 202364.58 +1890 3 1997-02-09 202364.58 +1890 4 1997-04-08 202364.58 +1890 5 1997-04-15 202364.58 +1890 6 1997-02-13 202364.58 +2180 2 1997-01-03 208481.57 +2180 3 1997-01-03 208481.57 +3619 1 1997-01-22 222274.54 +3619 3 1997-01-31 222274.54 +3619 4 1997-03-18 222274.54 +3619 6 1997-01-25 222274.54 +453 1 1997-06-30 216826.73 +453 2 1997-06-30 216826.73 +484 1 1997-03-06 219920.62 +484 2 1997-04-09 219920.62 +484 3 1997-01-24 219920.62 +484 4 1997-04-29 219920.62 +484 5 1997-03-05 219920.62 +484 6 1997-04-06 219920.62 +5606 2 1997-02-23 219959.08 +5606 3 1997-03-11 219959.08 +5606 4 1997-02-06 219959.08 +5606 6 1997-01-11 219959.08 +5606 7 1997-02-01 219959.08 +5859 2 1997-05-15 210643.96 +5859 5 1997-05-28 210643.96 +5859 6 1997-06-15 210643.96 +5895 1 1997-04-05 201419.83 +5895 2 1997-04-27 201419.83 +5895 3 1997-03-15 201419.83 +5895 4 1997-03-03 201419.83 +5895 5 1997-04-30 201419.83 +5895 6 1997-04-19 201419.83 +DROP DATABASE dbt3_s001; +set @@use_stat_tables=@save_use_stat_tables; +SET SESSION STORAGE_ENGINE=DEFAULT; diff --git a/mysql-test/main/rowid_filter_innodb.test b/mysql-test/main/rowid_filter_innodb.test new file mode 100644 index 00000000000..5408f0404f9 --- /dev/null +++ b/mysql-test/main/rowid_filter_innodb.test @@ -0,0 +1,7 @@ +--source include/have_innodb.inc + +SET SESSION STORAGE_ENGINE='InnoDB'; + +--source rowid_filter.test + +SET SESSION STORAGE_ENGINE=DEFAULT; diff --git a/mysql-test/main/select.result b/mysql-test/main/select.result index 94a92315acc..220f500e37a 100644 --- a/mysql-test/main/select.result +++ b/mysql-test/main/select.result @@ -2786,7 +2786,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index key1 key1 5 NULL 4 Using where; Using index explain select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range key1 key1 5 NULL 3 Using where; Using index +1 SIMPLE t1 index key1 key1 5 NULL 4 Using where; Using index select max(key1) from t1 where key1 <= 0.6158; max(key1) 0.6158000230789185 @@ -3408,7 +3408,7 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp CREATE TABLE t1 (sku int PRIMARY KEY, pr int); CREATE TABLE t2 (sku int PRIMARY KEY, sppr int, name varchar(255)); INSERT INTO t1 VALUES -(10, 10), (20, 10), (30, 20), (40, 30), (50, 10), (60, 10); +(10, 10), (20, 10), (30, 20), (40, 30), (50, 10), (60, 10), (70, 10); INSERT INTO t2 VALUES (10, 10, 'aaa'), (20, 10, 'bbb'), (30, 10, 'ccc'), (40, 20, 'ddd'), (50, 10, 'eee'), (60, 20, 'fff'), (70, 20, 'ggg'), (80, 30, 'hhh'); @@ -3522,7 +3522,7 @@ INSERT INTO t2 VALUES 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 +1 SIMPLE t2 ref idx idx 4 const 8 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 @@ -3533,14 +3533,14 @@ 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); +INSERT INTO t3 VALUES (2,10), (2,20), (1,30), (2,40), (2,50), (1,60), (3,70), (1,80), (3,90); 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 +1 SIMPLE t3 ref idx1 idx1 5 const 4 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 @@ -3569,7 +3569,7 @@ EXPLAIN SELECT t2.* FROM t1 JOIN t2 ON t2.fk=t1.pk WHERE t2.fk < 'c' AND t2.pk=t1.fk; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 3 Using index condition; Using where +1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 2 Using index condition; Using where 1 SIMPLE t2 eq_ref PRIMARY PRIMARY 18 test.t1.fk 1 Using where EXPLAIN SELECT t2.* FROM t1 JOIN t2 ON t2.fk=t1.pk @@ -3616,7 +3616,7 @@ t3.a=t2.a AND t3.c IN ('bb','ee'); 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 range si si 5 NULL 4 Using index condition; Using where -1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where +1 SIMPLE t3 eq_ref|filter PRIMARY,ci PRIMARY|ci 4|5 test.t2.a 1 (30%) Using where; Using filter EXPLAIN SELECT t3.a FROM t1,t2,t3 WHERE t1.id = 8 AND t2.i BETWEEN t1.b AND t1.e AND @@ -3624,7 +3624,7 @@ t3.a=t2.a AND t3.c IN ('bb','ee') ; 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 range si,ai si 5 NULL 4 Using index condition; Using where -1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where +1 SIMPLE t3 eq_ref|filter PRIMARY,ci PRIMARY|ci 4|5 test.t2.a 1 (30%) Using where; Using filter EXPLAIN SELECT t3.a FROM t1,t2 FORCE INDEX (si),t3 WHERE t1.id = 8 AND (t2.i=t1.b OR t2.i=t1.e) AND t3.a=t2.a AND @@ -3698,6 +3698,9 @@ INSERT INTO t1 SELECT * FROM t1 WHERE ID1_with_null IS NULL; INSERT INTO t1 SELECT * FROM t1 WHERE ID2_with_null IS NULL; INSERT INTO t1 SELECT * FROM t1 WHERE ID1_with_null IS NULL; INSERT INTO t1 SELECT * FROM t1 WHERE ID2_with_null IS NULL; +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK SELECT COUNT(*) FROM t1 WHERE ID1_with_null IS NULL AND ID2_with_null=3; COUNT(*) 24 @@ -3713,34 +3716,34 @@ COUNT(*) EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null=3 ; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where +1 SIMPLE t1 ref idx1,idx2 idx2 4 const 2 Using where EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID1_with_null=3 AND ID2_with_null=3 IS NULL ; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where +1 SIMPLE t1 ref idx1,idx2 idx2 4 const 2 Using where EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null IS NULL; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where +1 SIMPLE t1 ref idx1,idx2 idx2 4 const 2 Using where DROP INDEX idx1 ON t1; CREATE UNIQUE INDEX idx1 ON t1(ID1_with_null,ID2_with_null); EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null=3 ; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where +1 SIMPLE t1 ref idx1,idx2 idx2 4 const 2 Using where EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID1_with_null=3 AND ID2_with_null IS NULL ; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where +1 SIMPLE t1 ref idx1,idx2 idx2 4 const 2 Using where EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null IS NULL; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where +1 SIMPLE t1 ref idx1,idx2 idx2 4 const 2 Using where EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID1_with_null IS NULL AND (ID2_with_null=1 OR ID2_with_null=2); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where +1 SIMPLE t1 ref|filter idx1,idx2 idx1|idx2 5|4 const 2 (1%) Using index condition; Using where; Using filter DROP TABLE t1; CREATE TABLE t1 (a INT, ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, KEY ts(ts)); INSERT INTO t1 VALUES (30,"2006-01-03 23:00:00"), (31,"2006-01-03 23:00:00"); @@ -3759,7 +3762,7 @@ AND t1.ts BETWEEN t2.dt1 AND t2.dt2 AND t1.ts BETWEEN "2006-01-01" AND "2006-12-31"; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 -1 SIMPLE t1 range ts ts 4 NULL 1 Using index condition; Using where +1 SIMPLE t1 range ts ts 4 NULL 2 Using index condition; Using where SELECT * FROM t1 LEFT JOIN t2 ON (t1.a=t2.a) WHERE t1.a=30 AND t1.ts BETWEEN t2.dt1 AND t2.dt2 AND t1.ts BETWEEN "2006-01-01" AND "2006-12-31"; @@ -3801,6 +3804,7 @@ INSERT INTO t1 VALUES ('ccc'), ('bb'), ('cc '), ('aa '), ('aa'); INSERT INTO t2 VALUES ('bb',1), ('aa',2), ('cc ',3); INSERT INTO t2 VALUES (concat('cc ', 0x06), 4); INSERT INTO t2 VALUES ('cc',5), ('bb ',6), ('cc ',7); +INSERT INTO t2 VALUES ('bb ',8), ('aa',9), ('aa',10), ('bb',11); SELECT * FROM t2; name n bb 1 @@ -3810,27 +3814,39 @@ cc 4 cc 5 bb 6 cc 7 +bb 8 +aa 9 +aa 10 +bb 11 SELECT * FROM t2 ORDER BY name; name n aa 2 +aa 10 +aa 9 bb 1 +bb 8 bb 6 +bb 11 cc 4 -cc 3 -cc 5 cc 7 +cc 5 +cc 3 SELECT name, LENGTH(name), n FROM t2 ORDER BY name; name LENGTH(name) n aa 2 2 +aa 2 10 +aa 2 9 bb 2 1 +bb 3 8 bb 3 6 +bb 2 11 cc 4 4 -cc 5 3 -cc 2 5 cc 3 7 +cc 2 5 +cc 5 3 EXPLAIN SELECT name, LENGTH(name), n FROM t2 WHERE name='cc '; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ref name name 6 const 3 Using where +1 SIMPLE t2 ref name name 6 const 4 Using where SELECT name, LENGTH(name), n FROM t2 WHERE name='cc '; name LENGTH(name) n cc 5 3 @@ -3838,7 +3854,7 @@ cc 2 5 cc 3 7 EXPLAIN SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range name name 6 NULL 3 Using where +1 SIMPLE t2 range name name 6 NULL 4 Using where SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%'; name LENGTH(name) n cc 5 3 @@ -3847,7 +3863,7 @@ cc 2 5 cc 3 7 EXPLAIN SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%' ORDER BY name; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range name name 6 NULL 3 Using where; Using filesort +1 SIMPLE t2 range name name 6 NULL 4 Using where; Using filesort SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%' ORDER BY name; name LENGTH(name) n cc 4 4 @@ -3863,11 +3879,17 @@ name name n ccc NULL NULL bb bb 1 bb bb 6 +bb bb 8 +bb bb 11 cc cc 3 cc cc 5 cc cc 7 aa aa 2 +aa aa 9 +aa aa 10 aa aa 2 +aa aa 9 +aa aa 10 DROP TABLE t1,t2; CREATE TABLE t1 (name text); CREATE TABLE t2 (name text, n int, KEY (name(3))); @@ -3875,6 +3897,7 @@ INSERT INTO t1 VALUES ('ccc'), ('bb'), ('cc '), ('aa '), ('aa'); INSERT INTO t2 VALUES ('bb',1), ('aa',2), ('cc ',3); INSERT INTO t2 VALUES (concat('cc ', 0x06), 4); INSERT INTO t2 VALUES ('cc',5), ('bb ',6), ('cc ',7); +INSERT INTO t2 VALUES ('bb ',8), ('aa',9), ('aa',10), ('bb',11); SELECT * FROM t2; name n bb 1 @@ -3884,11 +3907,19 @@ cc 4 cc 5 bb 6 cc 7 +bb 8 +aa 9 +aa 10 +bb 11 SELECT * FROM t2 ORDER BY name; name n aa 2 +aa 9 +aa 10 bb 1 bb 6 +bb 8 +bb 11 cc 4 cc 3 cc 5 @@ -3896,15 +3927,19 @@ cc 7 SELECT name, LENGTH(name), n FROM t2 ORDER BY name; name LENGTH(name) n aa 2 2 +aa 2 9 +aa 2 10 bb 2 1 bb 3 6 +bb 3 8 +bb 2 11 cc 4 4 cc 5 3 cc 2 5 cc 3 7 EXPLAIN SELECT name, LENGTH(name), n FROM t2 WHERE name='cc '; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ref name name 6 const 3 Using where +1 SIMPLE t2 ref name name 6 const 4 Using where SELECT name, LENGTH(name), n FROM t2 WHERE name='cc '; name LENGTH(name) n cc 5 3 @@ -3912,7 +3947,7 @@ cc 2 5 cc 3 7 EXPLAIN SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range name name 6 NULL 3 Using where +1 SIMPLE t2 range name name 6 NULL 4 Using where SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%'; name LENGTH(name) n cc 5 3 @@ -3921,7 +3956,7 @@ cc 2 5 cc 3 7 EXPLAIN SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%' ORDER BY name; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range name name 6 NULL 3 Using where; Using filesort +1 SIMPLE t2 range name name 6 NULL 4 Using where; Using filesort SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%' ORDER BY name; name LENGTH(name) n cc 4 4 @@ -3937,11 +3972,17 @@ name name n ccc NULL NULL bb bb 1 bb bb 6 +bb bb 8 +bb bb 11 cc cc 3 cc cc 5 cc cc 7 aa aa 2 +aa aa 9 +aa aa 10 aa aa 2 +aa aa 9 +aa aa 10 DROP TABLE t1,t2; CREATE TABLE t1 ( access_id int NOT NULL default '0', @@ -5211,7 +5252,7 @@ INSERT INTO `CC` VALUES EXPLAIN SELECT `varchar_nokey` G1 FROM CC WHERE `int_nokey` AND `int_key` <= 4 HAVING G1 ORDER BY `varchar_key` LIMIT 6 ; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE CC range int_key int_key 4 NULL 10 Using index condition; Using where; Using filesort +1 SIMPLE CC range int_key int_key 4 NULL 9 Using index condition; Using where; Using filesort SELECT `varchar_nokey` G1 FROM CC WHERE `int_nokey` AND `int_key` <= 4 HAVING G1 ORDER BY `varchar_key` LIMIT 6 ; G1 diff --git a/mysql-test/main/select.test b/mysql-test/main/select.test index 52ef4aa2111..0d43dfd55b9 100644 --- a/mysql-test/main/select.test +++ b/mysql-test/main/select.test @@ -2915,7 +2915,7 @@ CREATE TABLE t1 (sku int PRIMARY KEY, pr int); CREATE TABLE t2 (sku int PRIMARY KEY, sppr int, name varchar(255)); INSERT INTO t1 VALUES - (10, 10), (20, 10), (30, 20), (40, 30), (50, 10), (60, 10); + (10, 10), (20, 10), (30, 20), (40, 30), (50, 10), (60, 10), (70, 10); INSERT INTO t2 VALUES (10, 10, 'aaa'), (20, 10, 'bbb'), (30, 10, 'ccc'), (40, 20, 'ddd'), @@ -3048,7 +3048,7 @@ 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); +INSERT INTO t3 VALUES (2,10), (2,20), (1,30), (2,40), (2,50), (1,60), (3,70), (1,80), (3,90); EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t2.b=t1.a INNER JOIN t3 ON t3.d=t1.id @@ -3230,6 +3230,8 @@ INSERT INTO t1 SELECT * FROM t1 WHERE ID2_with_null IS NULL; INSERT INTO t1 SELECT * FROM t1 WHERE ID1_with_null IS NULL; INSERT INTO t1 SELECT * FROM t1 WHERE ID2_with_null IS NULL; +ANALYZE TABLE t1; + SELECT COUNT(*) FROM t1 WHERE ID1_with_null IS NULL AND ID2_with_null=3; SELECT COUNT(*) FROM t1 WHERE ID1_with_null=3 AND ID2_with_null IS NULL; SELECT COUNT(*) FROM t1 WHERE ID1_with_null IS NULL AND ID2_with_null IS NULL; @@ -3311,6 +3313,7 @@ INSERT INTO t1 VALUES ('ccc'), ('bb'), ('cc '), ('aa '), ('aa'); INSERT INTO t2 VALUES ('bb',1), ('aa',2), ('cc ',3); INSERT INTO t2 VALUES (concat('cc ', 0x06), 4); INSERT INTO t2 VALUES ('cc',5), ('bb ',6), ('cc ',7); +INSERT INTO t2 VALUES ('bb ',8), ('aa',9), ('aa',10), ('bb',11); SELECT * FROM t2; SELECT * FROM t2 ORDER BY name; SELECT name, LENGTH(name), n FROM t2 ORDER BY name; @@ -3332,6 +3335,7 @@ INSERT INTO t1 VALUES ('ccc'), ('bb'), ('cc '), ('aa '), ('aa'); INSERT INTO t2 VALUES ('bb',1), ('aa',2), ('cc ',3); INSERT INTO t2 VALUES (concat('cc ', 0x06), 4); INSERT INTO t2 VALUES ('cc',5), ('bb ',6), ('cc ',7); +INSERT INTO t2 VALUES ('bb ',8), ('aa',9), ('aa',10), ('bb',11); SELECT * FROM t2; SELECT * FROM t2 ORDER BY name; SELECT name, LENGTH(name), n FROM t2 ORDER BY name; diff --git a/mysql-test/main/select_jcl6.result b/mysql-test/main/select_jcl6.result index b45fb8c4c10..bc86a27bce9 100644 --- a/mysql-test/main/select_jcl6.result +++ b/mysql-test/main/select_jcl6.result @@ -2797,7 +2797,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index key1 key1 5 NULL 4 Using where; Using index explain select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range key1 key1 5 NULL 3 Using where; Using index +1 SIMPLE t1 index key1 key1 5 NULL 4 Using where; Using index select max(key1) from t1 where key1 <= 0.6158; max(key1) 0.6158000230789185 @@ -3419,7 +3419,7 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp CREATE TABLE t1 (sku int PRIMARY KEY, pr int); CREATE TABLE t2 (sku int PRIMARY KEY, sppr int, name varchar(255)); INSERT INTO t1 VALUES -(10, 10), (20, 10), (30, 20), (40, 30), (50, 10), (60, 10); +(10, 10), (20, 10), (30, 20), (40, 30), (50, 10), (60, 10), (70, 10); INSERT INTO t2 VALUES (10, 10, 'aaa'), (20, 10, 'bbb'), (30, 10, 'ccc'), (40, 20, 'ddd'), (50, 10, 'eee'), (60, 20, 'fff'), (70, 20, 'ggg'), (80, 30, 'hhh'); @@ -3533,7 +3533,7 @@ INSERT INTO t2 VALUES 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 +1 SIMPLE t2 ref idx idx 4 const 8 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 @@ -3544,14 +3544,14 @@ 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); +INSERT INTO t3 VALUES (2,10), (2,20), (1,30), (2,40), (2,50), (1,60), (3,70), (1,80), (3,90); 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 +1 SIMPLE t3 ref idx1 idx1 5 const 4 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 @@ -3580,7 +3580,7 @@ EXPLAIN SELECT t2.* FROM t1 JOIN t2 ON t2.fk=t1.pk WHERE t2.fk < 'c' AND t2.pk=t1.fk; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 3 Using index condition; Using where; Rowid-ordered scan +1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 2 Using index condition; Using where; Rowid-ordered scan 1 SIMPLE t2 eq_ref PRIMARY PRIMARY 18 test.t1.fk 1 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan EXPLAIN SELECT t2.* FROM t1 JOIN t2 ON t2.fk=t1.pk @@ -3627,7 +3627,7 @@ t3.a=t2.a AND t3.c IN ('bb','ee'); 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 range si si 5 NULL 4 Using index condition; Using where; Rowid-ordered scan -1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +1 SIMPLE t3 eq_ref|filter PRIMARY,ci PRIMARY|ci 4|5 test.t2.a 1 (30%) Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan; Using filter EXPLAIN SELECT t3.a FROM t1,t2,t3 WHERE t1.id = 8 AND t2.i BETWEEN t1.b AND t1.e AND @@ -3635,7 +3635,7 @@ t3.a=t2.a AND t3.c IN ('bb','ee') ; 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 range si,ai si 5 NULL 4 Using index condition; Using where; Rowid-ordered scan -1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +1 SIMPLE t3 eq_ref|filter PRIMARY,ci PRIMARY|ci 4|5 test.t2.a 1 (30%) Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan; Using filter EXPLAIN SELECT t3.a FROM t1,t2 FORCE INDEX (si),t3 WHERE t1.id = 8 AND (t2.i=t1.b OR t2.i=t1.e) AND t3.a=t2.a AND @@ -3709,6 +3709,9 @@ INSERT INTO t1 SELECT * FROM t1 WHERE ID1_with_null IS NULL; INSERT INTO t1 SELECT * FROM t1 WHERE ID2_with_null IS NULL; INSERT INTO t1 SELECT * FROM t1 WHERE ID1_with_null IS NULL; INSERT INTO t1 SELECT * FROM t1 WHERE ID2_with_null IS NULL; +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK SELECT COUNT(*) FROM t1 WHERE ID1_with_null IS NULL AND ID2_with_null=3; COUNT(*) 24 @@ -3724,34 +3727,34 @@ COUNT(*) EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null=3 ; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where +1 SIMPLE t1 ref idx1,idx2 idx2 4 const 2 Using where EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID1_with_null=3 AND ID2_with_null=3 IS NULL ; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where +1 SIMPLE t1 ref idx1,idx2 idx2 4 const 2 Using where EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null IS NULL; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where +1 SIMPLE t1 ref idx1,idx2 idx2 4 const 2 Using where DROP INDEX idx1 ON t1; CREATE UNIQUE INDEX idx1 ON t1(ID1_with_null,ID2_with_null); EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null=3 ; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where +1 SIMPLE t1 ref idx1,idx2 idx2 4 const 2 Using where EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID1_with_null=3 AND ID2_with_null IS NULL ; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where +1 SIMPLE t1 ref idx1,idx2 idx2 4 const 2 Using where EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null IS NULL; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where +1 SIMPLE t1 ref idx1,idx2 idx2 4 const 2 Using where EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID1_with_null IS NULL AND (ID2_with_null=1 OR ID2_with_null=2); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where +1 SIMPLE t1 ref|filter idx1,idx2 idx1|idx2 5|4 const 2 (1%) Using index condition; Using where; Using filter DROP TABLE t1; CREATE TABLE t1 (a INT, ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, KEY ts(ts)); INSERT INTO t1 VALUES (30,"2006-01-03 23:00:00"), (31,"2006-01-03 23:00:00"); @@ -3770,7 +3773,7 @@ AND t1.ts BETWEEN t2.dt1 AND t2.dt2 AND t1.ts BETWEEN "2006-01-01" AND "2006-12-31"; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 -1 SIMPLE t1 range ts ts 4 NULL 1 Using index condition; Using where; Rowid-ordered scan +1 SIMPLE t1 range ts ts 4 NULL 2 Using index condition; Using where; Rowid-ordered scan SELECT * FROM t1 LEFT JOIN t2 ON (t1.a=t2.a) WHERE t1.a=30 AND t1.ts BETWEEN t2.dt1 AND t2.dt2 AND t1.ts BETWEEN "2006-01-01" AND "2006-12-31"; @@ -3812,6 +3815,7 @@ INSERT INTO t1 VALUES ('ccc'), ('bb'), ('cc '), ('aa '), ('aa'); INSERT INTO t2 VALUES ('bb',1), ('aa',2), ('cc ',3); INSERT INTO t2 VALUES (concat('cc ', 0x06), 4); INSERT INTO t2 VALUES ('cc',5), ('bb ',6), ('cc ',7); +INSERT INTO t2 VALUES ('bb ',8), ('aa',9), ('aa',10), ('bb',11); SELECT * FROM t2; name n bb 1 @@ -3821,27 +3825,39 @@ cc 4 cc 5 bb 6 cc 7 +bb 8 +aa 9 +aa 10 +bb 11 SELECT * FROM t2 ORDER BY name; name n aa 2 +aa 10 +aa 9 bb 1 +bb 8 bb 6 +bb 11 cc 4 -cc 3 -cc 5 cc 7 +cc 5 +cc 3 SELECT name, LENGTH(name), n FROM t2 ORDER BY name; name LENGTH(name) n aa 2 2 +aa 2 10 +aa 2 9 bb 2 1 +bb 3 8 bb 3 6 +bb 2 11 cc 4 4 -cc 5 3 -cc 2 5 cc 3 7 +cc 2 5 +cc 5 3 EXPLAIN SELECT name, LENGTH(name), n FROM t2 WHERE name='cc '; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ref name name 6 const 3 Using where +1 SIMPLE t2 ref name name 6 const 4 Using where SELECT name, LENGTH(name), n FROM t2 WHERE name='cc '; name LENGTH(name) n cc 5 3 @@ -3849,7 +3865,7 @@ cc 2 5 cc 3 7 EXPLAIN SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range name name 6 NULL 3 Using where +1 SIMPLE t2 range name name 6 NULL 4 Using where SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%'; name LENGTH(name) n cc 5 3 @@ -3858,7 +3874,7 @@ cc 2 5 cc 3 7 EXPLAIN SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%' ORDER BY name; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range name name 6 NULL 3 Using where; Using filesort +1 SIMPLE t2 range name name 6 NULL 4 Using where; Using filesort SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%' ORDER BY name; name LENGTH(name) n cc 4 4 @@ -3874,11 +3890,17 @@ name name n ccc NULL NULL bb bb 1 bb bb 6 +bb bb 8 +bb bb 11 cc cc 3 cc cc 5 cc cc 7 aa aa 2 +aa aa 9 +aa aa 10 aa aa 2 +aa aa 9 +aa aa 10 DROP TABLE t1,t2; CREATE TABLE t1 (name text); CREATE TABLE t2 (name text, n int, KEY (name(3))); @@ -3886,6 +3908,7 @@ INSERT INTO t1 VALUES ('ccc'), ('bb'), ('cc '), ('aa '), ('aa'); INSERT INTO t2 VALUES ('bb',1), ('aa',2), ('cc ',3); INSERT INTO t2 VALUES (concat('cc ', 0x06), 4); INSERT INTO t2 VALUES ('cc',5), ('bb ',6), ('cc ',7); +INSERT INTO t2 VALUES ('bb ',8), ('aa',9), ('aa',10), ('bb',11); SELECT * FROM t2; name n bb 1 @@ -3895,11 +3918,19 @@ cc 4 cc 5 bb 6 cc 7 +bb 8 +aa 9 +aa 10 +bb 11 SELECT * FROM t2 ORDER BY name; name n aa 2 +aa 9 +aa 10 bb 1 bb 6 +bb 8 +bb 11 cc 4 cc 3 cc 5 @@ -3907,15 +3938,19 @@ cc 7 SELECT name, LENGTH(name), n FROM t2 ORDER BY name; name LENGTH(name) n aa 2 2 +aa 2 9 +aa 2 10 bb 2 1 bb 3 6 +bb 3 8 +bb 2 11 cc 4 4 cc 5 3 cc 2 5 cc 3 7 EXPLAIN SELECT name, LENGTH(name), n FROM t2 WHERE name='cc '; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ref name name 6 const 3 Using where +1 SIMPLE t2 ref name name 6 const 4 Using where SELECT name, LENGTH(name), n FROM t2 WHERE name='cc '; name LENGTH(name) n cc 5 3 @@ -3923,7 +3958,7 @@ cc 2 5 cc 3 7 EXPLAIN SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range name name 6 NULL 3 Using where +1 SIMPLE t2 range name name 6 NULL 4 Using where SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%'; name LENGTH(name) n cc 5 3 @@ -3932,7 +3967,7 @@ cc 2 5 cc 3 7 EXPLAIN SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%' ORDER BY name; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range name name 6 NULL 3 Using where; Using filesort +1 SIMPLE t2 range name name 6 NULL 4 Using where; Using filesort SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%' ORDER BY name; name LENGTH(name) n cc 4 4 @@ -3948,11 +3983,17 @@ name name n ccc NULL NULL bb bb 1 bb bb 6 +bb bb 8 +bb bb 11 cc cc 3 cc cc 5 cc cc 7 aa aa 2 +aa aa 9 +aa aa 10 aa aa 2 +aa aa 9 +aa aa 10 DROP TABLE t1,t2; CREATE TABLE t1 ( access_id int NOT NULL default '0', @@ -5222,7 +5263,7 @@ INSERT INTO `CC` VALUES EXPLAIN SELECT `varchar_nokey` G1 FROM CC WHERE `int_nokey` AND `int_key` <= 4 HAVING G1 ORDER BY `varchar_key` LIMIT 6 ; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE CC range int_key int_key 4 NULL 10 Using index condition; Using where; Rowid-ordered scan; Using filesort +1 SIMPLE CC range int_key int_key 4 NULL 9 Using index condition; Using where; Rowid-ordered scan; Using filesort SELECT `varchar_nokey` G1 FROM CC WHERE `int_nokey` AND `int_key` <= 4 HAVING G1 ORDER BY `varchar_key` LIMIT 6 ; G1 diff --git a/mysql-test/main/select_pkeycache.result b/mysql-test/main/select_pkeycache.result index 94a92315acc..220f500e37a 100644 --- a/mysql-test/main/select_pkeycache.result +++ b/mysql-test/main/select_pkeycache.result @@ -2786,7 +2786,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index key1 key1 5 NULL 4 Using where; Using index explain select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range key1 key1 5 NULL 3 Using where; Using index +1 SIMPLE t1 index key1 key1 5 NULL 4 Using where; Using index select max(key1) from t1 where key1 <= 0.6158; max(key1) 0.6158000230789185 @@ -3408,7 +3408,7 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp CREATE TABLE t1 (sku int PRIMARY KEY, pr int); CREATE TABLE t2 (sku int PRIMARY KEY, sppr int, name varchar(255)); INSERT INTO t1 VALUES -(10, 10), (20, 10), (30, 20), (40, 30), (50, 10), (60, 10); +(10, 10), (20, 10), (30, 20), (40, 30), (50, 10), (60, 10), (70, 10); INSERT INTO t2 VALUES (10, 10, 'aaa'), (20, 10, 'bbb'), (30, 10, 'ccc'), (40, 20, 'ddd'), (50, 10, 'eee'), (60, 20, 'fff'), (70, 20, 'ggg'), (80, 30, 'hhh'); @@ -3522,7 +3522,7 @@ INSERT INTO t2 VALUES 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 +1 SIMPLE t2 ref idx idx 4 const 8 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 @@ -3533,14 +3533,14 @@ 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); +INSERT INTO t3 VALUES (2,10), (2,20), (1,30), (2,40), (2,50), (1,60), (3,70), (1,80), (3,90); 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 +1 SIMPLE t3 ref idx1 idx1 5 const 4 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 @@ -3569,7 +3569,7 @@ EXPLAIN SELECT t2.* FROM t1 JOIN t2 ON t2.fk=t1.pk WHERE t2.fk < 'c' AND t2.pk=t1.fk; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 3 Using index condition; Using where +1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 2 Using index condition; Using where 1 SIMPLE t2 eq_ref PRIMARY PRIMARY 18 test.t1.fk 1 Using where EXPLAIN SELECT t2.* FROM t1 JOIN t2 ON t2.fk=t1.pk @@ -3616,7 +3616,7 @@ t3.a=t2.a AND t3.c IN ('bb','ee'); 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 range si si 5 NULL 4 Using index condition; Using where -1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where +1 SIMPLE t3 eq_ref|filter PRIMARY,ci PRIMARY|ci 4|5 test.t2.a 1 (30%) Using where; Using filter EXPLAIN SELECT t3.a FROM t1,t2,t3 WHERE t1.id = 8 AND t2.i BETWEEN t1.b AND t1.e AND @@ -3624,7 +3624,7 @@ t3.a=t2.a AND t3.c IN ('bb','ee') ; 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 range si,ai si 5 NULL 4 Using index condition; Using where -1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where +1 SIMPLE t3 eq_ref|filter PRIMARY,ci PRIMARY|ci 4|5 test.t2.a 1 (30%) Using where; Using filter EXPLAIN SELECT t3.a FROM t1,t2 FORCE INDEX (si),t3 WHERE t1.id = 8 AND (t2.i=t1.b OR t2.i=t1.e) AND t3.a=t2.a AND @@ -3698,6 +3698,9 @@ INSERT INTO t1 SELECT * FROM t1 WHERE ID1_with_null IS NULL; INSERT INTO t1 SELECT * FROM t1 WHERE ID2_with_null IS NULL; INSERT INTO t1 SELECT * FROM t1 WHERE ID1_with_null IS NULL; INSERT INTO t1 SELECT * FROM t1 WHERE ID2_with_null IS NULL; +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK SELECT COUNT(*) FROM t1 WHERE ID1_with_null IS NULL AND ID2_with_null=3; COUNT(*) 24 @@ -3713,34 +3716,34 @@ COUNT(*) EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null=3 ; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where +1 SIMPLE t1 ref idx1,idx2 idx2 4 const 2 Using where EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID1_with_null=3 AND ID2_with_null=3 IS NULL ; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where +1 SIMPLE t1 ref idx1,idx2 idx2 4 const 2 Using where EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null IS NULL; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where +1 SIMPLE t1 ref idx1,idx2 idx2 4 const 2 Using where DROP INDEX idx1 ON t1; CREATE UNIQUE INDEX idx1 ON t1(ID1_with_null,ID2_with_null); EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null=3 ; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where +1 SIMPLE t1 ref idx1,idx2 idx2 4 const 2 Using where EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID1_with_null=3 AND ID2_with_null IS NULL ; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where +1 SIMPLE t1 ref idx1,idx2 idx2 4 const 2 Using where EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null IS NULL; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where +1 SIMPLE t1 ref idx1,idx2 idx2 4 const 2 Using where EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID1_with_null IS NULL AND (ID2_with_null=1 OR ID2_with_null=2); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where +1 SIMPLE t1 ref|filter idx1,idx2 idx1|idx2 5|4 const 2 (1%) Using index condition; Using where; Using filter DROP TABLE t1; CREATE TABLE t1 (a INT, ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, KEY ts(ts)); INSERT INTO t1 VALUES (30,"2006-01-03 23:00:00"), (31,"2006-01-03 23:00:00"); @@ -3759,7 +3762,7 @@ AND t1.ts BETWEEN t2.dt1 AND t2.dt2 AND t1.ts BETWEEN "2006-01-01" AND "2006-12-31"; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 -1 SIMPLE t1 range ts ts 4 NULL 1 Using index condition; Using where +1 SIMPLE t1 range ts ts 4 NULL 2 Using index condition; Using where SELECT * FROM t1 LEFT JOIN t2 ON (t1.a=t2.a) WHERE t1.a=30 AND t1.ts BETWEEN t2.dt1 AND t2.dt2 AND t1.ts BETWEEN "2006-01-01" AND "2006-12-31"; @@ -3801,6 +3804,7 @@ INSERT INTO t1 VALUES ('ccc'), ('bb'), ('cc '), ('aa '), ('aa'); INSERT INTO t2 VALUES ('bb',1), ('aa',2), ('cc ',3); INSERT INTO t2 VALUES (concat('cc ', 0x06), 4); INSERT INTO t2 VALUES ('cc',5), ('bb ',6), ('cc ',7); +INSERT INTO t2 VALUES ('bb ',8), ('aa',9), ('aa',10), ('bb',11); SELECT * FROM t2; name n bb 1 @@ -3810,27 +3814,39 @@ cc 4 cc 5 bb 6 cc 7 +bb 8 +aa 9 +aa 10 +bb 11 SELECT * FROM t2 ORDER BY name; name n aa 2 +aa 10 +aa 9 bb 1 +bb 8 bb 6 +bb 11 cc 4 -cc 3 -cc 5 cc 7 +cc 5 +cc 3 SELECT name, LENGTH(name), n FROM t2 ORDER BY name; name LENGTH(name) n aa 2 2 +aa 2 10 +aa 2 9 bb 2 1 +bb 3 8 bb 3 6 +bb 2 11 cc 4 4 -cc 5 3 -cc 2 5 cc 3 7 +cc 2 5 +cc 5 3 EXPLAIN SELECT name, LENGTH(name), n FROM t2 WHERE name='cc '; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ref name name 6 const 3 Using where +1 SIMPLE t2 ref name name 6 const 4 Using where SELECT name, LENGTH(name), n FROM t2 WHERE name='cc '; name LENGTH(name) n cc 5 3 @@ -3838,7 +3854,7 @@ cc 2 5 cc 3 7 EXPLAIN SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range name name 6 NULL 3 Using where +1 SIMPLE t2 range name name 6 NULL 4 Using where SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%'; name LENGTH(name) n cc 5 3 @@ -3847,7 +3863,7 @@ cc 2 5 cc 3 7 EXPLAIN SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%' ORDER BY name; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range name name 6 NULL 3 Using where; Using filesort +1 SIMPLE t2 range name name 6 NULL 4 Using where; Using filesort SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%' ORDER BY name; name LENGTH(name) n cc 4 4 @@ -3863,11 +3879,17 @@ name name n ccc NULL NULL bb bb 1 bb bb 6 +bb bb 8 +bb bb 11 cc cc 3 cc cc 5 cc cc 7 aa aa 2 +aa aa 9 +aa aa 10 aa aa 2 +aa aa 9 +aa aa 10 DROP TABLE t1,t2; CREATE TABLE t1 (name text); CREATE TABLE t2 (name text, n int, KEY (name(3))); @@ -3875,6 +3897,7 @@ INSERT INTO t1 VALUES ('ccc'), ('bb'), ('cc '), ('aa '), ('aa'); INSERT INTO t2 VALUES ('bb',1), ('aa',2), ('cc ',3); INSERT INTO t2 VALUES (concat('cc ', 0x06), 4); INSERT INTO t2 VALUES ('cc',5), ('bb ',6), ('cc ',7); +INSERT INTO t2 VALUES ('bb ',8), ('aa',9), ('aa',10), ('bb',11); SELECT * FROM t2; name n bb 1 @@ -3884,11 +3907,19 @@ cc 4 cc 5 bb 6 cc 7 +bb 8 +aa 9 +aa 10 +bb 11 SELECT * FROM t2 ORDER BY name; name n aa 2 +aa 9 +aa 10 bb 1 bb 6 +bb 8 +bb 11 cc 4 cc 3 cc 5 @@ -3896,15 +3927,19 @@ cc 7 SELECT name, LENGTH(name), n FROM t2 ORDER BY name; name LENGTH(name) n aa 2 2 +aa 2 9 +aa 2 10 bb 2 1 bb 3 6 +bb 3 8 +bb 2 11 cc 4 4 cc 5 3 cc 2 5 cc 3 7 EXPLAIN SELECT name, LENGTH(name), n FROM t2 WHERE name='cc '; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ref name name 6 const 3 Using where +1 SIMPLE t2 ref name name 6 const 4 Using where SELECT name, LENGTH(name), n FROM t2 WHERE name='cc '; name LENGTH(name) n cc 5 3 @@ -3912,7 +3947,7 @@ cc 2 5 cc 3 7 EXPLAIN SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range name name 6 NULL 3 Using where +1 SIMPLE t2 range name name 6 NULL 4 Using where SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%'; name LENGTH(name) n cc 5 3 @@ -3921,7 +3956,7 @@ cc 2 5 cc 3 7 EXPLAIN SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%' ORDER BY name; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range name name 6 NULL 3 Using where; Using filesort +1 SIMPLE t2 range name name 6 NULL 4 Using where; Using filesort SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%' ORDER BY name; name LENGTH(name) n cc 4 4 @@ -3937,11 +3972,17 @@ name name n ccc NULL NULL bb bb 1 bb bb 6 +bb bb 8 +bb bb 11 cc cc 3 cc cc 5 cc cc 7 aa aa 2 +aa aa 9 +aa aa 10 aa aa 2 +aa aa 9 +aa aa 10 DROP TABLE t1,t2; CREATE TABLE t1 ( access_id int NOT NULL default '0', @@ -5211,7 +5252,7 @@ INSERT INTO `CC` VALUES EXPLAIN SELECT `varchar_nokey` G1 FROM CC WHERE `int_nokey` AND `int_key` <= 4 HAVING G1 ORDER BY `varchar_key` LIMIT 6 ; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE CC range int_key int_key 4 NULL 10 Using index condition; Using where; Using filesort +1 SIMPLE CC range int_key int_key 4 NULL 9 Using index condition; Using where; Using filesort SELECT `varchar_nokey` G1 FROM CC WHERE `int_nokey` AND `int_key` <= 4 HAVING G1 ORDER BY `varchar_key` LIMIT 6 ; G1 diff --git a/mysql-test/main/selectivity.result b/mysql-test/main/selectivity.result index 00907235ecc..dc349a6008b 100644 --- a/mysql-test/main/selectivity.result +++ b/mysql-test/main/selectivity.result @@ -141,9 +141,9 @@ order by s_suppkey; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY supplier ALL PRIMARY NULL NULL NULL 10 100.00 Using filesort 1 PRIMARY <derived3> ref key0 key0 5 dbt3_s001.supplier.s_suppkey 10 100.00 Using where -3 DERIVED lineitem range i_l_shipdate,i_l_suppkey i_l_shipdate 4 NULL 268 100.00 Using where; Using temporary; Using filesort -2 SUBQUERY <derived4> ALL NULL NULL NULL NULL 268 100.00 -4 DERIVED lineitem range i_l_shipdate i_l_shipdate 4 NULL 268 100.00 Using where; Using temporary; Using filesort +3 DERIVED lineitem range i_l_shipdate,i_l_suppkey i_l_shipdate 4 NULL 269 100.00 Using where; Using temporary; Using filesort +2 SUBQUERY <derived4> ALL NULL NULL NULL NULL 269 100.00 +4 DERIVED lineitem range i_l_shipdate i_l_shipdate 4 NULL 269 100.00 Using where; Using temporary; Using filesort Warnings: Note 1003 /* select#1 */ select `dbt3_s001`.`supplier`.`s_suppkey` AS `s_suppkey`,`dbt3_s001`.`supplier`.`s_name` AS `s_name`,`dbt3_s001`.`supplier`.`s_address` AS `s_address`,`dbt3_s001`.`supplier`.`s_phone` AS `s_phone`,`revenue0`.`total_revenue` AS `total_revenue` from `dbt3_s001`.`supplier` join `dbt3_s001`.`revenue0` where `revenue0`.`supplier_no` = `dbt3_s001`.`supplier`.`s_suppkey` and `revenue0`.`total_revenue` = (/* select#2 */ select max(`revenue0`.`total_revenue`) from `dbt3_s001`.`revenue0`) order by `dbt3_s001`.`supplier`.`s_suppkey` select s_suppkey, s_name, s_address, s_phone, total_revenue @@ -162,9 +162,9 @@ order by s_suppkey; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY supplier ALL PRIMARY NULL NULL NULL 10 100.00 Using filesort 1 PRIMARY <derived3> ref key0 key0 5 dbt3_s001.supplier.s_suppkey 10 100.00 Using where -3 DERIVED lineitem range i_l_shipdate,i_l_suppkey i_l_shipdate 4 NULL 268 100.00 Using where; Using temporary; Using filesort -2 SUBQUERY <derived4> ALL NULL NULL NULL NULL 268 100.00 -4 DERIVED lineitem range i_l_shipdate i_l_shipdate 4 NULL 268 100.00 Using where; Using temporary; Using filesort +3 DERIVED lineitem range i_l_shipdate,i_l_suppkey i_l_shipdate 4 NULL 269 100.00 Using where; Using temporary; Using filesort +2 SUBQUERY <derived4> ALL NULL NULL NULL NULL 269 100.00 +4 DERIVED lineitem range i_l_shipdate i_l_shipdate 4 NULL 269 100.00 Using where; Using temporary; Using filesort Warnings: Note 1003 /* select#1 */ select `dbt3_s001`.`supplier`.`s_suppkey` AS `s_suppkey`,`dbt3_s001`.`supplier`.`s_name` AS `s_name`,`dbt3_s001`.`supplier`.`s_address` AS `s_address`,`dbt3_s001`.`supplier`.`s_phone` AS `s_phone`,`revenue0`.`total_revenue` AS `total_revenue` from `dbt3_s001`.`supplier` join `dbt3_s001`.`revenue0` where `revenue0`.`supplier_no` = `dbt3_s001`.`supplier`.`s_suppkey` and `revenue0`.`total_revenue` = (/* select#2 */ select max(`revenue0`.`total_revenue`) from `dbt3_s001`.`revenue0`) order by `dbt3_s001`.`supplier`.`s_suppkey` select s_suppkey, s_name, s_address, s_phone, total_revenue diff --git a/mysql-test/main/selectivity_no_engine.result b/mysql-test/main/selectivity_no_engine.result index 7fc3c6e9909..743dcd04695 100644 --- a/mysql-test/main/selectivity_no_engine.result +++ b/mysql-test/main/selectivity_no_engine.result @@ -161,7 +161,7 @@ Note 1003 select `test`.`t1`.`key1` AS `key1`,`test`.`t1`.`col1` AS `col1` from # Must show 100%, not 10% explain extended select * from t1 where key1=2; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 ref key1 key1 5 const 98 100.00 +1 SIMPLE t1 ref key1 key1 5 const 99 100.00 Warnings: Note 1003 select `test`.`t1`.`key1` AS `key1`,`test`.`t1`.`col1` AS `col1` from `test`.`t1` where `test`.`t1`.`key1` = 2 drop table t0, t1; @@ -231,11 +231,12 @@ f2 varchar(1024), KEY (f1,f2(255)) ); INSERT INTO t2 VALUES ('foo','baz','qux'),('bar','baz','qux'); +INSERT INTO t2 VALUES ('foo','bazz','qux'),('bar','bazz','qux'); set optimizer_use_condition_selectivity=2; explain select * from t1,t2 where t1.id = t2.t1_id and t2.f2='qux' and t2.f1='baz'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ref f1 f1 325 const,const 1 Using index condition; Using where +1 SIMPLE t2 ref f1 f1 325 const,const 2 Using index condition; Using where 1 SIMPLE t1 eq_ref PRIMARY PRIMARY 122 test.t2.t1_id 1 select * from t1,t2 where t1.id = t2.t1_id and t2.f2='qux' and t2.f1='baz'; id dt t1_id f1 f2 diff --git a/mysql-test/main/selectivity_no_engine.test b/mysql-test/main/selectivity_no_engine.test index 2a31c01ed97..270e719e74c 100644 --- a/mysql-test/main/selectivity_no_engine.test +++ b/mysql-test/main/selectivity_no_engine.test @@ -181,6 +181,7 @@ CREATE TABLE t2 ( ); INSERT INTO t2 VALUES ('foo','baz','qux'),('bar','baz','qux'); +INSERT INTO t2 VALUES ('foo','bazz','qux'),('bar','bazz','qux'); set optimizer_use_condition_selectivity=2; explain diff --git a/mysql-test/main/show_explain.cc b/mysql-test/main/show_explain.cc new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/mysql-test/main/show_explain.cc diff --git a/mysql-test/main/show_explain.result b/mysql-test/main/show_explain.result index 0819ae5ba37..32364d0ec89 100644 --- a/mysql-test/main/show_explain.result +++ b/mysql-test/main/show_explain.result @@ -641,7 +641,7 @@ SELECT 'test' FROM t1 WHERE a=1; connection default; show explain for $thr2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref a a 5 const 1 Using index +1 SIMPLE t1 ref a a 5 const 2 Using index Warnings: Note 1003 SELECT 'test' FROM t1 WHERE a=1 connection con1; diff --git a/mysql-test/main/show_explain.test b/mysql-test/main/show_explain.test index 6615ff66737..6647ca07eba 100644 --- a/mysql-test/main/show_explain.test +++ b/mysql-test/main/show_explain.test @@ -4,6 +4,7 @@ --source include/have_debug.inc --source include/have_innodb.inc + --disable_warnings drop table if exists t0, t1, t2, t3, t4; drop view if exists v1; @@ -328,6 +329,7 @@ connection con1; set debug_dbug='+d,show_explain_probe_join_exec_start'; set @show_explain_probe_select_id=1; + send select distinct a from t0; connection default; --source include/wait_condition.inc @@ -1202,3 +1204,4 @@ drop table t0,t1,t2; connection default; disconnect con1; set debug_sync='RESET'; + diff --git a/mysql-test/main/stat_tables.result b/mysql-test/main/stat_tables.result index 40290ca9879..9a5c023a72f 100644 --- a/mysql-test/main/stat_tables.result +++ b/mysql-test/main/stat_tables.result @@ -332,7 +332,7 @@ and o_orderkey=l_orderkey and p_partkey=l_partkey; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE orders ref PRIMARY,i_o_orderdate i_o_orderdate 4 const 1 1 SIMPLE lineitem ref PRIMARY,i_l_suppkey_partkey,i_l_partkey,i_l_orderkey,i_l_orderkey_quantity PRIMARY 4 dbt3_s001.orders.o_orderkey 4 Using where -1 SIMPLE part eq_ref PRIMARY,i_p_retailprice PRIMARY 4 dbt3_s001.lineitem.l_partkey 1 Using where +1 SIMPLE part eq_ref|filter PRIMARY,i_p_retailprice PRIMARY|i_p_retailprice 4|9 dbt3_s001.lineitem.l_partkey 1 (1%) Using where; Using filter select o_orderkey, p_partkey from part, lineitem, orders where p_retailprice > 1100 and o_orderdate='1997-01-01' diff --git a/mysql-test/main/stat_tables_disabled.result b/mysql-test/main/stat_tables_disabled.result index f57abc34e0c..b1c37169f02 100644 --- a/mysql-test/main/stat_tables_disabled.result +++ b/mysql-test/main/stat_tables_disabled.result @@ -1,3 +1,8 @@ +set @innodb_stats_persistent_save= @@innodb_stats_persistent; +set @innodb_stats_persistent_sample_pages_save= +@@innodb_stats_persistent_sample_pages; +set global innodb_stats_persistent= 1; +set global innodb_stats_persistent_sample_pages=100; SET SESSION STORAGE_ENGINE='InnoDB'; select @@global.use_stat_tables; @@global.use_stat_tables @@ -12,6 +17,7 @@ CREATE DATABASE dbt3_s001; use dbt3_s001; set @save_optimizer_switch=@@optimizer_switch; set optimizer_switch='extended_keys=off'; +set optimizer_switch='rowid_filter=off'; # # Bug mdev-503: optimizer ignores setting use_stat_tables='preferably' # @@ -68,3 +74,6 @@ DROP DATABASE dbt3_s001; use test; set use_stat_tables=@save_use_stat_tables; SET SESSION STORAGE_ENGINE=DEFAULT; +set global innodb_stats_persistent= @innodb_stats_persistent_save; +set global innodb_stats_persistent_sample_pages= +@innodb_stats_persistent_sample_pages_save; diff --git a/mysql-test/main/stat_tables_disabled.test b/mysql-test/main/stat_tables_disabled.test index c9d923f903b..427cf4874bc 100644 --- a/mysql-test/main/stat_tables_disabled.test +++ b/mysql-test/main/stat_tables_disabled.test @@ -1,3 +1,9 @@ +set @innodb_stats_persistent_save= @@innodb_stats_persistent; +set @innodb_stats_persistent_sample_pages_save= + @@innodb_stats_persistent_sample_pages; + +set global innodb_stats_persistent= 1; +set global innodb_stats_persistent_sample_pages=100; --source include/have_innodb.inc SET SESSION STORAGE_ENGINE='InnoDB'; @@ -19,6 +25,7 @@ use dbt3_s001; set @save_optimizer_switch=@@optimizer_switch; set optimizer_switch='extended_keys=off'; +set optimizer_switch='rowid_filter=off'; --disable_query_log --disable_result_log @@ -76,3 +83,7 @@ set use_stat_tables=@save_use_stat_tables; SET SESSION STORAGE_ENGINE=DEFAULT; + +set global innodb_stats_persistent= @innodb_stats_persistent_save; +set global innodb_stats_persistent_sample_pages= + @innodb_stats_persistent_sample_pages_save; diff --git a/mysql-test/main/stat_tables_innodb.result b/mysql-test/main/stat_tables_innodb.result index 070d13d9bb1..69c07b0932f 100644 --- a/mysql-test/main/stat_tables_innodb.result +++ b/mysql-test/main/stat_tables_innodb.result @@ -1,6 +1,11 @@ SET SESSION STORAGE_ENGINE='InnoDB'; set @save_optimizer_switch_for_stat_tables_test=@@optimizer_switch; set optimizer_switch='extended_keys=on'; +set @innodb_stats_persistent_save= @@innodb_stats_persistent; +set @innodb_stats_persistent_sample_pages_save= +@@innodb_stats_persistent_sample_pages; +set global innodb_stats_persistent= 1; +set global innodb_stats_persistent_sample_pages=100; select @@global.use_stat_tables; @@global.use_stat_tables COMPLEMENTARY @@ -633,5 +638,8 @@ MAX(pk) NULL DROP TABLE t1; set use_stat_tables=@save_use_stat_tables; +set global innodb_stats_persistent= @innodb_stats_persistent_save; +set global innodb_stats_persistent_sample_pages= +@innodb_stats_persistent_sample_pages_save; set optimizer_switch=@save_optimizer_switch_for_stat_tables_test; SET SESSION STORAGE_ENGINE=DEFAULT; diff --git a/mysql-test/main/stat_tables_innodb.test b/mysql-test/main/stat_tables_innodb.test index 04e81de8f9d..5a97ad89363 100644 --- a/mysql-test/main/stat_tables_innodb.test +++ b/mysql-test/main/stat_tables_innodb.test @@ -5,7 +5,16 @@ SET SESSION STORAGE_ENGINE='InnoDB'; set @save_optimizer_switch_for_stat_tables_test=@@optimizer_switch; set optimizer_switch='extended_keys=on'; +set @innodb_stats_persistent_save= @@innodb_stats_persistent; +set @innodb_stats_persistent_sample_pages_save= + @@innodb_stats_persistent_sample_pages; + +set global innodb_stats_persistent= 1; +set global innodb_stats_persistent_sample_pages=100; --source stat_tables.test +set global innodb_stats_persistent= @innodb_stats_persistent_save; +set global innodb_stats_persistent_sample_pages= + @innodb_stats_persistent_sample_pages_save; set optimizer_switch=@save_optimizer_switch_for_stat_tables_test; diff --git a/mysql-test/main/subselect.result b/mysql-test/main/subselect.result index 404d878a9ec..6f9fd458892 100644 --- a/mysql-test/main/subselect.result +++ b/mysql-test/main/subselect.result @@ -3103,13 +3103,17 @@ create table t1(a int, primary key (a)); insert into t1 values (10); create table t2 (a int primary key, b varchar(32), c int, unique key b(c, b)); insert into t2(a, c, b) values (1,10,'359'), (2,10,'35988'), (3,10,'35989'); +insert into t2(a, c, b) values (4,10,'360'), (5,10,'35998'), (6,10,'35999'); +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system PRIMARY NULL NULL NULL 1 1 PRIMARY r const PRIMARY PRIMARY 4 const 1 -2 SUBQUERY t2 range b b 40 NULL 2 Using where +2 SUBQUERY t2 range b b 40 NULL 3 Using where SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10; @@ -3121,7 +3125,7 @@ ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system PRIMARY NULL NULL NULL 1 1 PRIMARY r const PRIMARY PRIMARY 4 const 1 -2 SUBQUERY t2 range b b 40 NULL 2 Using index condition +2 SUBQUERY t2 range b b 40 NULL 3 Using index condition SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10; @@ -3708,7 +3712,7 @@ ORDER BY t1.t DESC LIMIT 1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 system NULL NULL NULL NULL 1 1 PRIMARY t1 index NULL PRIMARY 13 NULL 11 Using where; Using index -2 SUBQUERY t1 range PRIMARY PRIMARY 13 NULL 5 Using where; Using index +2 SUBQUERY t1 range PRIMARY PRIMARY 13 NULL 6 Using where; Using index SELECT * FROM t1,t2 WHERE t1.t = (SELECT t1.t FROM t1 WHERE t1.t < t2.t AND t1.i2=1 AND t2.i1=t1.i1 @@ -4977,7 +4981,7 @@ UNIQUE KEY b (b,c), KEY c (c), KEY b_2 (b) ); -INSERT INTO t3 VALUES (1,1,1), (2,32,1); +INSERT INTO t3 VALUES (1,1,1), (2,32,1), (3,33,1), (4,34,2); explain SELECT t1.a, (SELECT 1 FROM t2 WHERE t2.b=t3.c AND t2.c=t1.a ORDER BY t2.d LIMIT 1) AS incorrect FROM t1, t3 WHERE t3.b=t1.a; id select_type table type possible_keys key key_len ref rows Extra diff --git a/mysql-test/main/subselect.test b/mysql-test/main/subselect.test index d7c266cafb0..dd80b789516 100644 --- a/mysql-test/main/subselect.test +++ b/mysql-test/main/subselect.test @@ -2026,6 +2026,8 @@ insert into t1 values (10); create table t2 (a int primary key, b varchar(32), c int, unique key b(c, b)); insert into t2(a, c, b) values (1,10,'359'), (2,10,'35988'), (3,10,'35989'); +insert into t2(a, c, b) values (4,10,'360'), (5,10,'35998'), (6,10,'35999'); +analyze table t1; explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' @@ -3878,7 +3880,7 @@ CREATE TABLE t3 ( KEY b_2 (b) ); -INSERT INTO t3 VALUES (1,1,1), (2,32,1); +INSERT INTO t3 VALUES (1,1,1), (2,32,1), (3,33,1), (4,34,2); explain SELECT t1.a, (SELECT 1 FROM t2 WHERE t2.b=t3.c AND t2.c=t1.a ORDER BY t2.d LIMIT 1) AS incorrect FROM t1, t3 WHERE t3.b=t1.a; diff --git a/mysql-test/main/subselect2.result b/mysql-test/main/subselect2.result index 31e7774734e..76208429184 100644 --- a/mysql-test/main/subselect2.result +++ b/mysql-test/main/subselect2.result @@ -286,8 +286,8 @@ WHERE date < '2012-12-12 12:12:12' ORDER BY mirror_date ASC ) AS calculated_result; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 -2 DERIVED t1 range date date 6 NULL 2 Using index condition; Using where; Rowid-ordered scan; Using filesort +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3 +2 DERIVED t1 ALL date NULL NULL NULL 3 Using where; Using filesort SELECT * FROM ( SELECT node_uid, date, mirror_date, @result := 0 AS result FROM t1 @@ -309,8 +309,8 @@ WHERE date < '2012-12-12 12:12:12' ORDER BY mirror_date ASC ) AS calculated_result; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 -2 DERIVED t1 range date date 6 NULL 2 Using index condition; Using where; Using filesort +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3 +2 DERIVED t1 ALL date NULL NULL NULL 3 Using where; Using filesort SELECT * FROM ( SELECT node_uid, date, mirror_date, @result := 0 AS result FROM t1 diff --git a/mysql-test/main/subselect_mat.result b/mysql-test/main/subselect_mat.result index 010ba03153b..4592b1d5f70 100644 --- a/mysql-test/main/subselect_mat.result +++ b/mysql-test/main/subselect_mat.result @@ -39,6 +39,14 @@ create index it3i3 on t3i (c1, c2); insert into t1i select * from t1; insert into t2i select * from t2; insert into t3i select * from t3; +analyze table t1,t2,t3,t1i,t2i,t3i; +Table Op Msg_type Msg_text +test.t1 analyze status OK +test.t2 analyze status OK +test.t3 analyze status OK +test.t1i analyze status Table is already up to date +test.t2i analyze status Table is already up to date +test.t3i analyze status Table is already up to date set @@optimizer_switch='materialization=on,in_to_exists=off,firstmatch=off'; /****************************************************************************** * Simple tests. @@ -143,27 +151,44 @@ select * from t1i where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' a1 a2 1 - 01 2 - 01 1 - 02 2 - 02 +create table t2i_c like t2i; +insert into t2i_c select * from t2i; +insert into t2i_c select * from t2i; +insert into t2i_c select * from t2i; +insert into t2i_c select * from t2i; +analyze table t2i_c; +Table Op Msg_type Msg_text +test.t2i_c analyze status OK +show create table t2i_c; +Table Create Table +t2i_c CREATE TABLE `t2i_c` ( + `b1` char(8) DEFAULT NULL, + `b2` char(8) DEFAULT NULL, + KEY `it2i1` (`b1`), + KEY `it2i2` (`b2`), + KEY `it2i3` (`b1`,`b2`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 explain extended -select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1); +select * from t1 where (a1, a2) in (select b1, max(b2) from t2i_c group by b1); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where -2 MATERIALIZED t2i range NULL it2i3 9 NULL 3 100.00 Using index for group-by +2 MATERIALIZED t2i_c range NULL it2i3 9 NULL 3 100.00 Using index for group-by Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (/* select#2 */ select `test`.`t2i`.`b1`,max(`test`.`t2i`.`b2`) from `test`.`t2i` group by `test`.`t2i`.`b1` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where `test`.`t1`.`a1` = `<subquery2>`.`b1` and `test`.`t1`.`a2` = `<subquery2>`.`max(b2)`)))) -select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1); +Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (/* select#2 */ select `test`.`t2i_c`.`b1`,max(`test`.`t2i_c`.`b2`) from `test`.`t2i_c` group by `test`.`t2i_c`.`b1` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where `test`.`t1`.`a1` = `<subquery2>`.`b1` and `test`.`t1`.`a2` = `<subquery2>`.`max(b2)`)))) +select * from t1 where (a1, a2) in (select b1, max(b2) from t2i_c group by b1); a1 a2 1 - 01 2 - 01 1 - 02 2 - 02 -prepare st1 from "explain select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1)"; +prepare st1 from "explain select * from t1 where (a1, a2) in (select b1, max(b2) from t2i_c group by b1)"; execute st1; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where -2 MATERIALIZED t2i range NULL it2i3 9 NULL 3 Using index for group-by +2 MATERIALIZED t2i_c range NULL it2i3 9 NULL 3 Using index for group-by execute st1; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where -2 MATERIALIZED t2i range NULL it2i3 9 NULL 3 Using index for group-by -prepare st2 from "select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1)"; +2 MATERIALIZED t2i_c range NULL it2i3 9 NULL 3 Using index for group-by +prepare st2 from "select * from t1 where (a1, a2) in (select b1, max(b2) from t2i_c group by b1)"; execute st2; a1 a2 1 - 01 2 - 01 @@ -172,6 +197,7 @@ execute st2; a1 a2 1 - 01 2 - 01 1 - 02 2 - 02 +drop table t2i_c; explain extended select * from t1 where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1); id select_type table type possible_keys key key_len ref rows filtered Extra diff --git a/mysql-test/main/subselect_mat_cost.result b/mysql-test/main/subselect_mat_cost.result index daf8d18534c..5acf8cbee37 100644 --- a/mysql-test/main/subselect_mat_cost.result +++ b/mysql-test/main/subselect_mat_cost.result @@ -248,7 +248,7 @@ WHERE Code NOT IN (SELECT Country FROM CountryLanguage WHERE Language = 'English AND CountryLanguage.Language = 'French' AND Code = Country; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY CountryLanguage ref PRIMARY,Language Language 30 const 20 Using index condition +1 PRIMARY CountryLanguage ref PRIMARY,Language Language 30 const 19 Using index condition 1 PRIMARY Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where 2 DEPENDENT SUBQUERY CountryLanguage unique_subquery PRIMARY,Language PRIMARY 33 func,const 1 Using index; Using where SELECT Country.Name @@ -280,6 +280,7 @@ Q2.2m: Countries that speak French OR Spanish, but do not speak English MATERIALIZATION because the outer query filters less rows than Q5-a, so there are more lookups. +set statement optimizer_switch='rowid_filter=off' for EXPLAIN SELECT Country.Name FROM Country, CountryLanguage @@ -287,9 +288,10 @@ WHERE Code NOT IN (SELECT Country FROM CountryLanguage WHERE Language = 'English AND (CountryLanguage.Language = 'French' OR CountryLanguage.Language = 'Spanish') AND Code = Country; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY CountryLanguage range PRIMARY,Language Language 30 NULL 45 Using index condition; Using where; Rowid-ordered scan +1 PRIMARY CountryLanguage range PRIMARY,Language Language 30 NULL 44 Using index condition; Using where; Rowid-ordered scan 1 PRIMARY Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where -2 MATERIALIZED CountryLanguage ref PRIMARY,Language Language 30 const 47 Using index condition +3 MATERIALIZED CountryLanguage ref PRIMARY,Language Language 30 const 48 Using index condition +set statement optimizer_switch='rowid_filter=off' for SELECT Country.Name FROM Country, CountryLanguage WHERE Code NOT IN (SELECT Country FROM CountryLanguage WHERE Language = 'English') @@ -349,7 +351,7 @@ where (Language, Country) NOT IN FROM City LEFT JOIN Country ON (Country = Code and City.Population < 10000)) AND Language IN ('English','Spanish'); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY CountryLanguage range Language Language 30 NULL 72 Using index condition; Using where; Rowid-ordered scan +1 PRIMARY CountryLanguage range Language Language 30 NULL 73 Using index condition; Using where; Rowid-ordered scan 2 DEPENDENT SUBQUERY City ref CityName CityName 35 func 1 Using index condition 2 DEPENDENT SUBQUERY Country eq_ref PRIMARY PRIMARY 3 world.City.Country 1 Using where; Using index select count(*) @@ -481,7 +483,7 @@ select Name, City.id in (select capital from Country where capital is not null) from City where City.population > 10000000; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY City range Population Population 5 NULL 4 Using index condition; Rowid-ordered scan +1 PRIMARY City range Population Population 5 NULL 3 Using index condition; Rowid-ordered scan 2 MATERIALIZED Country ALL NULL NULL NULL NULL 239 Using where select Name, City.id in (select capital from Country where capital is not null) as is_capital from City @@ -497,7 +499,7 @@ select Name, City.id in (select capital from Country where capital is not null) from City where City.population > 10000000; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY City range Population Population 5 NULL 4 Using index condition; Rowid-ordered scan +1 PRIMARY City range Population Population 5 NULL 3 Using index condition; Rowid-ordered scan 2 SUBQUERY Country index_subquery CountryCapital CountryCapital 5 func 2 Using index; Using where select Name, City.id in (select capital from Country where capital is not null) as is_capital from City diff --git a/mysql-test/main/subselect_mat_cost.test b/mysql-test/main/subselect_mat_cost.test index 5a1fb550ca4..5f44d0d2bf4 100644 --- a/mysql-test/main/subselect_mat_cost.test +++ b/mysql-test/main/subselect_mat_cost.test @@ -205,6 +205,9 @@ WHERE Code NOT IN (SELECT Country FROM CountryLanguage WHERE Language = 'English -- echo Countries that speak French OR Spanish, but do not speak English -- echo MATERIALIZATION because the outer query filters less rows than Q5-a, -- echo so there are more lookups. + + +set statement optimizer_switch='rowid_filter=off' for EXPLAIN SELECT Country.Name FROM Country, CountryLanguage @@ -212,6 +215,7 @@ WHERE Code NOT IN (SELECT Country FROM CountryLanguage WHERE Language = 'English AND (CountryLanguage.Language = 'French' OR CountryLanguage.Language = 'Spanish') AND Code = Country; +set statement optimizer_switch='rowid_filter=off' for SELECT Country.Name FROM Country, CountryLanguage WHERE Code NOT IN (SELECT Country FROM CountryLanguage WHERE Language = 'English') diff --git a/mysql-test/main/subselect_no_exists_to_in.result b/mysql-test/main/subselect_no_exists_to_in.result index 6463aa4e4e2..8b1438db530 100644 --- a/mysql-test/main/subselect_no_exists_to_in.result +++ b/mysql-test/main/subselect_no_exists_to_in.result @@ -3106,13 +3106,17 @@ create table t1(a int, primary key (a)); insert into t1 values (10); create table t2 (a int primary key, b varchar(32), c int, unique key b(c, b)); insert into t2(a, c, b) values (1,10,'359'), (2,10,'35988'), (3,10,'35989'); +insert into t2(a, c, b) values (4,10,'360'), (5,10,'35998'), (6,10,'35999'); +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system PRIMARY NULL NULL NULL 1 1 PRIMARY r const PRIMARY PRIMARY 4 const 1 -2 SUBQUERY t2 range b b 40 NULL 2 Using where +2 SUBQUERY t2 range b b 40 NULL 3 Using where SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10; @@ -3124,7 +3128,7 @@ ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system PRIMARY NULL NULL NULL 1 1 PRIMARY r const PRIMARY PRIMARY 4 const 1 -2 SUBQUERY t2 range b b 40 NULL 2 Using index condition +2 SUBQUERY t2 range b b 40 NULL 3 Using index condition SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10; @@ -3711,7 +3715,7 @@ ORDER BY t1.t DESC LIMIT 1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 system NULL NULL NULL NULL 1 1 PRIMARY t1 index NULL PRIMARY 13 NULL 11 Using where; Using index -2 SUBQUERY t1 range PRIMARY PRIMARY 13 NULL 5 Using where; Using index +2 SUBQUERY t1 range PRIMARY PRIMARY 13 NULL 6 Using where; Using index SELECT * FROM t1,t2 WHERE t1.t = (SELECT t1.t FROM t1 WHERE t1.t < t2.t AND t1.i2=1 AND t2.i1=t1.i1 @@ -4979,7 +4983,7 @@ UNIQUE KEY b (b,c), KEY c (c), KEY b_2 (b) ); -INSERT INTO t3 VALUES (1,1,1), (2,32,1); +INSERT INTO t3 VALUES (1,1,1), (2,32,1), (3,33,1), (4,34,2); explain SELECT t1.a, (SELECT 1 FROM t2 WHERE t2.b=t3.c AND t2.c=t1.a ORDER BY t2.d LIMIT 1) AS incorrect FROM t1, t3 WHERE t3.b=t1.a; id select_type table type possible_keys key key_len ref rows Extra diff --git a/mysql-test/main/subselect_no_mat.result b/mysql-test/main/subselect_no_mat.result index 0fa338ef222..979b1ab5d47 100644 --- a/mysql-test/main/subselect_no_mat.result +++ b/mysql-test/main/subselect_no_mat.result @@ -3108,13 +3108,17 @@ create table t1(a int, primary key (a)); insert into t1 values (10); create table t2 (a int primary key, b varchar(32), c int, unique key b(c, b)); insert into t2(a, c, b) values (1,10,'359'), (2,10,'35988'), (3,10,'35989'); +insert into t2(a, c, b) values (4,10,'360'), (5,10,'35998'), (6,10,'35999'); +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system PRIMARY NULL NULL NULL 1 1 PRIMARY r const PRIMARY PRIMARY 4 const 1 -2 SUBQUERY t2 range b b 40 NULL 2 Using where +2 SUBQUERY t2 range b b 40 NULL 3 Using where SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10; @@ -3126,7 +3130,7 @@ ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system PRIMARY NULL NULL NULL 1 1 PRIMARY r const PRIMARY PRIMARY 4 const 1 -2 SUBQUERY t2 range b b 40 NULL 2 Using index condition +2 SUBQUERY t2 range b b 40 NULL 3 Using index condition SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10; @@ -3711,7 +3715,7 @@ ORDER BY t1.t DESC LIMIT 1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 system NULL NULL NULL NULL 1 1 PRIMARY t1 index NULL PRIMARY 13 NULL 11 Using where; Using index -2 SUBQUERY t1 range PRIMARY PRIMARY 13 NULL 5 Using where; Using index +2 SUBQUERY t1 range PRIMARY PRIMARY 13 NULL 6 Using where; Using index SELECT * FROM t1,t2 WHERE t1.t = (SELECT t1.t FROM t1 WHERE t1.t < t2.t AND t1.i2=1 AND t2.i1=t1.i1 @@ -4977,7 +4981,7 @@ UNIQUE KEY b (b,c), KEY c (c), KEY b_2 (b) ); -INSERT INTO t3 VALUES (1,1,1), (2,32,1); +INSERT INTO t3 VALUES (1,1,1), (2,32,1), (3,33,1), (4,34,2); explain SELECT t1.a, (SELECT 1 FROM t2 WHERE t2.b=t3.c AND t2.c=t1.a ORDER BY t2.d LIMIT 1) AS incorrect FROM t1, t3 WHERE t3.b=t1.a; id select_type table type possible_keys key key_len ref rows Extra diff --git a/mysql-test/main/subselect_no_opts.result b/mysql-test/main/subselect_no_opts.result index 7704667a2dc..a43c4f031cf 100644 --- a/mysql-test/main/subselect_no_opts.result +++ b/mysql-test/main/subselect_no_opts.result @@ -3104,13 +3104,17 @@ create table t1(a int, primary key (a)); insert into t1 values (10); create table t2 (a int primary key, b varchar(32), c int, unique key b(c, b)); insert into t2(a, c, b) values (1,10,'359'), (2,10,'35988'), (3,10,'35989'); +insert into t2(a, c, b) values (4,10,'360'), (5,10,'35998'), (6,10,'35999'); +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system PRIMARY NULL NULL NULL 1 1 PRIMARY r const PRIMARY PRIMARY 4 const 1 -2 SUBQUERY t2 range b b 40 NULL 2 Using where +2 SUBQUERY t2 range b b 40 NULL 3 Using where SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10; @@ -3122,7 +3126,7 @@ ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system PRIMARY NULL NULL NULL 1 1 PRIMARY r const PRIMARY PRIMARY 4 const 1 -2 SUBQUERY t2 range b b 40 NULL 2 Using index condition +2 SUBQUERY t2 range b b 40 NULL 3 Using index condition SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10; @@ -3707,7 +3711,7 @@ ORDER BY t1.t DESC LIMIT 1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 system NULL NULL NULL NULL 1 1 PRIMARY t1 index NULL PRIMARY 13 NULL 11 Using where; Using index -2 SUBQUERY t1 range PRIMARY PRIMARY 13 NULL 5 Using where; Using index +2 SUBQUERY t1 range PRIMARY PRIMARY 13 NULL 6 Using where; Using index SELECT * FROM t1,t2 WHERE t1.t = (SELECT t1.t FROM t1 WHERE t1.t < t2.t AND t1.i2=1 AND t2.i1=t1.i1 @@ -4973,7 +4977,7 @@ UNIQUE KEY b (b,c), KEY c (c), KEY b_2 (b) ); -INSERT INTO t3 VALUES (1,1,1), (2,32,1); +INSERT INTO t3 VALUES (1,1,1), (2,32,1), (3,33,1), (4,34,2); explain SELECT t1.a, (SELECT 1 FROM t2 WHERE t2.b=t3.c AND t2.c=t1.a ORDER BY t2.d LIMIT 1) AS incorrect FROM t1, t3 WHERE t3.b=t1.a; id select_type table type possible_keys key key_len ref rows Extra diff --git a/mysql-test/main/subselect_no_scache.result b/mysql-test/main/subselect_no_scache.result index af1157321e2..f016f5e6b3c 100644 --- a/mysql-test/main/subselect_no_scache.result +++ b/mysql-test/main/subselect_no_scache.result @@ -3109,13 +3109,17 @@ create table t1(a int, primary key (a)); insert into t1 values (10); create table t2 (a int primary key, b varchar(32), c int, unique key b(c, b)); insert into t2(a, c, b) values (1,10,'359'), (2,10,'35988'), (3,10,'35989'); +insert into t2(a, c, b) values (4,10,'360'), (5,10,'35998'), (6,10,'35999'); +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system PRIMARY NULL NULL NULL 1 1 PRIMARY r const PRIMARY PRIMARY 4 const 1 -2 SUBQUERY t2 range b b 40 NULL 2 Using where +2 SUBQUERY t2 range b b 40 NULL 3 Using where SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10; @@ -3127,7 +3131,7 @@ ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system PRIMARY NULL NULL NULL 1 1 PRIMARY r const PRIMARY PRIMARY 4 const 1 -2 SUBQUERY t2 range b b 40 NULL 2 Using index condition +2 SUBQUERY t2 range b b 40 NULL 3 Using index condition SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10; @@ -3714,7 +3718,7 @@ ORDER BY t1.t DESC LIMIT 1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 system NULL NULL NULL NULL 1 1 PRIMARY t1 index NULL PRIMARY 13 NULL 11 Using where; Using index -2 SUBQUERY t1 range PRIMARY PRIMARY 13 NULL 5 Using where; Using index +2 SUBQUERY t1 range PRIMARY PRIMARY 13 NULL 6 Using where; Using index SELECT * FROM t1,t2 WHERE t1.t = (SELECT t1.t FROM t1 WHERE t1.t < t2.t AND t1.i2=1 AND t2.i1=t1.i1 @@ -4983,7 +4987,7 @@ UNIQUE KEY b (b,c), KEY c (c), KEY b_2 (b) ); -INSERT INTO t3 VALUES (1,1,1), (2,32,1); +INSERT INTO t3 VALUES (1,1,1), (2,32,1), (3,33,1), (4,34,2); explain SELECT t1.a, (SELECT 1 FROM t2 WHERE t2.b=t3.c AND t2.c=t1.a ORDER BY t2.d LIMIT 1) AS incorrect FROM t1, t3 WHERE t3.b=t1.a; id select_type table type possible_keys key key_len ref rows Extra diff --git a/mysql-test/main/subselect_no_semijoin.result b/mysql-test/main/subselect_no_semijoin.result index 13f4cb8b2b5..8e348100cb4 100644 --- a/mysql-test/main/subselect_no_semijoin.result +++ b/mysql-test/main/subselect_no_semijoin.result @@ -3104,13 +3104,17 @@ create table t1(a int, primary key (a)); insert into t1 values (10); create table t2 (a int primary key, b varchar(32), c int, unique key b(c, b)); insert into t2(a, c, b) values (1,10,'359'), (2,10,'35988'), (3,10,'35989'); +insert into t2(a, c, b) values (4,10,'360'), (5,10,'35998'), (6,10,'35999'); +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system PRIMARY NULL NULL NULL 1 1 PRIMARY r const PRIMARY PRIMARY 4 const 1 -2 SUBQUERY t2 range b b 40 NULL 2 Using where +2 SUBQUERY t2 range b b 40 NULL 3 Using where SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10; @@ -3122,7 +3126,7 @@ ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system PRIMARY NULL NULL NULL 1 1 PRIMARY r const PRIMARY PRIMARY 4 const 1 -2 SUBQUERY t2 range b b 40 NULL 2 Using index condition +2 SUBQUERY t2 range b b 40 NULL 3 Using index condition SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10; @@ -3707,7 +3711,7 @@ ORDER BY t1.t DESC LIMIT 1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 system NULL NULL NULL NULL 1 1 PRIMARY t1 index NULL PRIMARY 13 NULL 11 Using where; Using index -2 SUBQUERY t1 range PRIMARY PRIMARY 13 NULL 5 Using where; Using index +2 SUBQUERY t1 range PRIMARY PRIMARY 13 NULL 6 Using where; Using index SELECT * FROM t1,t2 WHERE t1.t = (SELECT t1.t FROM t1 WHERE t1.t < t2.t AND t1.i2=1 AND t2.i1=t1.i1 @@ -4973,7 +4977,7 @@ UNIQUE KEY b (b,c), KEY c (c), KEY b_2 (b) ); -INSERT INTO t3 VALUES (1,1,1), (2,32,1); +INSERT INTO t3 VALUES (1,1,1), (2,32,1), (3,33,1), (4,34,2); explain SELECT t1.a, (SELECT 1 FROM t2 WHERE t2.b=t3.c AND t2.c=t1.a ORDER BY t2.d LIMIT 1) AS incorrect FROM t1, t3 WHERE t3.b=t1.a; id select_type table type possible_keys key key_len ref rows Extra diff --git a/mysql-test/main/subselect_sj.result b/mysql-test/main/subselect_sj.result index c12bad5affa..03de4072815 100644 --- a/mysql-test/main/subselect_sj.result +++ b/mysql-test/main/subselect_sj.result @@ -204,7 +204,7 @@ a b a b insert into t1 select (A.a + 10 * B.a),1 from t0 A, t0 B; explain extended select * from t1 where a in (select pk from t10 where pk<3); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t10 range PRIMARY PRIMARY 4 NULL 4 100.00 Using where; Using index +1 PRIMARY t10 range PRIMARY PRIMARY 4 NULL 3 100.00 Using where; Using index 1 PRIMARY t1 ALL NULL NULL NULL NULL 103 100.00 Using where; Using join buffer (flat, BNL join) Warnings: Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t10` join `test`.`t1` where `test`.`t1`.`a` = `test`.`t10`.`pk` and `test`.`t10`.`pk` < 3 @@ -729,7 +729,7 @@ SELECT int_key FROM ot1 WHERE int_nokey IN (SELECT it2.int_key FROM it1 LEFT JOIN it2 ON it2.datetime_key); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 11 +1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 10 1 PRIMARY ot1 ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) 2 MATERIALIZED it1 index NULL int_key 4 NULL 2 Using index 2 MATERIALIZED it2 ALL int_key,datetime_key NULL NULL NULL 20 Using where @@ -3079,9 +3079,11 @@ set optimizer_switch= @tmp_mdev6859; set @tmp_mdev12675=@@optimizer_switch; set optimizer_switch=default; create table t1 (a int) engine=myisam; -insert into t1 values (5),(3),(2),(7),(2),(5),(1); +insert into t1 values (3),(2),(7),(2),(1); create table t2 (b int, index idx(b)) engine=myisam; -insert into t2 values (2),(3),(2),(1),(3),(4); +insert into t2 values (2),(3),(2),(1),(3),(4),(1),(2),(1),(2); +insert into t2 select b+10 from t2; +insert into t2 select b+10 from t2; insert into t2 select b+10 from t2; insert into t2 select b+10 from t2; insert into t2 select b+10 from t2; @@ -3100,15 +3102,15 @@ test.t2 analyze status OK explain select a from t1, t2 where b between 1 and 2 and a in (select b from t2); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 7 Using where -1 PRIMARY t2 ref idx idx 5 test.t1.a 256 Using index; FirstMatch(t1) -1 PRIMARY t2 range idx idx 5 NULL 2 Using where; Using index; Using join buffer (flat, BNL join) +1 PRIMARY t1 ALL NULL NULL NULL NULL 5 Using where +1 PRIMARY t2 ref idx idx 5 test.t1.a 1463 Using index; FirstMatch(t1) +1 PRIMARY t2 range idx idx 5 NULL 5 Using where; Using index; Using join buffer (flat, BNL join) explain select a from t1 join t2 on b between 1 and 2 and a in (select b from t2); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 7 Using where -1 PRIMARY t2 ref idx idx 5 test.t1.a 256 Using index; FirstMatch(t1) -1 PRIMARY t2 range idx idx 5 NULL 2 Using where; Using index; Using join buffer (flat, BNL join) +1 PRIMARY t1 ALL NULL NULL NULL NULL 5 Using where +1 PRIMARY t2 ref idx idx 5 test.t1.a 1463 Using index; FirstMatch(t1) +1 PRIMARY t2 range idx idx 5 NULL 5 Using where; Using index; Using join buffer (flat, BNL join) drop table t1,t2; set optimizer_switch= @tmp_mdev12675; # diff --git a/mysql-test/main/subselect_sj.test b/mysql-test/main/subselect_sj.test index 962a69c10c1..1df143738b5 100644 --- a/mysql-test/main/subselect_sj.test +++ b/mysql-test/main/subselect_sj.test @@ -2782,9 +2782,11 @@ set optimizer_switch= @tmp_mdev6859; set @tmp_mdev12675=@@optimizer_switch; set optimizer_switch=default; create table t1 (a int) engine=myisam; -insert into t1 values (5),(3),(2),(7),(2),(5),(1); +insert into t1 values (3),(2),(7),(2),(1); create table t2 (b int, index idx(b)) engine=myisam; -insert into t2 values (2),(3),(2),(1),(3),(4); +insert into t2 values (2),(3),(2),(1),(3),(4),(1),(2),(1),(2); +insert into t2 select b+10 from t2; +insert into t2 select b+10 from t2; insert into t2 select b+10 from t2; insert into t2 select b+10 from t2; insert into t2 select b+10 from t2; diff --git a/mysql-test/main/subselect_sj2.result b/mysql-test/main/subselect_sj2.result index 948be5766a2..e5ed30cb259 100644 --- a/mysql-test/main/subselect_sj2.result +++ b/mysql-test/main/subselect_sj2.result @@ -1,3 +1,8 @@ +set @innodb_stats_persistent_save= @@innodb_stats_persistent; +set @innodb_stats_persistent_sample_pages_save= +@@innodb_stats_persistent_sample_pages; +set global innodb_stats_persistent= 1; +set global innodb_stats_persistent_sample_pages=100; set @subselect_sj2_tmp= @@optimizer_switch; set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on'; set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; @@ -67,6 +72,11 @@ primary key(pk1, pk2, pk3) ) engine=innodb; insert into t3 select a,a, a,a,a from t0; insert into t3 select a,a, a+100,a+100,a+100 from t0; +analyze table t1,t2,t3; +Table Op Msg_type Msg_text +test.t1 analyze status OK +test.t2 analyze status OK +test.t3 analyze status OK explain select * from t3 where b in (select a from t1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 ALL b NULL NULL NULL 20 @@ -119,7 +129,7 @@ set max_heap_table_size= @save_max_heap_table_size; explain select * from t1 where a in (select b from t2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where -1 PRIMARY t2 ref b b 5 test.t1.a 2 Using index; FirstMatch(t1) +1 PRIMARY t2 ref b b 5 test.t1.a 1 Using index; FirstMatch(t1) select * from t1; a b 1 1 @@ -717,9 +727,8 @@ alter table t3 add primary key(id), add key(a); The following must use loose index scan over t3, key a: explain select count(a) from t2 where a in ( SELECT a FROM t3); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t2 index a a 5 NULL 1000 Using index -1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t3 index a a 5 NULL 30000 Using index +1 PRIMARY t2 index a a 5 NULL 1000 Using where; Using index +1 PRIMARY t3 ref a a 5 test.t2.a 30 Using index; FirstMatch(t2) select count(a) from t2 where a in ( SELECT a FROM t3); count(a) 1000 @@ -922,6 +931,10 @@ INSERT INTO t2 VALUES (6,'u',6),(7,'m',7),(8,'k',8),(9,'o',9),(10,'w',1), (11,'m',2),(12,'q',3),(13,'m',4),(14,'d',5), (15,'g',6),(16,'x',7),(17,'f',8); +analyze table t1,t2; +Table Op Msg_type Msg_text +test.t1 analyze status OK +test.t2 analyze status OK explain SELECT * FROM t1 WHERE b IN ( SELECT d FROM t2, t1 @@ -953,6 +966,9 @@ INSERT INTO t1 VALUES ('y','y'),('t','t'),('d','d'),('s','s'),('r','r'), ('m','m'),('b','b'),('x','x'),('g','g'),('p','p'), ('q','q'),('w','w'),('d','d'),('e','e'); +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1; # This query returned 6 rows instead of 19 SELECT * FROM v1 @@ -986,6 +1002,9 @@ y y CREATE TABLE t2 (a VARCHAR(1), b VARCHAR(1) NOT NULL, KEY(a)) ENGINE=InnoDB; INSERT INTO t2 SELECT * FROM t1; INSERT INTO t2 SELECT * FROM t1; +ANALYZE TABLE t2; +Table Op Msg_type Msg_text +test.t2 analyze status OK EXPLAIN SELECT * FROM t2 WHERE (a, a) IN (SELECT alias2.b, alias2.a FROM t1 AS alias1, t1 AS alias2 @@ -1081,11 +1100,11 @@ WHERE alias5.b = alias4.b AND ( alias5.b >= alias3.b OR alias5.c != alias3.c ) ); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY alias3 ALL PRIMARY NULL NULL NULL 19 Using where -1 PRIMARY alias4 ref PRIMARY,c c 4 test.alias3.d 1 Using index -1 PRIMARY alias5 eq_ref PRIMARY PRIMARY 4 test.alias4.b 1 Using where; FirstMatch(alias3) -1 PRIMARY alias2 ALL NULL NULL NULL NULL 14 Using join buffer (flat, BNL join) +1 PRIMARY alias3 ALL PRIMARY NULL NULL NULL 19 +1 PRIMARY alias5 index PRIMARY c 4 NULL 19 Using where; Using index +1 PRIMARY alias4 eq_ref PRIMARY,c PRIMARY 4 test.alias5.b 1 Using where; FirstMatch(alias3) 1 PRIMARY alias1 ALL NULL NULL NULL NULL 14 Using join buffer (flat, BNL join) +1 PRIMARY alias2 ALL NULL NULL NULL NULL 14 Using join buffer (flat, BNL join) SELECT COUNT(*) FROM t1 AS alias1, t1 AS alias2, t2 AS alias3 WHERE alias3.d IN ( SELECT alias4.c FROM t2 AS alias4, t2 AS alias5 @@ -1102,11 +1121,11 @@ WHERE alias5.b = alias4.b AND ( alias5.b >= alias3.b OR alias3.c != alias5.c ) ); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY alias3 ALL PRIMARY NULL NULL NULL 19 Using where -1 PRIMARY alias4 ref PRIMARY,c c 4 test.alias3.d 1 Using index -1 PRIMARY alias5 eq_ref PRIMARY PRIMARY 4 test.alias4.b 1 Using where; FirstMatch(alias3) -1 PRIMARY alias2 ALL NULL NULL NULL NULL 14 Using join buffer (flat, BNL join) +1 PRIMARY alias3 ALL PRIMARY NULL NULL NULL 19 +1 PRIMARY alias5 index PRIMARY c 4 NULL 19 Using where; Using index +1 PRIMARY alias4 eq_ref PRIMARY,c PRIMARY 4 test.alias5.b 1 Using where; FirstMatch(alias3) 1 PRIMARY alias1 ALL NULL NULL NULL NULL 14 Using join buffer (flat, BNL join) +1 PRIMARY alias2 ALL NULL NULL NULL NULL 14 Using join buffer (flat, BNL join) SELECT COUNT(*) FROM t1 AS alias1, t1 AS alias2, t2 AS alias3 WHERE alias3.d IN ( SELECT alias4.c FROM t2 AS alias4, t2 AS alias5 @@ -1232,6 +1251,11 @@ INSERT IGNORE INTO t2 (t2id, t1idref) SELECT t1id, t1id FROM t1; INSERT IGNORE INTO t1 VALUES (200001, 'a'); INSERT IGNORE INTO t2 (t2id, t1idref) VALUES (200011, 200001),(200012, 200001),(200013, 200001); INSERT IGNORE INTO t3 VALUES (1, 200011, 1), (1, 200012, 2), (1, 200013, 3); +ANALYZE TABLE t1,t2,t3; +Table Op Msg_type Msg_text +test.t1 analyze status OK +test.t2 analyze status OK +test.t3 analyze status OK set @tmp7474= @@optimizer_search_depth; SET SESSION optimizer_search_depth = 1; SELECT SQL_NO_CACHE @@ -1332,4 +1356,7 @@ a pk b DROP TABLE t1,t2,t3; DROP VIEW v3; # This must be the last in the file: +set global innodb_stats_persistent= @innodb_stats_persistent_save; +set global innodb_stats_persistent_sample_pages= +@innodb_stats_persistent_sample_pages_save; set optimizer_switch=@subselect_sj2_tmp; diff --git a/mysql-test/main/subselect_sj2.test b/mysql-test/main/subselect_sj2.test index a948b086a85..9ed886da3ad 100644 --- a/mysql-test/main/subselect_sj2.test +++ b/mysql-test/main/subselect_sj2.test @@ -1,6 +1,13 @@ # # DuplicateElimination strategy test # + +set @innodb_stats_persistent_save= @@innodb_stats_persistent; +set @innodb_stats_persistent_sample_pages_save= + @@innodb_stats_persistent_sample_pages; + +set global innodb_stats_persistent= 1; +set global innodb_stats_persistent_sample_pages=100; --source include/have_innodb.inc set @subselect_sj2_tmp= @@optimizer_switch; @@ -57,6 +64,8 @@ create table t3 ( insert into t3 select a,a, a,a,a from t0; insert into t3 select a,a, a+100,a+100,a+100 from t0; +analyze table t1,t2,t3; + explain select * from t3 where b in (select a from t1); select * from t3 where b in (select a from t1); @@ -1113,6 +1122,8 @@ INSERT INTO t2 VALUES (11,'m',2),(12,'q',3),(13,'m',4),(14,'d',5), (15,'g',6),(16,'x',7),(17,'f',8); +analyze table t1,t2; + explain SELECT * FROM t1 WHERE b IN ( SELECT d FROM t2, t1 @@ -1139,6 +1150,8 @@ INSERT INTO t1 VALUES ('m','m'),('b','b'),('x','x'),('g','g'),('p','p'), ('q','q'),('w','w'),('d','d'),('e','e'); +ANALYZE TABLE t1; + CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1; --echo # This query returned 6 rows instead of 19 @@ -1155,6 +1168,9 @@ WHERE ( a, a ) IN ( CREATE TABLE t2 (a VARCHAR(1), b VARCHAR(1) NOT NULL, KEY(a)) ENGINE=InnoDB; INSERT INTO t2 SELECT * FROM t1; INSERT INTO t2 SELECT * FROM t1; + +ANALYZE TABLE t2; + EXPLAIN SELECT * FROM t2 WHERE (a, a) IN (SELECT alias2.b, alias2.a FROM t1 AS alias1, t1 AS alias2 @@ -1379,6 +1395,8 @@ INSERT IGNORE INTO t1 VALUES (200001, 'a'); INSERT IGNORE INTO t2 (t2id, t1idref) VALUES (200011, 200001),(200012, 200001),(200013, 200001); INSERT IGNORE INTO t3 VALUES (1, 200011, 1), (1, 200012, 2), (1, 200013, 3); +ANALYZE TABLE t1,t2,t3; + set @tmp7474= @@optimizer_search_depth; SET SESSION optimizer_search_depth = 1; @@ -1465,4 +1483,7 @@ DROP TABLE t1,t2,t3; DROP VIEW v3; --echo # This must be the last in the file: +set global innodb_stats_persistent= @innodb_stats_persistent_save; +set global innodb_stats_persistent_sample_pages= + @innodb_stats_persistent_sample_pages_save; set optimizer_switch=@subselect_sj2_tmp; diff --git a/mysql-test/main/subselect_sj2_jcl6.result b/mysql-test/main/subselect_sj2_jcl6.result index 2955307eb86..b930bdcb131 100644 --- a/mysql-test/main/subselect_sj2_jcl6.result +++ b/mysql-test/main/subselect_sj2_jcl6.result @@ -9,6 +9,11 @@ Variable_name Value join_cache_level 6 set @optimizer_switch_for_subselect_sj2_test=@@optimizer_switch; set @join_cache_level_for_subselect_sj2_test=@@join_cache_level; +set @innodb_stats_persistent_save= @@innodb_stats_persistent; +set @innodb_stats_persistent_sample_pages_save= +@@innodb_stats_persistent_sample_pages; +set global innodb_stats_persistent= 1; +set global innodb_stats_persistent_sample_pages=100; set @subselect_sj2_tmp= @@optimizer_switch; set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on'; set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; @@ -78,6 +83,11 @@ primary key(pk1, pk2, pk3) ) engine=innodb; insert into t3 select a,a, a,a,a from t0; insert into t3 select a,a, a+100,a+100,a+100 from t0; +analyze table t1,t2,t3; +Table Op Msg_type Msg_text +test.t1 analyze status OK +test.t2 analyze status OK +test.t3 analyze status OK explain select * from t3 where b in (select a from t1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 ALL b NULL NULL NULL 20 @@ -937,6 +947,10 @@ INSERT INTO t2 VALUES (6,'u',6),(7,'m',7),(8,'k',8),(9,'o',9),(10,'w',1), (11,'m',2),(12,'q',3),(13,'m',4),(14,'d',5), (15,'g',6),(16,'x',7),(17,'f',8); +analyze table t1,t2; +Table Op Msg_type Msg_text +test.t1 analyze status OK +test.t2 analyze status OK explain SELECT * FROM t1 WHERE b IN ( SELECT d FROM t2, t1 @@ -968,6 +982,9 @@ INSERT INTO t1 VALUES ('y','y'),('t','t'),('d','d'),('s','s'),('r','r'), ('m','m'),('b','b'),('x','x'),('g','g'),('p','p'), ('q','q'),('w','w'),('d','d'),('e','e'); +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1; # This query returned 6 rows instead of 19 SELECT * FROM v1 @@ -1001,6 +1018,9 @@ y y CREATE TABLE t2 (a VARCHAR(1), b VARCHAR(1) NOT NULL, KEY(a)) ENGINE=InnoDB; INSERT INTO t2 SELECT * FROM t1; INSERT INTO t2 SELECT * FROM t1; +ANALYZE TABLE t2; +Table Op Msg_type Msg_text +test.t2 analyze status OK EXPLAIN SELECT * FROM t2 WHERE (a, a) IN (SELECT alias2.b, alias2.a FROM t1 AS alias1, t1 AS alias2 @@ -1096,11 +1116,11 @@ WHERE alias5.b = alias4.b AND ( alias5.b >= alias3.b OR alias5.c != alias3.c ) ); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY alias3 ALL PRIMARY NULL NULL NULL 19 Using where -1 PRIMARY alias4 ref PRIMARY,c c 4 test.alias3.d 1 Using index -1 PRIMARY alias5 eq_ref PRIMARY PRIMARY 4 test.alias4.b 1 Using where; FirstMatch(alias3) -1 PRIMARY alias2 ALL NULL NULL NULL NULL 14 Using join buffer (flat, BNL join) +1 PRIMARY alias3 ALL PRIMARY NULL NULL NULL 19 +1 PRIMARY alias5 index PRIMARY c 4 NULL 19 Using where; Using index; Using join buffer (flat, BNL join) +1 PRIMARY alias4 eq_ref PRIMARY,c PRIMARY 4 test.alias5.b 1 Using where; FirstMatch(alias3); Using join buffer (incremental, BKA join); Key-ordered scan 1 PRIMARY alias1 ALL NULL NULL NULL NULL 14 Using join buffer (incremental, BNL join) +1 PRIMARY alias2 ALL NULL NULL NULL NULL 14 Using join buffer (incremental, BNL join) SELECT COUNT(*) FROM t1 AS alias1, t1 AS alias2, t2 AS alias3 WHERE alias3.d IN ( SELECT alias4.c FROM t2 AS alias4, t2 AS alias5 @@ -1117,11 +1137,11 @@ WHERE alias5.b = alias4.b AND ( alias5.b >= alias3.b OR alias3.c != alias5.c ) ); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY alias3 ALL PRIMARY NULL NULL NULL 19 Using where -1 PRIMARY alias4 ref PRIMARY,c c 4 test.alias3.d 1 Using index -1 PRIMARY alias5 eq_ref PRIMARY PRIMARY 4 test.alias4.b 1 Using where; FirstMatch(alias3) -1 PRIMARY alias2 ALL NULL NULL NULL NULL 14 Using join buffer (flat, BNL join) +1 PRIMARY alias3 ALL PRIMARY NULL NULL NULL 19 +1 PRIMARY alias5 index PRIMARY c 4 NULL 19 Using where; Using index; Using join buffer (flat, BNL join) +1 PRIMARY alias4 eq_ref PRIMARY,c PRIMARY 4 test.alias5.b 1 Using where; FirstMatch(alias3); Using join buffer (incremental, BKA join); Key-ordered scan 1 PRIMARY alias1 ALL NULL NULL NULL NULL 14 Using join buffer (incremental, BNL join) +1 PRIMARY alias2 ALL NULL NULL NULL NULL 14 Using join buffer (incremental, BNL join) SELECT COUNT(*) FROM t1 AS alias1, t1 AS alias2, t2 AS alias3 WHERE alias3.d IN ( SELECT alias4.c FROM t2 AS alias4, t2 AS alias5 @@ -1247,6 +1267,11 @@ INSERT IGNORE INTO t2 (t2id, t1idref) SELECT t1id, t1id FROM t1; INSERT IGNORE INTO t1 VALUES (200001, 'a'); INSERT IGNORE INTO t2 (t2id, t1idref) VALUES (200011, 200001),(200012, 200001),(200013, 200001); INSERT IGNORE INTO t3 VALUES (1, 200011, 1), (1, 200012, 2), (1, 200013, 3); +ANALYZE TABLE t1,t2,t3; +Table Op Msg_type Msg_text +test.t1 analyze status OK +test.t2 analyze status OK +test.t3 analyze status OK set @tmp7474= @@optimizer_search_depth; SET SESSION optimizer_search_depth = 1; SELECT SQL_NO_CACHE @@ -1347,7 +1372,15 @@ a pk b DROP TABLE t1,t2,t3; DROP VIEW v3; # This must be the last in the file: +set global innodb_stats_persistent= @innodb_stats_persistent_save; +set global innodb_stats_persistent_sample_pages= +@innodb_stats_persistent_sample_pages_save; set optimizer_switch=@subselect_sj2_tmp; +set @innodb_stats_persistent_save= @@innodb_stats_persistent; +set @innodb_stats_persistent_sample_pages_save= +@@innodb_stats_persistent_sample_pages; +set global innodb_stats_persistent= 1; +set global innodb_stats_persistent_sample_pages=100; # # Bug #898073: potential incremental join cache for semijoin # @@ -1440,6 +1473,9 @@ set join_cache_level=default; show variables like 'join_cache_level'; Variable_name Value join_cache_level 2 +set global innodb_stats_persistent= @innodb_stats_persistent_save; +set global innodb_stats_persistent_sample_pages= +@innodb_stats_persistent_sample_pages_save; set @@optimizer_switch=@save_optimizer_switch_jcl6; set @optimizer_switch_for_subselect_sj2_test=NULL; set @join_cache_level_subselect_sj2_test=NULL; diff --git a/mysql-test/main/subselect_sj2_jcl6.test b/mysql-test/main/subselect_sj2_jcl6.test index 7ff08716230..9be6102a5f9 100644 --- a/mysql-test/main/subselect_sj2_jcl6.test +++ b/mysql-test/main/subselect_sj2_jcl6.test @@ -16,6 +16,13 @@ set @join_cache_level_for_subselect_sj2_test=@@join_cache_level; --source subselect_sj2.test +set @innodb_stats_persistent_save= @@innodb_stats_persistent; +set @innodb_stats_persistent_sample_pages_save= + @@innodb_stats_persistent_sample_pages; + +set global innodb_stats_persistent= 1; +set global innodb_stats_persistent_sample_pages=100; + --echo # --echo # Bug #898073: potential incremental join cache for semijoin --echo # @@ -107,6 +114,10 @@ DROP TABLE t1,t2; set join_cache_level=default; show variables like 'join_cache_level'; +set global innodb_stats_persistent= @innodb_stats_persistent_save; +set global innodb_stats_persistent_sample_pages= + @innodb_stats_persistent_sample_pages_save; + set @@optimizer_switch=@save_optimizer_switch_jcl6; set @optimizer_switch_for_subselect_sj2_test=NULL; set @join_cache_level_subselect_sj2_test=NULL; diff --git a/mysql-test/main/subselect_sj2_mat.result b/mysql-test/main/subselect_sj2_mat.result index 884451d7dff..65dfddce34d 100644 --- a/mysql-test/main/subselect_sj2_mat.result +++ b/mysql-test/main/subselect_sj2_mat.result @@ -1,5 +1,10 @@ set optimizer_switch='materialization=on'; set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; +set @innodb_stats_persistent_save= @@innodb_stats_persistent; +set @innodb_stats_persistent_sample_pages_save= +@@innodb_stats_persistent_sample_pages; +set global innodb_stats_persistent= 1; +set global innodb_stats_persistent_sample_pages=100; set @subselect_sj2_tmp= @@optimizer_switch; set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on'; set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; @@ -69,6 +74,11 @@ primary key(pk1, pk2, pk3) ) engine=innodb; insert into t3 select a,a, a,a,a from t0; insert into t3 select a,a, a+100,a+100,a+100 from t0; +analyze table t1,t2,t3; +Table Op Msg_type Msg_text +test.t1 analyze status OK +test.t2 analyze status OK +test.t3 analyze status OK explain select * from t3 where b in (select a from t1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 ALL b NULL NULL NULL 20 @@ -121,7 +131,7 @@ set max_heap_table_size= @save_max_heap_table_size; explain select * from t1 where a in (select b from t2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where -1 PRIMARY t2 ref b b 5 test.t1.a 2 Using index; FirstMatch(t1) +1 PRIMARY t2 ref b b 5 test.t1.a 1 Using index; FirstMatch(t1) select * from t1; a b 1 1 @@ -719,9 +729,8 @@ alter table t3 add primary key(id), add key(a); The following must use loose index scan over t3, key a: explain select count(a) from t2 where a in ( SELECT a FROM t3); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t2 index a a 5 NULL 1000 Using index -1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t3 index a a 5 NULL 30000 Using index +1 PRIMARY t2 index a a 5 NULL 1000 Using where; Using index +1 PRIMARY t3 ref a a 5 test.t2.a 30 Using index; FirstMatch(t2) select count(a) from t2 where a in ( SELECT a FROM t3); count(a) 1000 @@ -924,6 +933,10 @@ INSERT INTO t2 VALUES (6,'u',6),(7,'m',7),(8,'k',8),(9,'o',9),(10,'w',1), (11,'m',2),(12,'q',3),(13,'m',4),(14,'d',5), (15,'g',6),(16,'x',7),(17,'f',8); +analyze table t1,t2; +Table Op Msg_type Msg_text +test.t1 analyze status OK +test.t2 analyze status OK explain SELECT * FROM t1 WHERE b IN ( SELECT d FROM t2, t1 @@ -955,6 +968,9 @@ INSERT INTO t1 VALUES ('y','y'),('t','t'),('d','d'),('s','s'),('r','r'), ('m','m'),('b','b'),('x','x'),('g','g'),('p','p'), ('q','q'),('w','w'),('d','d'),('e','e'); +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1; # This query returned 6 rows instead of 19 SELECT * FROM v1 @@ -988,6 +1004,9 @@ y y CREATE TABLE t2 (a VARCHAR(1), b VARCHAR(1) NOT NULL, KEY(a)) ENGINE=InnoDB; INSERT INTO t2 SELECT * FROM t1; INSERT INTO t2 SELECT * FROM t1; +ANALYZE TABLE t2; +Table Op Msg_type Msg_text +test.t2 analyze status OK EXPLAIN SELECT * FROM t2 WHERE (a, a) IN (SELECT alias2.b, alias2.a FROM t1 AS alias1, t1 AS alias2 @@ -1083,11 +1102,11 @@ WHERE alias5.b = alias4.b AND ( alias5.b >= alias3.b OR alias5.c != alias3.c ) ); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY alias3 ALL PRIMARY NULL NULL NULL 19 Using where -1 PRIMARY alias4 ref PRIMARY,c c 4 test.alias3.d 1 Using index -1 PRIMARY alias5 eq_ref PRIMARY PRIMARY 4 test.alias4.b 1 Using where; FirstMatch(alias3) -1 PRIMARY alias2 ALL NULL NULL NULL NULL 14 Using join buffer (flat, BNL join) +1 PRIMARY alias3 ALL PRIMARY NULL NULL NULL 19 +1 PRIMARY alias5 index PRIMARY c 4 NULL 19 Using where; Using index +1 PRIMARY alias4 eq_ref PRIMARY,c PRIMARY 4 test.alias5.b 1 Using where; FirstMatch(alias3) 1 PRIMARY alias1 ALL NULL NULL NULL NULL 14 Using join buffer (flat, BNL join) +1 PRIMARY alias2 ALL NULL NULL NULL NULL 14 Using join buffer (flat, BNL join) SELECT COUNT(*) FROM t1 AS alias1, t1 AS alias2, t2 AS alias3 WHERE alias3.d IN ( SELECT alias4.c FROM t2 AS alias4, t2 AS alias5 @@ -1104,11 +1123,11 @@ WHERE alias5.b = alias4.b AND ( alias5.b >= alias3.b OR alias3.c != alias5.c ) ); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY alias3 ALL PRIMARY NULL NULL NULL 19 Using where -1 PRIMARY alias4 ref PRIMARY,c c 4 test.alias3.d 1 Using index -1 PRIMARY alias5 eq_ref PRIMARY PRIMARY 4 test.alias4.b 1 Using where; FirstMatch(alias3) -1 PRIMARY alias2 ALL NULL NULL NULL NULL 14 Using join buffer (flat, BNL join) +1 PRIMARY alias3 ALL PRIMARY NULL NULL NULL 19 +1 PRIMARY alias5 index PRIMARY c 4 NULL 19 Using where; Using index +1 PRIMARY alias4 eq_ref PRIMARY,c PRIMARY 4 test.alias5.b 1 Using where; FirstMatch(alias3) 1 PRIMARY alias1 ALL NULL NULL NULL NULL 14 Using join buffer (flat, BNL join) +1 PRIMARY alias2 ALL NULL NULL NULL NULL 14 Using join buffer (flat, BNL join) SELECT COUNT(*) FROM t1 AS alias1, t1 AS alias2, t2 AS alias3 WHERE alias3.d IN ( SELECT alias4.c FROM t2 AS alias4, t2 AS alias5 @@ -1234,6 +1253,11 @@ INSERT IGNORE INTO t2 (t2id, t1idref) SELECT t1id, t1id FROM t1; INSERT IGNORE INTO t1 VALUES (200001, 'a'); INSERT IGNORE INTO t2 (t2id, t1idref) VALUES (200011, 200001),(200012, 200001),(200013, 200001); INSERT IGNORE INTO t3 VALUES (1, 200011, 1), (1, 200012, 2), (1, 200013, 3); +ANALYZE TABLE t1,t2,t3; +Table Op Msg_type Msg_text +test.t1 analyze status OK +test.t2 analyze status OK +test.t3 analyze status OK set @tmp7474= @@optimizer_search_depth; SET SESSION optimizer_search_depth = 1; SELECT SQL_NO_CACHE @@ -1334,7 +1358,15 @@ a pk b DROP TABLE t1,t2,t3; DROP VIEW v3; # This must be the last in the file: +set global innodb_stats_persistent= @innodb_stats_persistent_save; +set global innodb_stats_persistent_sample_pages= +@innodb_stats_persistent_sample_pages_save; set optimizer_switch=@subselect_sj2_tmp; +set @innodb_stats_persistent_save= @@innodb_stats_persistent; +set @innodb_stats_persistent_sample_pages_save= +@@innodb_stats_persistent_sample_pages; +set global innodb_stats_persistent= 1; +set global innodb_stats_persistent_sample_pages=100; set optimizer_switch=default; select @@optimizer_switch like '%materialization=on%'; @@optimizer_switch like '%materialization=on%' @@ -1419,7 +1451,7 @@ WHERE t1.cat_id = t3.cat_id AND t3.cat_id IN (SELECT cat_id FROM t2) AND t3.sack_id = 33479 AND t3.kit_id = 6; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t3 ref PRIMARY PRIMARY 5 const,const 4 Using index +1 PRIMARY t3 ref PRIMARY PRIMARY 5 const,const 5 Using index 1 PRIMARY t2 ref cat_id cat_id 4 test.t3.cat_id 2 Using where; Using index; FirstMatch(t3) 1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t2.cat_id 1 Using where; Using index SELECT count(*) FROM t1, t3 @@ -1435,7 +1467,7 @@ WHERE t1.cat_id = t3.cat_id AND t3.cat_id IN (SELECT cat_id FROM t4) AND t3.sack_id = 33479 AND t3.kit_id = 6; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t3 ref PRIMARY PRIMARY 5 const,const 4 Using index +1 PRIMARY t3 ref PRIMARY PRIMARY 5 const,const 5 Using index 1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.cat_id 1 Using index 2 MATERIALIZED t4 index cat_id cat_id 4 NULL 19 Using index @@ -1451,7 +1483,7 @@ WHERE t1.cat_id = t3.cat_id AND t3.cat_id IN (SELECT cat_id FROM t2) AND t3.sack_id = 33479 AND t3.kit_id = 6; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t3 ref PRIMARY PRIMARY 5 const,const 4 Using index +1 PRIMARY t3 ref PRIMARY PRIMARY 5 const,const 5 Using index 1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 Using where 1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.cat_id 1 Using index 2 MATERIALIZED t2 index cat_id cat_id 4 NULL 19 Using index @@ -1704,7 +1736,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t index PRIMARY PRIMARY 4 NULL 13 Using where; Using index 2 MATERIALIZED <subquery3> ALL distinct_key NULL NULL NULL 8 2 MATERIALIZED A ALL PRIMARY NULL NULL NULL 13 Using where; Using join buffer (flat, BNL join) -3 MATERIALIZED B ALL PRIMARY NULL NULL NULL 13 Using where +3 MATERIALIZED B range PRIMARY PRIMARY 4 NULL 8 Using where SELECT SQL_NO_CACHE t.id FROM t1 t WHERE ( @@ -1841,6 +1873,14 @@ CREATE TABLE t5 (id_product int) ENGINE=MyISAM; INSERT INTO `t5` VALUES (652),(668),(669),(670),(671),(673),(674),(675),(676), (677),(679),(680),(681),(682),(683),(684),(685),(686); +ANALYZE TABLE t1,t2,t3,t,t5; +Table Op Msg_type Msg_text +test.t1 analyze status OK +test.t2 analyze status Table is already up to date +test.t3 analyze status OK +test.t analyze Error Table 'test.t' doesn't exist +test.t analyze status Operation failed +test.t5 analyze status OK explain SELECT * FROM t3 JOIN t4 ON (t4.id_product = t3.id_product AND t4.id_shop = 1) @@ -1863,8 +1903,11 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY <subquery6> eq_ref distinct_key distinct_key 4 func 1 Using where 1 PRIMARY t5 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) 5 MATERIALIZED t2_4 range id_t2,id_product id_t2 5 NULL 18 Using index condition; Using where -4 MATERIALIZED t2_3 range id_t2,id_product id_t2 5 NULL 32 Using index condition; Using where +4 MATERIALIZED t2_3 range id_t2,id_product id_t2 5 NULL 33 Using index condition; Using where 3 MATERIALIZED t2_2 ref id_t2,id_product id_t2 5 const 12 -2 MATERIALIZED t2_1 ref id_t2,id_product id_t2 5 const 50 -6 MATERIALIZED t2_5 range id_t2,id_product id_t2 5 NULL 30 Using index condition; Using where +2 MATERIALIZED t2_1 ref id_t2,id_product id_t2 5 const 51 +6 MATERIALIZED t2_5 range id_t2,id_product id_t2 5 NULL 31 Using index condition; Using where drop table t1,t2,t3,t4,t5; +set global innodb_stats_persistent= @innodb_stats_persistent_save; +set global innodb_stats_persistent_sample_pages= +@innodb_stats_persistent_sample_pages_save; diff --git a/mysql-test/main/subselect_sj2_mat.test b/mysql-test/main/subselect_sj2_mat.test index 6ae687aa99a..47e48283b44 100644 --- a/mysql-test/main/subselect_sj2_mat.test +++ b/mysql-test/main/subselect_sj2_mat.test @@ -5,6 +5,12 @@ set optimizer_switch='materialization=on'; set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; --source subselect_sj2.test +set @innodb_stats_persistent_save= @@innodb_stats_persistent; +set @innodb_stats_persistent_sample_pages_save= + @@innodb_stats_persistent_sample_pages; + +set global innodb_stats_persistent= 1; +set global innodb_stats_persistent_sample_pages=100; set optimizer_switch=default; select @@optimizer_switch like '%materialization=on%'; @@ -467,6 +473,8 @@ CREATE TABLE t5 (id_product int) ENGINE=MyISAM; INSERT INTO `t5` VALUES (652),(668),(669),(670),(671),(673),(674),(675),(676), (677),(679),(680),(681),(682),(683),(684),(685),(686); + +ANALYZE TABLE t1,t2,t3,t,t5; explain SELECT * FROM t3 @@ -481,3 +489,7 @@ AND t3.id_product IN (SELECT id_product FROM t2 t2_4 WHERE t2_4.id_t2 = 34 OR t2 AND t3.id_product IN (SELECT id_product FROM t2 t2_5 WHERE t2_5.id_t2 = 29 OR t2_5.id_t2 = 28 OR t2_5.id_t2 = 26); drop table t1,t2,t3,t4,t5; + +set global innodb_stats_persistent= @innodb_stats_persistent_save; +set global innodb_stats_persistent_sample_pages= + @innodb_stats_persistent_sample_pages_save; diff --git a/mysql-test/main/subselect_sj_jcl6.result b/mysql-test/main/subselect_sj_jcl6.result index e31f4f3a1cc..92719507742 100644 --- a/mysql-test/main/subselect_sj_jcl6.result +++ b/mysql-test/main/subselect_sj_jcl6.result @@ -217,7 +217,7 @@ a b a b insert into t1 select (A.a + 10 * B.a),1 from t0 A, t0 B; explain extended select * from t1 where a in (select pk from t10 where pk<3); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t10 range PRIMARY PRIMARY 4 NULL 4 100.00 Using where; Using index +1 PRIMARY t10 range PRIMARY PRIMARY 4 NULL 3 100.00 Using where; Using index 1 PRIMARY t1 ALL NULL NULL NULL NULL 103 100.00 Using where; Using join buffer (flat, BNL join) Warnings: Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t10` join `test`.`t1` where `test`.`t1`.`a` = `test`.`t10`.`pk` and `test`.`t10`.`pk` < 3 @@ -742,7 +742,7 @@ SELECT int_key FROM ot1 WHERE int_nokey IN (SELECT it2.int_key FROM it1 LEFT JOIN it2 ON it2.datetime_key); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 11 +1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 10 1 PRIMARY ot1 ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) 2 MATERIALIZED it1 index NULL int_key 4 NULL 2 Using index 2 MATERIALIZED it2 ALL int_key,datetime_key NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) @@ -3093,9 +3093,11 @@ set optimizer_switch= @tmp_mdev6859; set @tmp_mdev12675=@@optimizer_switch; set optimizer_switch=default; create table t1 (a int) engine=myisam; -insert into t1 values (5),(3),(2),(7),(2),(5),(1); +insert into t1 values (3),(2),(7),(2),(1); create table t2 (b int, index idx(b)) engine=myisam; -insert into t2 values (2),(3),(2),(1),(3),(4); +insert into t2 values (2),(3),(2),(1),(3),(4),(1),(2),(1),(2); +insert into t2 select b+10 from t2; +insert into t2 select b+10 from t2; insert into t2 select b+10 from t2; insert into t2 select b+10 from t2; insert into t2 select b+10 from t2; @@ -3114,15 +3116,15 @@ test.t2 analyze status OK explain select a from t1, t2 where b between 1 and 2 and a in (select b from t2); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 7 Using where -1 PRIMARY t2 ref idx idx 5 test.t1.a 256 Using index; FirstMatch(t1) -1 PRIMARY t2 range idx idx 5 NULL 2 Using where; Using index; Using join buffer (flat, BNL join) +1 PRIMARY t1 ALL NULL NULL NULL NULL 5 Using where +1 PRIMARY t2 ref idx idx 5 test.t1.a 1463 Using index; FirstMatch(t1) +1 PRIMARY t2 range idx idx 5 NULL 5 Using where; Using index; Using join buffer (flat, BNL join) explain select a from t1 join t2 on b between 1 and 2 and a in (select b from t2); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 7 Using where -1 PRIMARY t2 ref idx idx 5 test.t1.a 256 Using index; FirstMatch(t1) -1 PRIMARY t2 range idx idx 5 NULL 2 Using where; Using index; Using join buffer (flat, BNL join) +1 PRIMARY t1 ALL NULL NULL NULL NULL 5 Using where +1 PRIMARY t2 ref idx idx 5 test.t1.a 1463 Using index; FirstMatch(t1) +1 PRIMARY t2 range idx idx 5 NULL 5 Using where; Using index; Using join buffer (flat, BNL join) drop table t1,t2; set optimizer_switch= @tmp_mdev12675; # diff --git a/mysql-test/main/subselect_sj_mat.result b/mysql-test/main/subselect_sj_mat.result index 983c6c31c65..3f99d340af8 100644 --- a/mysql-test/main/subselect_sj_mat.result +++ b/mysql-test/main/subselect_sj_mat.result @@ -38,6 +38,14 @@ create index it3i3 on t3i (c1, c2); insert into t1i select * from t1; insert into t2i select * from t2; insert into t3i select * from t3; +analyze table t1,t2,t3,t1i,t2i,t3i; +Table Op Msg_type Msg_text +test.t1 analyze status OK +test.t2 analyze status OK +test.t3 analyze status OK +test.t1i analyze status Table is already up to date +test.t2i analyze status Table is already up to date +test.t3i analyze status Table is already up to date set @@optimizer_switch='materialization=on,in_to_exists=off,firstmatch=off'; /****************************************************************************** * Simple tests. @@ -149,30 +157,47 @@ select * from t1i where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' a1 a2 1 - 01 2 - 01 1 - 02 2 - 02 +create table t2i_c like t2i; +insert into t2i_c select * from t2i; +insert into t2i_c select * from t2i; +insert into t2i_c select * from t2i; +insert into t2i_c select * from t2i; +analyze table t2i_c; +Table Op Msg_type Msg_text +test.t2i_c analyze status OK +show create table t2i_c; +Table Create Table +t2i_c CREATE TABLE `t2i_c` ( + `b1` char(8) DEFAULT NULL, + `b2` char(8) DEFAULT NULL, + KEY `it2i1` (`b1`), + KEY `it2i2` (`b2`), + KEY `it2i3` (`b1`,`b2`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 explain extended -select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1); +select * from t1 where (a1, a2) in (select b1, max(b2) from t2i_c group by b1); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where 1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 16 test.t1.a1,test.t1.a2 1 100.00 -2 MATERIALIZED t2i range NULL it2i3 9 NULL 3 100.00 Using index for group-by +2 MATERIALIZED t2i_c range NULL it2i3 9 NULL 3 100.00 Using index for group-by Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (/* select#2 */ select `test`.`t2i`.`b1`,max(`test`.`t2i`.`b2`) from `test`.`t2i` group by `test`.`t2i`.`b1`) join `test`.`t1` where `<subquery2>`.`b1` = `test`.`t1`.`a1` and `<subquery2>`.`max(b2)` = `test`.`t1`.`a2` -select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1); +Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (/* select#2 */ select `test`.`t2i_c`.`b1`,max(`test`.`t2i_c`.`b2`) from `test`.`t2i_c` group by `test`.`t2i_c`.`b1`) join `test`.`t1` where `<subquery2>`.`b1` = `test`.`t1`.`a1` and `<subquery2>`.`max(b2)` = `test`.`t1`.`a2` +select * from t1 where (a1, a2) in (select b1, max(b2) from t2i_c group by b1); a1 a2 1 - 01 2 - 01 1 - 02 2 - 02 -prepare st1 from "explain select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1)"; +prepare st1 from "explain select * from t1 where (a1, a2) in (select b1, max(b2) from t2i_c group by b1)"; execute st1; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where 1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 16 test.t1.a1,test.t1.a2 1 -2 MATERIALIZED t2i range NULL it2i3 9 NULL 3 Using index for group-by +2 MATERIALIZED t2i_c range NULL it2i3 9 NULL 3 Using index for group-by execute st1; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where 1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 16 test.t1.a1,test.t1.a2 1 -2 MATERIALIZED t2i range NULL it2i3 9 NULL 3 Using index for group-by -prepare st2 from "select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1)"; +2 MATERIALIZED t2i_c range NULL it2i3 9 NULL 3 Using index for group-by +prepare st2 from "select * from t1 where (a1, a2) in (select b1, max(b2) from t2i_c group by b1)"; execute st2; a1 a2 1 - 01 2 - 01 @@ -181,6 +206,7 @@ execute st2; a1 a2 1 - 01 2 - 01 1 - 02 2 - 02 +drop table t2i_c; explain extended select * from t1 where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1); id select_type table type possible_keys key key_len ref rows filtered Extra diff --git a/mysql-test/main/subselect_sj_mat.test b/mysql-test/main/subselect_sj_mat.test index 7b8179bba38..2cffa2e82b8 100644 --- a/mysql-test/main/subselect_sj_mat.test +++ b/mysql-test/main/subselect_sj_mat.test @@ -55,6 +55,7 @@ create index it3i3 on t3i (c1, c2); insert into t1i select * from t1; insert into t2i select * from t2; insert into t3i select * from t3; +analyze table t1,t2,t3,t1i,t2i,t3i; # force the use of materialization set @@optimizer_switch='materialization=on,in_to_exists=off,firstmatch=off'; @@ -108,16 +109,24 @@ select * from t1i where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' select * from t1i where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1); # BUG#31639: Wrong plan for uncorrelated subquery when loose scan is applicable. +create table t2i_c like t2i; +insert into t2i_c select * from t2i; +insert into t2i_c select * from t2i; +insert into t2i_c select * from t2i; +insert into t2i_c select * from t2i; +analyze table t2i_c; +show create table t2i_c; explain extended -select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1); -select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1); +select * from t1 where (a1, a2) in (select b1, max(b2) from t2i_c group by b1); +select * from t1 where (a1, a2) in (select b1, max(b2) from t2i_c group by b1); -prepare st1 from "explain select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1)"; +prepare st1 from "explain select * from t1 where (a1, a2) in (select b1, max(b2) from t2i_c group by b1)"; execute st1; execute st1; -prepare st2 from "select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1)"; +prepare st2 from "select * from t1 where (a1, a2) in (select b1, max(b2) from t2i_c group by b1)"; execute st2; execute st2; +drop table t2i_c; explain extended select * from t1 where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1); diff --git a/mysql-test/main/table_elim.result b/mysql-test/main/table_elim.result index cf9a4a38779..2bfbbfb433f 100644 --- a/mysql-test/main/table_elim.result +++ b/mysql-test/main/table_elim.result @@ -138,7 +138,7 @@ Note 1003 /* select#1 */ select `f`.`id` AS `id` from `test`.`t0` `f` join `test This should use facts, a2 and its subquery: explain extended select id from v1 where attr2 between 12 and 14; id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY a2 range PRIMARY,attr2 attr2 5 NULL 5 100.00 Using index condition; Using where +1 PRIMARY a2 range PRIMARY,attr2 attr2 5 NULL 4 100.00 Using index condition; Using where 1 PRIMARY f eq_ref PRIMARY PRIMARY 4 test.a2.id 1 100.00 Using index 3 DEPENDENT SUBQUERY t2 ref PRIMARY PRIMARY 4 test.a2.id 2 100.00 Using index Warnings: @@ -166,7 +166,7 @@ Note 1003 /* select#1 */ select `f`.`id` AS `id` from `test`.`t0` `f` join `test This should use facts, a2 and its subquery: explain extended select id from v2 where attr2 between 12 and 14; id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY a2 range PRIMARY,attr2 attr2 5 NULL 5 100.00 Using index condition +1 PRIMARY a2 range PRIMARY,attr2 attr2 5 NULL 4 100.00 Using index condition 1 PRIMARY f eq_ref PRIMARY PRIMARY 4 test.a2.id 1 100.00 Using where; Using index 3 DEPENDENT SUBQUERY t2 ref PRIMARY PRIMARY 4 test.f.id 2 100.00 Using index Warnings: diff --git a/mysql-test/main/type_bit.result b/mysql-test/main/type_bit.result index 12fe302a5be..42b31be72d2 100644 --- a/mysql-test/main/type_bit.result +++ b/mysql-test/main/type_bit.result @@ -256,7 +256,7 @@ a+0 b+0 127 403 explain select a+0, b+0 from t1 where a > 40 and a < 70 order by 2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 2 NULL 8 Using where; Using index; Using filesort +1 SIMPLE t1 range a a 2 NULL 9 Using where; Using index; Using filesort select a+0, b+0 from t1 where a > 40 and a < 70 order by 2; a+0 b+0 57 135 @@ -677,9 +677,12 @@ DROP TABLE t2; CREATE TABLE t1(a BIT(13), KEY(a)); INSERT IGNORE INTO t1(a) VALUES (65535),(65525),(65535),(65535),(65535),(65535),(65535),(65535),(65535),(65535); +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK EXPLAIN SELECT 1 FROM t1 GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range NULL a 3 NULL 6 Using index for group-by +1 SIMPLE t1 range NULL a 3 NULL 2 Using index for group-by SELECT 1 FROM t1 GROUP BY a; 1 1 @@ -762,7 +765,7 @@ CREATE TABLE t1 (a BIT(7), b BIT(9), KEY(a, b)); INSERT INTO t1 VALUES(0, 0), (5, 3), (5, 6), (6, 4), (7, 0); EXPLAIN SELECT a+0, b+0 FROM t1 WHERE a > 4 and b < 7 ORDER BY 2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 2 NULL 4 Using where; Using index; Using filesort +1 SIMPLE t1 index a a 5 NULL 5 Using where; Using index; Using filesort DROP TABLE t1; End of 5.0 tests create table t1(a bit(7)); diff --git a/mysql-test/main/type_bit.test b/mysql-test/main/type_bit.test index c6d5a1f2f05..ee14b38ada0 100644 --- a/mysql-test/main/type_bit.test +++ b/mysql-test/main/type_bit.test @@ -326,6 +326,7 @@ CREATE TABLE t1(a BIT(13), KEY(a)); --disable_warnings INSERT IGNORE INTO t1(a) VALUES (65535),(65525),(65535),(65535),(65535),(65535),(65535),(65535),(65535),(65535); +ANALYZE TABLE t1; --enable_warnings EXPLAIN SELECT 1 FROM t1 GROUP BY a; diff --git a/mysql-test/main/type_blob.result b/mysql-test/main/type_blob.result index 3c99366168c..83a7f49f8c6 100644 --- a/mysql-test/main/type_blob.result +++ b/mysql-test/main/type_blob.result @@ -618,7 +618,8 @@ id txt 3 Ford drop table t1; create table t1 (id integer primary key auto_increment, txt text, index txt_index (txt (20))); -insert into t1 (txt) values ('Chevy'), ('Chevy '), (NULL); +insert into t1 (txt) values +('Chevy'), ('Chevy '), (NULL), ('Honda'), ('Subaru'), ('Honda'); select * from t1 where txt='Chevy' or txt is NULL; id txt 1 Chevy @@ -626,7 +627,7 @@ id txt 3 NULL explain select * from t1 where txt='Chevy' or txt is NULL; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref_or_null txt_index txt_index 23 const 2 Using where +1 SIMPLE t1 ref_or_null txt_index txt_index 23 const 3 Using where select * from t1 where txt='Chevy '; id txt 1 Chevy @@ -648,7 +649,7 @@ select * from t1 where txt='Chevy' or txt='Chevy ' or txt='Ford'; id txt 1 Chevy 2 Chevy -4 Ford +7 Ford select * from t1 where txt='Chevy' or txt='Chevy '; id txt 1 Chevy @@ -688,12 +689,18 @@ id txt 2 Chevy select * from t1 where txt > 'Chevy'; id txt -4 Ford +4 Honda +5 Subaru +6 Honda +7 Ford select * from t1 where txt >= 'Chevy'; id txt 1 Chevy 2 Chevy -4 Ford +4 Honda +5 Subaru +6 Honda +7 Ford alter table t1 modify column txt blob; explain select * from t1 where txt='Chevy' or txt is NULL; id select_type table type possible_keys key key_len ref rows Extra diff --git a/mysql-test/main/type_blob.test b/mysql-test/main/type_blob.test index 2c74d4ea241..4b5f3578e3a 100644 --- a/mysql-test/main/type_blob.test +++ b/mysql-test/main/type_blob.test @@ -360,7 +360,8 @@ select * from t1 where txt >= 'Chevy'; drop table t1; create table t1 (id integer primary key auto_increment, txt text, index txt_index (txt (20))); -insert into t1 (txt) values ('Chevy'), ('Chevy '), (NULL); +insert into t1 (txt) values + ('Chevy'), ('Chevy '), (NULL), ('Honda'), ('Subaru'), ('Honda'); select * from t1 where txt='Chevy' or txt is NULL; explain select * from t1 where txt='Chevy' or txt is NULL; select * from t1 where txt='Chevy '; diff --git a/mysql-test/main/type_date.result b/mysql-test/main/type_date.result index 2c268cfdd88..3515312d5b7 100644 --- a/mysql-test/main/type_date.result +++ b/mysql-test/main/type_date.result @@ -211,7 +211,7 @@ a SET SQL_MODE=TRADITIONAL; EXPLAIN SELECT * FROM t1 WHERE a = '0000-00-00'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref i i 4 const 1 Using index +1 SIMPLE t1 ref i i 4 const 2 Using index SELECT * FROM t1 WHERE a = '0000-00-00'; a 0000-00-00 @@ -240,7 +240,7 @@ a SET SQL_MODE=TRADITIONAL; EXPLAIN SELECT * FROM t1 WHERE a = '1000-00-00'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref i i 4 const 1 Using index +1 SIMPLE t1 ref i i 4 const 2 Using index SELECT * FROM t1 WHERE a = '1000-00-00'; a 1000-00-00 diff --git a/mysql-test/main/type_datetime.result b/mysql-test/main/type_datetime.result index 7a213842e03..4a95556db55 100644 --- a/mysql-test/main/type_datetime.result +++ b/mysql-test/main/type_datetime.result @@ -103,7 +103,7 @@ date numfacture expedition 0000-00-00 00:00:00 1212 0001-00-00 00:00:00 EXPLAIN SELECT * FROM t1 WHERE expedition='0001-00-00 00:00:00'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref expedition expedition 5 const 1 +1 SIMPLE t1 ref expedition expedition 5 const 2 drop table t1; create table t1 (a datetime not null, b datetime not null); insert into t1 values (now(), now()); @@ -1253,7 +1253,7 @@ INSERT INTO t1 VALUES ('2001-01-01 23:00:03', 'yes'); INSERT INTO t1 VALUES ('2001-01-01 23:00:04', 'yes'); EXPLAIN SELECT * FROM t1 WHERE a NOT IN ('2001-01-01 23:00:01','2001-01-01 23:00:02'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 6 NULL 5 Using index condition +1 SIMPLE t1 range a a 6 NULL 4 Using index condition SELECT * FROM t1 WHERE a NOT IN ('2001-01-01 23:00:01','2001-01-01 23:00:02'); a filler 2001-01-01 23:00:03 yes @@ -1292,7 +1292,7 @@ INSERT INTO t1 VALUES ('2001-01-01 23:00:03.1', 'yes'); INSERT INTO t1 VALUES ('2001-01-01 23:00:04.1', 'yes'); EXPLAIN SELECT * FROM t1 WHERE a NOT IN ('2001-01-01 23:00:01.1','2001-01-01 23:00:02.1'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 7 NULL 5 Using index condition +1 SIMPLE t1 range a a 7 NULL 4 Using index condition SELECT * FROM t1 WHERE a NOT IN ('2001-01-01 23:00:01.1','2001-01-01 23:00:02.1'); a filler 2001-01-01 23:00:03.1 yes diff --git a/mysql-test/main/type_time.result b/mysql-test/main/type_time.result index 0a66a94db69..fe72f2dc576 100644 --- a/mysql-test/main/type_time.result +++ b/mysql-test/main/type_time.result @@ -1608,7 +1608,7 @@ INSERT INTO t1 VALUES ('23:00:03', 'yes'); INSERT INTO t1 VALUES ('23:00:04', 'yes'); EXPLAIN SELECT * FROM t1 WHERE a NOT IN ('23:00:01','23:00:02'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 4 NULL 5 Using index condition +1 SIMPLE t1 range a a 4 NULL 4 Using index condition SELECT * FROM t1 WHERE a NOT IN ('23:00:01','23:00:02'); a filler 23:00:03 yes @@ -1686,7 +1686,7 @@ INSERT INTO t1 VALUES ('24:00:03', 'yes'); INSERT INTO t1 VALUES ('24:00:04', 'yes'); EXPLAIN SELECT * FROM t1 WHERE a NOT IN ('24:00:01','24:00:02'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 4 NULL 5 Using index condition +1 SIMPLE t1 range a a 4 NULL 4 Using index condition SELECT * FROM t1 WHERE a NOT IN ('24:00:01','24:00:02'); a filler 24:00:03 yes @@ -1764,7 +1764,7 @@ INSERT INTO t1 VALUES ('838:00:03', 'yes'); INSERT INTO t1 VALUES ('838:00:04', 'yes'); EXPLAIN SELECT * FROM t1 WHERE a NOT IN ('838:00:01','838:00:02'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 4 NULL 5 Using index condition +1 SIMPLE t1 range a a 4 NULL 4 Using index condition SELECT * FROM t1 WHERE a NOT IN ('838:00:01','838:00:02'); a filler 838:00:03 yes @@ -1842,7 +1842,7 @@ INSERT INTO t1 VALUES ('23:00:03.1', 'yes'); INSERT INTO t1 VALUES ('23:00:04.1', 'yes'); EXPLAIN SELECT * FROM t1 WHERE a NOT IN ('23:00:01.1','23:00:02.1'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 5 Using index condition +1 SIMPLE t1 range a a 5 NULL 4 Using index condition SELECT * FROM t1 WHERE a NOT IN ('23:00:01.1','23:00:02.1'); a filler 23:00:03.1 yes @@ -1920,7 +1920,7 @@ INSERT INTO t1 VALUES ('838:00:03.1', 'yes'); INSERT INTO t1 VALUES ('838:00:04.1', 'yes'); EXPLAIN SELECT * FROM t1 WHERE a NOT IN ('838:00:01.1','838:00:02.1'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 5 Using index condition +1 SIMPLE t1 range a a 5 NULL 4 Using index condition SELECT * FROM t1 WHERE a NOT IN ('838:00:01.1','838:00:02.1'); a filler 838:00:03.1 yes diff --git a/mysql-test/main/type_timestamp.result b/mysql-test/main/type_timestamp.result index a708ef5ec34..e8bd81a7df5 100644 --- a/mysql-test/main/type_timestamp.result +++ b/mysql-test/main/type_timestamp.result @@ -532,6 +532,10 @@ DROP TABLE t1; # are appended with .0 # CREATE TABLE t1 ( a TIMESTAMP, KEY ( a ) ); +INSERT INTO t1 VALUES( '2010-02-01 09:30:01' ); +INSERT INTO t1 VALUES( '2010-02-01 09:30:02' ); +INSERT INTO t1 VALUES( '2010-02-01 09:30:03' ); +INSERT INTO t1 VALUES( '2010-02-01 09:30:04' ); INSERT INTO t1 VALUES( '2010-02-01 09:31:01' ); INSERT INTO t1 VALUES( '2010-02-01 09:31:02' ); INSERT INTO t1 VALUES( '2010-02-01 09:31:03' ); @@ -548,10 +552,18 @@ a 2010-02-01 09:31:04 SELECT * FROM t1 WHERE a <= '2010-02-01 09:31:02.0'; a +2010-02-01 09:30:01 +2010-02-01 09:30:02 +2010-02-01 09:30:03 +2010-02-01 09:30:04 2010-02-01 09:31:01 2010-02-01 09:31:02 SELECT * FROM t1 WHERE '2010-02-01 09:31:02.0' >= a; a +2010-02-01 09:30:01 +2010-02-01 09:30:02 +2010-02-01 09:30:03 +2010-02-01 09:30:04 2010-02-01 09:31:01 2010-02-01 09:31:02 EXPLAIN diff --git a/mysql-test/main/type_timestamp.test b/mysql-test/main/type_timestamp.test index eeb6e2f8213..0a3ffb2b899 100644 --- a/mysql-test/main/type_timestamp.test +++ b/mysql-test/main/type_timestamp.test @@ -367,6 +367,10 @@ DROP TABLE t1; --echo # CREATE TABLE t1 ( a TIMESTAMP, KEY ( a ) ); +INSERT INTO t1 VALUES( '2010-02-01 09:30:01' ); +INSERT INTO t1 VALUES( '2010-02-01 09:30:02' ); +INSERT INTO t1 VALUES( '2010-02-01 09:30:03' ); +INSERT INTO t1 VALUES( '2010-02-01 09:30:04' ); INSERT INTO t1 VALUES( '2010-02-01 09:31:01' ); INSERT INTO t1 VALUES( '2010-02-01 09:31:02' ); INSERT INTO t1 VALUES( '2010-02-01 09:31:03' ); diff --git a/mysql-test/main/type_varchar.result b/mysql-test/main/type_varchar.result index 53f390e8b38..a23de349e4e 100644 --- a/mysql-test/main/type_varchar.result +++ b/mysql-test/main/type_varchar.result @@ -108,7 +108,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref v v 257 const 3 Using where; Using index explain select * from t1 where v like 'S%' order by v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 257 NULL 2 Using where; Using index +1 SIMPLE t1 range v v 257 NULL 3 Using where; Using index alter table t1 change v v varchar(255); select * from t1 where v like 'This is a test' order by v; v @@ -132,7 +132,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref v v 258 const 3 Using where; Using index explain select * from t1 where v like 'S%' order by v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 258 NULL 2 Using where; Using index +1 SIMPLE t1 range v v 258 NULL 3 Using where; Using index alter table t1 change v v varchar(256); select * from t1 where v like 'This is a test' order by v; v @@ -156,7 +156,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref v v 259 const 3 Using where; Using index explain select * from t1 where v like 'S%' order by v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 259 NULL 2 Using where; Using index +1 SIMPLE t1 range v v 259 NULL 3 Using where; Using index alter table t1 change v v varchar(257); select * from t1 where v like 'This is a test' order by v; v @@ -180,7 +180,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref v v 260 const 3 Using where; Using index explain select * from t1 where v like 'S%' order by v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 260 NULL 2 Using where; Using index +1 SIMPLE t1 range v v 260 NULL 3 Using where; Using index alter table t1 change v v varchar(258); select * from t1 where v like 'This is a test' order by v; v @@ -204,7 +204,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref v v 261 const 3 Using where; Using index explain select * from t1 where v like 'S%' order by v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 261 NULL 2 Using where; Using index +1 SIMPLE t1 range v v 261 NULL 3 Using where; Using index alter table t1 change v v varchar(259); select * from t1 where v like 'This is a test' order by v; v @@ -228,7 +228,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref v v 262 const 3 Using where; Using index explain select * from t1 where v like 'S%' order by v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 262 NULL 2 Using where; Using index +1 SIMPLE t1 range v v 262 NULL 3 Using where; Using index alter table t1 change v v varchar(258); select * from t1 where v like 'This is a test' order by v; v @@ -252,7 +252,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref v v 261 const 3 Using where; Using index explain select * from t1 where v like 'S%' order by v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 261 NULL 2 Using where; Using index +1 SIMPLE t1 range v v 261 NULL 3 Using where; Using index alter table t1 change v v varchar(257); select * from t1 where v like 'This is a test' order by v; v @@ -276,7 +276,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref v v 260 const 3 Using where; Using index explain select * from t1 where v like 'S%' order by v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 260 NULL 2 Using where; Using index +1 SIMPLE t1 range v v 260 NULL 3 Using where; Using index alter table t1 change v v varchar(256); select * from t1 where v like 'This is a test' order by v; v @@ -300,7 +300,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref v v 259 const 3 Using where; Using index explain select * from t1 where v like 'S%' order by v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 259 NULL 2 Using where; Using index +1 SIMPLE t1 range v v 259 NULL 3 Using where; Using index alter table t1 change v v varchar(255); select * from t1 where v like 'This is a test' order by v; v @@ -324,7 +324,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref v v 258 const 3 Using where; Using index explain select * from t1 where v like 'S%' order by v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 258 NULL 2 Using where; Using index +1 SIMPLE t1 range v v 258 NULL 3 Using where; Using index alter table t1 change v v varchar(254); select * from t1 where v like 'This is a test' order by v; v @@ -348,7 +348,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref v v 257 const 3 Using where; Using index explain select * from t1 where v like 'S%' order by v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 257 NULL 2 Using where; Using index +1 SIMPLE t1 range v v 257 NULL 3 Using where; Using index alter table t1 change v v varchar(253); alter table t1 change v v varchar(254), drop key v; alter table t1 change v v varchar(300), add key (v(10)); @@ -374,7 +374,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref v v 13 const 4 Using where explain select * from t1 where v like 'S%' order by v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 13 NULL 2 Using where; Using filesort +1 SIMPLE t1 range v v 13 NULL 3 Using where; Using filesort drop table t1; create table t1 (pkcol varchar(16), othercol varchar(16), primary key (pkcol)); insert into t1 values ('test', 'something'); diff --git a/mysql-test/main/user_var.result b/mysql-test/main/user_var.result index bf3d4f6dada..b475a8ca60a 100644 --- a/mysql-test/main/user_var.result +++ b/mysql-test/main/user_var.result @@ -22,7 +22,7 @@ i @vv1:=if(sv1.i,1,0) @vv2:=if(sv2.i,1,0) @vv3:=if(sv3.i,1,0) @vv1+@vv2+@vv3 2 1 0 0 1 explain select * from t1 where i=@vv1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref i i 4 const 1 +1 SIMPLE t1 ref i i 4 const 2 select @vv1,i,v from t1 where i=@vv1; @vv1 i v 1 1 1 @@ -35,7 +35,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index NULL i 4 NULL 3 Using where; Using index explain select * from t1 where i=@vv1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref i i 4 const 1 +1 SIMPLE t1 ref i i 4 const 2 drop table t1,t2; set @a=0,@b=0; select @a:=10, @b:=1, @a > @b, @a < @b; diff --git a/mysql-test/main/view.result b/mysql-test/main/view.result index fcd3fc202e0..eed9b224e2e 100644 --- a/mysql-test/main/view.result +++ b/mysql-test/main/view.result @@ -4394,7 +4394,8 @@ DROP VIEW v1,v2; DROP TABLE t1; CREATE TABLE t1 (a varchar(10), KEY (a)) ; INSERT INTO t1 VALUES -('DD'), ('ZZ'), ('ZZ'), ('KK'), ('FF'), ('HH'),('MM'); +('DD'), ('ZZ'), ('ZZ'), ('KK'), ('FF'), ('HH'), ('MM'), +('AA'), ('DD'), ('CC'), ('GG'); CREATE VIEW v1 AS SELECT * FROM t1; # t1 and v1 should return the same result set SELECT * FROM v1 WHERE a > 'JJ' OR a <> 0 AND a = 'VV'; diff --git a/mysql-test/main/view.test b/mysql-test/main/view.test index 658cd09ae6f..f5590e01639 100644 --- a/mysql-test/main/view.test +++ b/mysql-test/main/view.test @@ -4248,7 +4248,8 @@ DROP TABLE t1; CREATE TABLE t1 (a varchar(10), KEY (a)) ; INSERT INTO t1 VALUES - ('DD'), ('ZZ'), ('ZZ'), ('KK'), ('FF'), ('HH'),('MM'); + ('DD'), ('ZZ'), ('ZZ'), ('KK'), ('FF'), ('HH'), ('MM'), + ('AA'), ('DD'), ('CC'), ('GG'); CREATE VIEW v1 AS SELECT * FROM t1; diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 37a3decdbca..651ace759a3 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -6265,19 +6265,22 @@ ha_rows ha_partition::multi_range_read_info_const(uint keyno, uint ret_mrr_mode= 0; range_seq_t seq_it; part_id_range save_part_spec; + Cost_estimate part_cost; DBUG_ENTER("ha_partition::multi_range_read_info_const"); DBUG_PRINT("enter", ("partition this: %p", this)); m_mrr_new_full_buffer_size= 0; save_part_spec= m_part_spec; + cost->reset(); + seq_it= seq->init(seq_init_param, n_ranges, *mrr_mode); if (unlikely((error= multi_range_key_create_key(seq, seq_it)))) { if (likely(error == HA_ERR_END_OF_FILE)) // No keys in range { rows= 0; - goto calc_cost; + goto end; } /* This error means that we can't do multi_range_read for the moment @@ -6306,18 +6309,20 @@ ha_rows ha_partition::multi_range_read_info_const(uint keyno, ha_rows tmp_rows; uint tmp_mrr_mode; m_mrr_buffer_size[i]= 0; + part_cost.reset(); tmp_mrr_mode= *mrr_mode; tmp_rows= (*file)-> multi_range_read_info_const(keyno, &m_part_seq_if, &m_partition_part_key_multi_range_hld[i], m_part_mrr_range_length[i], &m_mrr_buffer_size[i], - &tmp_mrr_mode, cost); + &tmp_mrr_mode, &part_cost); if (tmp_rows == HA_POS_ERROR) { m_part_spec= save_part_spec; DBUG_RETURN(HA_POS_ERROR); } + cost->add(&part_cost); rows+= tmp_rows; ret_mrr_mode|= tmp_mrr_mode; m_mrr_new_full_buffer_size+= m_mrr_buffer_size[i]; @@ -6325,15 +6330,8 @@ ha_rows ha_partition::multi_range_read_info_const(uint keyno, } while (*(++file)); *mrr_mode= ret_mrr_mode; -calc_cost: +end: m_part_spec= save_part_spec; - cost->reset(); - cost->avg_io_cost= 1; - if ((*mrr_mode & HA_MRR_INDEX_ONLY) && rows > 2) - cost->io_count= keyread_time(keyno, n_ranges, (uint) rows); - else - cost->io_count= read_time(keyno, n_ranges, rows); - cost->cpu_cost= (double) rows / TIME_FOR_COMPARE + 0.01; DBUG_RETURN(rows); } @@ -9341,6 +9339,43 @@ double ha_partition::scan_time() /** + @brief + Caculate time to scan the given index (index only scan) + + @param inx Index number to scan + + @return time for scanning index inx +*/ + +double ha_partition::key_scan_time(uint inx) +{ + double scan_time= 0; + uint i; + DBUG_ENTER("ha_partition::key_scan_time"); + for (i= bitmap_get_first_set(&m_part_info->read_partitions); + i < m_tot_parts; + i= bitmap_get_next_set(&m_part_info->read_partitions, i)) + scan_time+= m_file[i]->key_scan_time(inx); + DBUG_RETURN(scan_time); +} + + +double ha_partition::keyread_time(uint inx, uint ranges, ha_rows rows) +{ + double read_time= 0; + uint i; + DBUG_ENTER("ha_partition::keyread_time"); + if (!ranges) + DBUG_RETURN(handler::keyread_time(inx, ranges, rows)); + for (i= bitmap_get_first_set(&m_part_info->read_partitions); + i < m_tot_parts; + i= bitmap_get_next_set(&m_part_info->read_partitions, i)) + read_time+= m_file[i]->keyread_time(inx, ranges, rows); + DBUG_RETURN(read_time); +} + + +/** Find number of records in a range. @param inx Index number @param min_key Start of range diff --git a/sql/ha_partition.h b/sql/ha_partition.h index 202f27840dc..f19e9ff96c8 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -912,6 +912,10 @@ public: */ virtual double scan_time(); + virtual double key_scan_time(uint inx); + + virtual double keyread_time(uint inx, uint ranges, ha_rows rows); + /* The next method will never be called if you do not implement indexes. */ diff --git a/sql/handler.cc b/sql/handler.cc index e5081accb30..30ce3f654df 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -43,6 +43,7 @@ #include "debug_sync.h" // DEBUG_SYNC #include "sql_audit.h" #include "ha_sequence.h" +#include "rowid_filter.h" #ifdef WITH_PARTITION_STORAGE_ENGINE #include "ha_partition.h" @@ -2602,36 +2603,26 @@ LEX_CSTRING *handler::engine_name() } -/** - The method returns the cost of the random I/O accesses when - index is used. +/* + It is assumed that the value of the parameter 'ranges' can be only 0 or 1. + If ranges == 1 then the function returns the cost of index only scan + by index 'keyno' of one range containing 'rows' key entries. + If ranges == 0 then the function returns only the cost of copying + those key entries into the engine buffers. */ -double handler::get_io_cost(uint index, ha_rows rows, uint *length) +double handler::keyread_time(uint index, uint ranges, ha_rows rows) { - uint len= table->key_info[index].key_length + ref_length; + DBUG_ASSERT(ranges == 0 || ranges == 1); + size_t len= table->key_info[index].key_length + ref_length; if (index == table->s->primary_key && table->file->primary_key_is_clustered()) len= table->s->stored_rec_length; - double keys_per_block= (stats.block_size/2.0/len+1); - *length= len; - return (rows + keys_per_block-1)/ keys_per_block; -} - - -double handler::keyread_time(uint index, uint ranges, ha_rows rows) -{ - /* - It is assumed that we will read trough the whole key range and that all - key blocks are half full (normally things are much better). It is also - assumed that each time we read the next key from the index, the handler - performs a random seek, thus the cost is proportional to the number of - blocks read. This model does not take into account clustered indexes - - engines that support that (e.g. InnoDB) may want to overwrite this method. - The model counts in the time to read index entries from cache. - */ - uint len; - return get_io_cost(index, rows, &len) + - len*rows/(stats.block_size+1)/TIME_FOR_COMPARE ; + uint keys_per_block= (stats.block_size/2.0/len+1); + ulonglong blocks= !rows ? 0 : (rows-1) / keys_per_block + 1; + double cost= (double)rows*len/(stats.block_size+1)*IDX_BLOCK_COPY_COST; + if (ranges) + cost+= blocks; + return cost; } void **handler::ha_data(THD *thd) const @@ -5766,6 +5757,35 @@ extern "C" enum icp_result handler_index_cond_check(void* h_arg) return res; } + +/** + Rowid filter callback - to be called by an engine to check rowid / primary + keys of the rows whose data is to be fetched against the used rowid filter +*/ + +extern "C" int handler_rowid_filter_check(void *h_arg) +{ + handler *h= (handler*) h_arg; + TABLE *tab= h->get_table(); + h->position(tab->record[0]); + return h->pushed_rowid_filter->check((char *) h->ref); +} + + +/** + Callback function for an engine to check whether the used rowid filter + has been already built +*/ + +extern "C" int handler_rowid_filter_is_active(void *h_arg) +{ + if (!h_arg) + return false; + handler *h= (handler*) h_arg; + return h->rowid_filter_is_active; +} + + int handler::index_read_idx_map(uchar * buf, uint index, const uchar * key, key_part_map keypart_map, enum ha_rkey_function find_flag) @@ -6230,6 +6250,7 @@ int handler::ha_reset() /* Reset information about pushed engine conditions */ cancel_pushed_idx_cond(); /* Reset information about pushed index conditions */ + cancel_pushed_rowid_filter(); clear_top_table_fields(); DBUG_RETURN(reset()); } diff --git a/sql/handler.h b/sql/handler.h index e5a6deb6659..ee730e8a725 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -47,6 +47,7 @@ class Alter_info; class Virtual_column_info; class sequence_definition; +class Rowid_filter; // the following is for checking tables @@ -324,6 +325,8 @@ enum enum_alter_inplace_result { */ #define HA_CLUSTERED_INDEX 512 +#define HA_DO_RANGE_FILTER_PUSHDOWN 1024 + /* bits in alter_table_flags: */ @@ -2561,11 +2564,14 @@ typedef bool (*SKIP_INDEX_TUPLE_FUNC) (range_seq_t seq, range_id_t range_info); class Cost_estimate { public: - double io_count; /* number of I/O */ - double avg_io_cost; /* cost of an average I/O oper. */ - double cpu_cost; /* cost of operations in CPU */ - double import_cost; /* cost of remote operations */ - double mem_cost; /* cost of used memory */ + double io_count; /* number of I/O to fetch records */ + double avg_io_cost; /* cost of an average I/O oper. to fetch records */ + double idx_io_count; /* number of I/O to read keys */ + double idx_avg_io_cost; /* cost of an average I/O oper. to fetch records */ + double cpu_cost; /* total cost of operations in CPU */ + double idx_cpu_cost; /* cost of operations in CPU for index */ + double import_cost; /* cost of remote operations */ + double mem_cost; /* cost of used memory */ enum { IO_COEFF=1 }; enum { CPU_COEFF=1 }; @@ -2579,10 +2585,18 @@ public: double total_cost() { - return IO_COEFF*io_count*avg_io_cost + CPU_COEFF * cpu_cost + + return IO_COEFF*io_count*avg_io_cost + + IO_COEFF*idx_io_count*idx_avg_io_cost + + CPU_COEFF*cpu_cost + MEM_COEFF*mem_cost + IMPORT_COEFF*import_cost; } + double index_only_cost() + { + return IO_COEFF*idx_io_count*idx_avg_io_cost + + CPU_COEFF*idx_cpu_cost; + } + /** Whether or not all costs in the object are zero @@ -2590,30 +2604,48 @@ public: */ bool is_zero() const { - return io_count == 0.0 && cpu_cost == 0.0 && + return io_count == 0.0 && idx_io_count && cpu_cost == 0.0 && import_cost == 0.0 && mem_cost == 0.0; } void reset() { avg_io_cost= 1.0; - io_count= cpu_cost= mem_cost= import_cost= 0.0; + idx_avg_io_cost= 1.0; + io_count= idx_io_count= cpu_cost= idx_cpu_cost= mem_cost= import_cost= 0.0; } void multiply(double m) { io_count *= m; cpu_cost *= m; + idx_io_count *= m; + idx_cpu_cost *= m; import_cost *= m; /* Don't multiply mem_cost */ } void add(const Cost_estimate* cost) { - double io_count_sum= io_count + cost->io_count; - add_io(cost->io_count, cost->avg_io_cost); - io_count= io_count_sum; + if (cost->io_count) + { + double io_count_sum= io_count + cost->io_count; + avg_io_cost= (io_count * avg_io_cost + + cost->io_count * cost->avg_io_cost) + /io_count_sum; + io_count= io_count_sum; + } + if (cost->idx_io_count) + { + double idx_io_count_sum= idx_io_count + cost->idx_io_count; + idx_avg_io_cost= (idx_io_count * idx_avg_io_cost + + cost->idx_io_count * cost->idx_avg_io_cost) + /idx_io_count_sum; + idx_io_count= idx_io_count_sum; + } cpu_cost += cost->cpu_cost; + idx_cpu_cost += cost->idx_cpu_cost; + import_cost += cost->import_cost; } void add_io(double add_io_cnt, double add_avg_cost) @@ -2790,6 +2822,9 @@ public: extern "C" enum icp_result handler_index_cond_check(void* h_arg); +extern "C" int handler_rowid_filter_check(void* h_arg); +extern "C" int handler_rowid_filter_is_active(void* h_arg); + uint calculate_key_len(TABLE *, uint, const uchar *, key_part_map); /* bitmap with first N+1 bits set @@ -2956,6 +2991,11 @@ public: Item *pushed_idx_cond; uint pushed_idx_cond_keyno; /* The index which the above condition is for */ + /* Rowid filter pushed into the engine */ + Rowid_filter *pushed_rowid_filter; + /* true when the pushed rowid filter has been already filled */ + bool rowid_filter_is_active; + Discrete_interval auto_inc_interval_for_cur_row; /** Number of reserved auto-increment intervals. Serves as a heuristic @@ -3020,6 +3060,8 @@ public: tracker(NULL), pushed_idx_cond(NULL), pushed_idx_cond_keyno(MAX_KEY), + pushed_rowid_filter(NULL), + rowid_filter_is_active(0), auto_inc_intervals_count(0), m_psi(NULL), set_top_table_fields(FALSE), top_table(0), top_table_field(0), top_table_fields(0), @@ -3226,6 +3268,11 @@ public: virtual double scan_time() { return ulonglong2double(stats.data_file_length) / IO_SIZE + 2; } + virtual double key_scan_time(uint index) + { + return keyread_time(index, 1, records()); + } + /** The cost of reading a set of ranges from the table using an index to access it. @@ -3249,8 +3296,6 @@ public: */ virtual double keyread_time(uint index, uint ranges, ha_rows rows); - double get_io_cost(uint index, ha_rows rows, uint *length); - virtual const key_map *keys_to_use_for_scanning() { return &key_map_empty; } /* @@ -4046,6 +4091,14 @@ public: in_range_check_pushed_down= false; } + virtual void cancel_pushed_rowid_filter() + { + pushed_rowid_filter= NULL; + rowid_filter_is_active= false; + } + + virtual bool rowid_filter_push(Rowid_filter *rowid_filter) { return true; } + /* Needed for partition / spider */ virtual TABLE_LIST *get_next_global_for_child() { return NULL; } diff --git a/sql/multi_range_read.cc b/sql/multi_range_read.cc index d6952e71899..cab278f5859 100644 --- a/sql/multi_range_read.cc +++ b/sql/multi_range_read.cc @@ -20,6 +20,12 @@ #include "key.h" #include "sql_statistics.h" +static ulonglong key_block_no(handler *h, uint keyno, uint keyentry_pos) +{ + return (ulonglong) (h->keyread_time(keyno, 1, keyentry_pos + 1) - + h->keyread_time(keyno, 0, keyentry_pos + 1) + 0.5) + 1; +} + /**************************************************************************** * Default MRR implementation (MRR to non-MRR converter) ***************************************************************************/ @@ -47,6 +53,24 @@ for a user to be able to interrupt the calculation by killing the connection/query. + @note + Starting from 10.4 the implementation of this method tries to take into + account gaps between range intervals. Before this we had such paradoxical + cases when, for example, the cost of the index scan by range [1..3] was + almost twice as less than the cost of of the index scan by two intervals + [1..1] and [3..3]. + + @note + The current implementation of the method is not efficient for it + requires extra dives for gaps. Although these dives are not expensive + as they touch the index nodes that with very high probability are in + cache this is still not good. We could avoid it if records in range + also returned positions of the ends of range intervals. It's not + hard to implement it now for MyISAM as this engine provides a function + returning an approximation of the relative position of a key tuple + among other index key tuples. Unfortunately InnoDB now does not provide + anything like this function. + @retval HA_POS_ERROR Error or the engine is unable to perform the requested scan. Values of OUT parameters are undefined. @@ -61,12 +85,21 @@ handler::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, uint *bufsz, uint *flags, Cost_estimate *cost) { KEY_MULTI_RANGE range; + key_range prev_start_key; range_seq_t seq_it; - ha_rows rows, total_rows= 0; + ha_rows min_pos= 0; + ha_rows total_rows= 0; uint n_ranges=0; + uint n_eq_ranges= 0; + ulonglong total_touched_blocks= 0; + key_range *prev_min_endp= 0; + ulonglong prev_max_block_no=0; + ha_rows max_rows= stats.records; THD *thd= table->in_use; - uint limit= thd->variables.eq_range_index_dive_limit; + StringBuffer<64> key_value; + uint limit= thd->variables.eq_range_index_dive_limit; + bool use_statistics_for_eq_range= eq_ranges_exceeds_limit(seq, seq_init_param, limit); @@ -77,10 +110,15 @@ handler::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, seq_it= seq->init(seq_init_param, n_ranges, *flags); while (!seq->next(seq_it, &range)) { + ha_rows rows; + ulonglong new_touched_blocks= 0; + if (unlikely(thd->killed != 0)) return HA_POS_ERROR; n_ranges++; + if (range.range_flag & EQ_RANGE) + n_eq_ranges++; key_range *min_endp, *max_endp; if (range.range_flag & GEOM_FLAG) { @@ -95,38 +133,93 @@ handler::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, max_endp= range.end_key.length? &range.end_key : NULL; } int keyparts_used= my_count_bits(range.start_key.keypart_map); - if ((range.range_flag & UNIQUE_RANGE) && !(range.range_flag & NULL_RANGE)) - rows= 1; /* there can be at most one row */ - else if (use_statistics_for_eq_range && - !(range.range_flag & NULL_RANGE) && - (range.range_flag & EQ_RANGE) && - table->key_info[keyno].actual_rec_per_key(keyparts_used - 1) > 0.5) - rows= - (ha_rows) table->key_info[keyno].actual_rec_per_key(keyparts_used - 1); + if (use_statistics_for_eq_range && + !(range.range_flag & NULL_RANGE) && + (range.range_flag & EQ_RANGE) && + table->key_info[keyno].actual_rec_per_key(keyparts_used - 1) > 0.5) + { + if ((range.range_flag & UNIQUE_RANGE) && !(range.range_flag & NULL_RANGE)) + rows= 1; /* there can be at most one row */ + else + rows= + (ha_rows) table->key_info[keyno].actual_rec_per_key(keyparts_used-1); + } else { - if (HA_POS_ERROR == (rows= this->records_in_range(keyno, min_endp, + ulonglong min_block_no; + ulonglong max_block_no; + if ((range.range_flag & UNIQUE_RANGE) && !(range.range_flag & NULL_RANGE)) + rows= 1; /* there can be at most one row */ + else if (HA_POS_ERROR == (rows= this->records_in_range(keyno, min_endp, max_endp))) { /* Can't scan one range => can't do MRR scan at all */ total_rows= HA_POS_ERROR; break; } + if (!max_endp && !(prev_min_endp && prev_min_endp->length)) + min_pos+= max_rows - rows; + else + { + key_range *start_endp= prev_min_endp; + if (start_endp && !start_endp->keypart_map) + start_endp= 0; + /* + Get the estimate of rows in the previous gap + and two ranges surrounding this gap + */ + ha_rows r= this->records_in_range(keyno,start_endp,max_endp); + if (r == HA_POS_ERROR) + { + /* Some engine cannot estimate such ranges */ + total_rows += rows; + continue; + } + min_pos+= r - rows; + } + min_block_no= key_block_no(this, keyno, min_pos); + max_block_no= key_block_no(this, keyno, min_pos + rows); + new_touched_blocks= max_block_no - min_block_no + + MY_TEST(min_block_no != prev_max_block_no); + prev_max_block_no= max_block_no; + if (!prev_min_endp) + prev_min_endp= &prev_start_key; + /* Save range.start_key for the next iteration step */ + prev_start_key= range.start_key; + key_value.copy((const char *) prev_start_key.key, prev_start_key.length, + key_value.charset()); + prev_start_key.key= (const uchar *) key_value.ptr(); } total_rows += rows; + total_touched_blocks+= new_touched_blocks; } if (total_rows != HA_POS_ERROR) { + set_if_smaller(total_rows, max_rows); /* The following calculation is the same as in multi_range_read_info(): */ *flags |= HA_MRR_USE_DEFAULT_IMPL; cost->reset(); cost->avg_io_cost= 1; /* assume random seeks */ - if ((*flags & HA_MRR_INDEX_ONLY) && total_rows > 2) - cost->io_count= keyread_time(keyno, n_ranges, (uint)total_rows); + cost->idx_avg_io_cost= 1; + if (!(keyno == table->s->primary_key && primary_key_is_clustered())) + { + cost->idx_io_count= total_touched_blocks + + keyread_time(keyno, 0, total_rows); + cost->cpu_cost= cost->idx_cpu_cost= + (double) total_rows / TIME_FOR_COMPARE_IDX + + (2 * n_ranges - n_eq_ranges) * IDX_LOOKUP_COST; + if (!(*flags & HA_MRR_INDEX_ONLY)) + { + cost->io_count= read_time(keyno, 0, total_rows); + cost->cpu_cost+= (double) total_rows / TIME_FOR_COMPARE; + } + } else - cost->io_count= read_time(keyno, n_ranges, total_rows); - cost->cpu_cost= (double) total_rows / TIME_FOR_COMPARE + 0.01; + { + cost->io_count= read_time(keyno, total_touched_blocks, (uint) total_rows); + cost->cpu_cost= (double) total_rows / TIME_FOR_COMPARE + 0.01; + } } return total_rows; } @@ -183,10 +276,22 @@ ha_rows handler::multi_range_read_info(uint keyno, uint n_ranges, uint n_rows, cost->avg_io_cost= 1; /* assume random seeks */ /* Produce the same cost as non-MRR code does */ - if (*flags & HA_MRR_INDEX_ONLY) - cost->io_count= keyread_time(keyno, n_ranges, n_rows); + if (!(keyno == table->s->primary_key && primary_key_is_clustered())) + { + cost->idx_io_count= n_ranges + keyread_time(keyno, 0, n_rows); + cost->cpu_cost= cost->idx_cpu_cost= + (double) n_rows / TIME_FOR_COMPARE_IDX + n_ranges * IDX_LOOKUP_COST; + if (!(*flags & HA_MRR_INDEX_ONLY)) + { + cost->io_count= read_time(keyno, 0, n_rows); + cost->cpu_cost+= (double) n_rows / TIME_FOR_COMPARE; + } + } else - cost->io_count= read_time(keyno, n_ranges, n_rows); + { + cost->io_count= read_time(keyno, n_ranges, (uint)n_rows); + cost->cpu_cost= (double) n_rows / TIME_FOR_COMPARE + 0.01; + } return 0; } diff --git a/sql/opt_range.cc b/sql/opt_range.cc index b9b74bdd0c4..ba2705bab40 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -2520,6 +2520,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, quick=0; needed_reg.clear_all(); quick_keys.clear_all(); + head->with_impossible_ranges.clear_all(); DBUG_ASSERT(!head->is_filled_at_execution()); if (keys_to_use.is_clear_all() || head->is_filled_at_execution()) DBUG_RETURN(0); @@ -2639,8 +2640,8 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, if (!force_quick_range && !head->covering_keys.is_clear_all()) { int key_for_use= find_shortest_key(head, &head->covering_keys); - double key_read_time= head->file->keyread_time(key_for_use, 1, records) + - (double) records / TIME_FOR_COMPARE; + double key_read_time= head->file->key_scan_time(key_for_use) + + (double) records / TIME_FOR_COMPARE_IDX; DBUG_PRINT("info", ("'all'+'using index' scan will be using key %d, " "read time %g", key_for_use, key_read_time)); if (key_read_time < read_time) @@ -4790,6 +4791,7 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge, double roru_index_costs; ha_rows roru_total_records; double roru_intersect_part= 1.0; + double limit_read_time= read_time; size_t n_child_scans; DBUG_ENTER("get_best_disjunct_quick"); DBUG_PRINT("info", ("Full table scan cost: %g", read_time)); @@ -4936,7 +4938,7 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge, if (imerge_trp) { TABLE_READ_PLAN *trp= merge_same_index_scans(param, imerge, imerge_trp, - read_time); + limit_read_time); if (trp != imerge_trp) DBUG_RETURN(trp); } @@ -5409,9 +5411,8 @@ bool prepare_search_best_index_intersect(PARAM *param, same_index_prefix(cpk_scan->key_info, key_info, used_key_parts)) continue; - cost= table->file->keyread_time((*index_scan)->keynr, - (*index_scan)->range_count, - (*index_scan)->records); + cost= table->quick_index_only_costs[(*index_scan)->keynr]; + if (cost >= cutoff_cost) continue; @@ -8556,6 +8557,7 @@ int and_range_trees(RANGE_OPT_PARAM *param, SEL_TREE *tree1, SEL_TREE *tree2, if (key && key->type == SEL_ARG::IMPOSSIBLE) { result->type= SEL_TREE::IMPOSSIBLE; + param->table->with_impossible_ranges.set_bit(param->real_keynr[key_no]); DBUG_RETURN(1); } result_keys.set_bit(key_no); @@ -10541,7 +10543,6 @@ ha_rows check_quick_select(PARAM *param, uint idx, bool index_only, handler *file= param->table->file; ha_rows rows= HA_POS_ERROR; uint keynr= param->real_keynr[idx]; - uint length; DBUG_ENTER("check_quick_select"); /* Handle cases when we don't have a valid non-empty list of range */ @@ -10600,8 +10601,10 @@ ha_rows check_quick_select(PARAM *param, uint idx, bool index_only, MY_MIN(param->table->quick_condition_rows, rows); param->table->quick_rows[keynr]= rows; param->table->quick_costs[keynr]= cost->total_cost(); - param->table->quick_key_io[keynr]= - file->get_io_cost(keynr, param->table->quick_rows[keynr], &length); + if (keynr == param->table->s->primary_key && pk_is_clustered) + param->table->quick_index_only_costs[keynr]= 0; + else + param->table->quick_index_only_costs[keynr]= cost->index_only_cost(); } } /* Figure out if the key scan is ROR (returns rows in ROWID order) or not */ @@ -13656,7 +13659,7 @@ void cost_group_min_max(TABLE* table, KEY *index_info, uint used_key_parts, 1/double(2*TIME_FOR_COMPARE); const double cpu_cost= num_groups * - (tree_traversal_cost + 1/double(TIME_FOR_COMPARE)); + (tree_traversal_cost + 1/double(TIME_FOR_COMPARE_IDX)); *read_cost= io_cost + cpu_cost; *records= num_groups; diff --git a/sql/opt_subselect.h b/sql/opt_subselect.h index 031118288b9..e81b100e2a1 100644 --- a/sql/opt_subselect.h +++ b/sql/opt_subselect.h @@ -303,6 +303,7 @@ public: pos->loosescan_picker.loosescan_parts= best_max_loose_keypart + 1; pos->use_join_buffer= FALSE; pos->table= tab; + pos->range_rowid_filter_info= tab->range_rowid_filter_info; // todo need ref_depend_map ? DBUG_PRINT("info", ("Produced a LooseScan plan, key %s, %s", tab->table->key_info[best_loose_scan_key].name.str, diff --git a/sql/rowid_filter.cc b/sql/rowid_filter.cc index bcca9a0f528..4348eea081d 100644 --- a/sql/rowid_filter.cc +++ b/sql/rowid_filter.cc @@ -1,218 +1,556 @@ +/* + Copyright (c) 2018, 2019 MariaDB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#include "mariadb.h" +#include "table.h" +#include "sql_class.h" +#include "opt_range.h" #include "rowid_filter.h" +#include "sql_select.h" + + +inline +double Range_rowid_filter_cost_info::lookup_cost( + Rowid_filter_container_type cont_type) +{ + switch (cont_type) { + case SORTED_ARRAY_CONTAINER: + return log(est_elements)*0.01; + default: + DBUG_ASSERT(0); + return 0; + } +} /** - Sets information about filter with key_numb index. - It sets a cardinality of filter, calculates its selectivity - and gets slope and interscept values. + @brief + The average gain in cost per row to use the range filter with this cost info */ -void Range_filter_cost_info::init(TABLE *tab, uint key_numb) +inline +double Range_rowid_filter_cost_info::avg_access_and_eval_gain_per_row( + Rowid_filter_container_type cont_type) { - table= tab; - key_no= key_numb; - cardinality= table->quick_rows[key_no]; - b= filter_io_cost() + filter_write_cost() + filter_sort_cost(); - selectivity= cardinality/((double) table->stat_records()); - a= (1 + COST_COND_EVAL)*(1 - selectivity) - lookup_cost(); - intersect_x_axis_abcissa= b/a; + return (1+1.0/TIME_FOR_COMPARE) * (1 - selectivity) - + lookup_cost(cont_type); } - /** @brief - Sort available filters by their building cost in the increasing order + Initialize the cost info structure for a range filter - @details - The method starts sorting available filters from the first filter that - is not defined as the best filter. If there are two filters that are - defined as the best filters there is no need to sort other filters. - Best filters are already sorted by their building cost and have the - smallest bulding cost in comparison with other filters by definition. + @param cont_type The type of the container of the range filter + @param tab The table for which the range filter is evaluated + @param idx The index used to create this range filter +*/ + +void Range_rowid_filter_cost_info::init(Rowid_filter_container_type cont_type, + TABLE *tab, uint idx) +{ + container_type= cont_type; + table= tab; + key_no= idx; + est_elements= table->quick_rows[key_no]; + b= build_cost(container_type); + selectivity= est_elements/((double) table->stat_records()); + a= avg_access_and_eval_gain_per_row(container_type); + if (a > 0) + cross_x= b/a; + abs_independent.clear_all(); +} - As the sorting method bubble sort is used. + +/** + @brief + Return the cost of building a range filter of a certain type */ -void TABLE::sort_range_filter_cost_info_array() +double +Range_rowid_filter_cost_info::build_cost(Rowid_filter_container_type cont_type) { - if (best_filter_count == 2) - return; + double cost= 0; - for (uint i= best_filter_count; i < range_filter_cost_info_elements-1; i++) - { - for (uint j= i+1; j < range_filter_cost_info_elements; j++) - { - if (range_filter_cost_info[i].intersect_x_axis_abcissa > - range_filter_cost_info[j].intersect_x_axis_abcissa) - swap_variables(Range_filter_cost_info, - range_filter_cost_info[i], - range_filter_cost_info[j]); - } + cost+= table->quick_index_only_costs[key_no]; + + switch (cont_type) { + + case SORTED_ARRAY_CONTAINER: + cost+= ARRAY_WRITE_COST * est_elements; /* cost filling the container */ + cost+= ARRAY_SORT_C * est_elements * log(est_elements); /* sorting cost */ + break; + default: + DBUG_ASSERT(0); } + + return cost; +} + + +Rowid_filter_container *Range_rowid_filter_cost_info::create_container() +{ + THD *thd= table->in_use; + uint elem_sz= table->file->ref_length; + Rowid_filter_container *res= 0; + + switch (container_type) { + case SORTED_ARRAY_CONTAINER: + res= new (thd->mem_root) Rowid_filter_sorted_array(est_elements, elem_sz); + break; + default: + DBUG_ASSERT(0); + } + return res; +} + + +static +int compare_range_rowid_filter_cost_info_by_a( + Range_rowid_filter_cost_info **filter_ptr_1, + Range_rowid_filter_cost_info **filter_ptr_2) +{ + double diff= (*filter_ptr_2)->get_a() - (*filter_ptr_1)->get_a(); + return (diff < 0 ? -1 : (diff > 0 ? 1 : 0)); } /** @brief - The method searches for the filters that can reduce the join cost the most + Prepare the array with cost info on range filters to be used by optimizer @details - The method looks through the available filters trying to choose the best - filter and eliminate as many filters as possible. - - Filters are considered as a linear functions. The best filter is the linear - function that intersects all other linear functions not in the I quadrant - and has the biggest a (slope) value. This filter will reduce the partial - join cost the most. If it is possible the second best filter is also - chosen. The second best filter can be used if the ref access is made on - the index of the first best filter. - - So there is no need to store all other filters except filters that - intersect in the I quadrant. It is impossible to say on this step which - filter is better and will give the biggest gain. - - The number of filters that can be used is stored in the - range_filter_cost_info_elements variable. + The function removes the array of cost info on range filters the elements + for those range filters that won't be ever chosen as the best filter, no + matter what index will be used to access the table and at what step the + table will be joined. */ -void TABLE::prune_range_filters() +void TABLE::prune_range_rowid_filters() { - key_map pruned_filter_map; - pruned_filter_map.clear_all(); - Range_filter_cost_info *max_slope_filters[2] = {0, 0}; - - for (uint i= 0; i < range_filter_cost_info_elements; i++) + uint i, j; + + /* + For the elements of the array with cost info on range filters + build a bit matrix of absolutely independent elements. + Two elements are absolutely independent if they such indexes that + there is no other index that overlaps both of them or is constraint + correlated with both of them. Use abs_independent key maps to store + the elements if this bit matrix. + */ + + Range_rowid_filter_cost_info **filter_ptr_1= range_rowid_filter_cost_info_ptr; + for (i= 0; i < range_rowid_filter_cost_info_elems; i++, filter_ptr_1++) { - Range_filter_cost_info *filter= &range_filter_cost_info[i]; - if (filter->a < 0) + uint key_no= (*filter_ptr_1)->key_no; + Range_rowid_filter_cost_info **filter_ptr_2= filter_ptr_1 + 1; + for (j= i+1; j < range_rowid_filter_cost_info_elems; j++, filter_ptr_2++) { - range_filter_cost_info_elements--; - swap_variables(Range_filter_cost_info, range_filter_cost_info[i], - range_filter_cost_info[range_filter_cost_info_elements]); - continue; - } - for (uint j= i+1; j < range_filter_cost_info_elements; j++) - { - Range_filter_cost_info *cand_filter= &range_filter_cost_info[j]; - - double intersect_x= filter->get_intersect_x(cand_filter); - double intersect_y= filter->get_intersect_y(intersect_x); - - if (intersect_x > 0 && intersect_y > 0) + key_map map= key_info[key_no].overlapped; + map.intersect(key_info[(*filter_ptr_2)->key_no].overlapped); + if (map.is_clear_all()) { - pruned_filter_map.set_bit(cand_filter->key_no); - pruned_filter_map.set_bit(filter->key_no); + (*filter_ptr_1)->abs_independent.set_bit((*filter_ptr_2)->key_no); + (*filter_ptr_2)->abs_independent.set_bit(key_no); } } - if (!pruned_filter_map.is_set(filter->key_no)) + } + + /* Sort the array range_filter_cost_info by 'a' in descending order */ + my_qsort(range_rowid_filter_cost_info_ptr, + range_rowid_filter_cost_info_elems, + sizeof(Range_rowid_filter_cost_info *), + (qsort_cmp) compare_range_rowid_filter_cost_info_by_a); + + /* + For each element check whether it is created for the filter that + can be ever chosen as the best one. If it's not the case remove + from the array. Otherwise put it in the array in such a place + that all already checked elements left the array are ordered by + cross_x. + */ + + Range_rowid_filter_cost_info **cand_filter_ptr= + range_rowid_filter_cost_info_ptr; + for (i= 0; i < range_rowid_filter_cost_info_elems; i++, cand_filter_ptr++) + { + bool is_pruned= false; + Range_rowid_filter_cost_info **usable_filter_ptr= + range_rowid_filter_cost_info_ptr; + key_map abs_indep; + abs_indep.clear_all(); + for (uint j= 0; j < i; j++, usable_filter_ptr++) { - if (!max_slope_filters[0]) - max_slope_filters[0]= filter; + if ((*cand_filter_ptr)->cross_x >= (*usable_filter_ptr)->cross_x) + { + if (abs_indep.is_set((*usable_filter_ptr)->key_no)) + { + /* + The following is true here for the element e being checked: + There are at 2 elements e1 and e2 among already selected such that + e1.cross_x < e.cross_x and e1.a > e.a + and + e2.cross_x < e_cross_x and e2.a > e.a, + i.e. the range filters f1, f2 of both e1 and e2 always promise + better gains then the range filter of e. + As e1 and e2 are absolutely independent one of the range filters + f1, f2 will be always a better choice than f no matter what index + is chosen to access the table. Because of this the element e + can be safely removed from the array. + */ + + is_pruned= true; + break; + } + abs_indep.merge((*usable_filter_ptr)->abs_independent); + } else { - if (!max_slope_filters[1] || - max_slope_filters[1]->a < filter->a) - max_slope_filters[1]= filter; - if (max_slope_filters[0]->a < max_slope_filters[1]->a) - swap_variables(Range_filter_cost_info*, max_slope_filters[0], - max_slope_filters[1]); + /* + Move the element being checked to the proper position to have all + elements that have been already checked to be sorted by cross_x + */ + Range_rowid_filter_cost_info *moved= *cand_filter_ptr; + memmove(usable_filter_ptr+1, usable_filter_ptr, + sizeof(Range_rowid_filter_cost_info *) * (i-j-1)); + *usable_filter_ptr= moved; } } - } - - for (uint i= 0; i<2; i++) - { - if (max_slope_filters[i]) + if (is_pruned) { - swap_variables(Range_filter_cost_info, - range_filter_cost_info[i], - *max_slope_filters[i]); - if (i == 0 && - max_slope_filters[1] == &range_filter_cost_info[0]) - max_slope_filters[1]= max_slope_filters[0]; - - best_filter_count++; - max_slope_filters[i]= &range_filter_cost_info[i]; + /* Remove the checked element from the array */ + memmove(cand_filter_ptr, cand_filter_ptr+1, + sizeof(Range_rowid_filter_cost_info *) * + (range_rowid_filter_cost_info_elems - 1 - i)); + range_rowid_filter_cost_info_elems--; } } - sort_range_filter_cost_info_array(); } -void TABLE::select_usable_range_filters(THD *thd) +/** + @brief + Return maximum number of elements that a container allowed to have + */ + +static uint +get_max_range_rowid_filter_elems_for_table( + THD *thd, TABLE *tab, + Rowid_filter_container_type cont_type) +{ + switch (cont_type) { + case SORTED_ARRAY_CONTAINER : + return thd->variables.max_rowid_filter_size/tab->file->ref_length; + default : + DBUG_ASSERT(0); + return 0; + } +} + + +/** + @brief + Prepare info on possible range filters used by optimizer + + @param table The thread handler + + @details + The function first selects the indexes of the table that potentially + can be used for range filters and allocates an array of the objects + of the Range_rowid_filter_cost_info type to store cost info on + possible range filters and an array of pointers to these objects. + The latter is created for easy sorting of the objects with cost info + by different sort criteria. Then the function initializes the allocated + array with cost info for each possible range filter. After this + the function calls the method TABLE::prune_range_rowid_filters(). + The method removes the elements of the array for the filters that + promise less gain then others remaining in the array in any situation + and optimizes the order of the elements for faster choice of the best + range filter. +*/ + +void TABLE::init_cost_info_for_usable_range_rowid_filters(THD *thd) { uint key_no; key_map usable_range_filter_keys; usable_range_filter_keys.clear_all(); key_map::Iterator it(quick_keys); + + /* + From all indexes that can be used for range accesses select only such that + - range filter pushdown is supported by the engine for them (1) + - they are not clustered primary (2) + - the range filter containers for them are not too large (3) + */ while ((key_no= it++) != key_map::Iterator::BITMAP_END) { - if (quick_rows[key_no] > - thd->variables.max_rowid_filter_size/file->ref_length) + if (!(file->index_flags(key_no, 0, 1) & HA_DO_RANGE_FILTER_PUSHDOWN)) // !1 + continue; + if (key_no == s->primary_key && file->primary_key_is_clustered()) // !2 + continue; + if (quick_rows[key_no] > + get_max_range_rowid_filter_elems_for_table(thd, this, + SORTED_ARRAY_CONTAINER)) // !3 continue; usable_range_filter_keys.set_bit(key_no); } - if (usable_range_filter_keys.is_clear_all()) + /* + Allocate an array of objects to store cost info for the selected filters + and allocate an array of pointers to these objects + */ + + range_rowid_filter_cost_info_elems= usable_range_filter_keys.bits_set(); + if (!range_rowid_filter_cost_info_elems) + return; + + range_rowid_filter_cost_info_ptr= + (Range_rowid_filter_cost_info **) + thd->calloc(sizeof(Range_rowid_filter_cost_info *) * + range_rowid_filter_cost_info_elems); + range_rowid_filter_cost_info= + new (thd->mem_root) + Range_rowid_filter_cost_info[range_rowid_filter_cost_info_elems]; + if (!range_rowid_filter_cost_info_ptr || !range_rowid_filter_cost_info) + { + range_rowid_filter_cost_info_elems= 0; return; + } + + /* Fill the allocated array with cost info on the selected range filters */ - range_filter_cost_info_elements= usable_range_filter_keys.bits_set(); - range_filter_cost_info= - new (thd->mem_root) Range_filter_cost_info [range_filter_cost_info_elements]; - Range_filter_cost_info *curr_filter_cost_info= range_filter_cost_info; + Range_rowid_filter_cost_info **curr_ptr= range_rowid_filter_cost_info_ptr; + Range_rowid_filter_cost_info *curr_filter_cost_info= + range_rowid_filter_cost_info; key_map::Iterator li(usable_range_filter_keys); while ((key_no= li++) != key_map::Iterator::BITMAP_END) { - curr_filter_cost_info->init(this, key_no); + *curr_ptr= curr_filter_cost_info; + curr_filter_cost_info->init(SORTED_ARRAY_CONTAINER, this, key_no); + curr_ptr++; curr_filter_cost_info++; } - prune_range_filters(); + + prune_range_rowid_filters(); } -Range_filter_cost_info -*TABLE::best_filter_for_current_join_order(uint ref_key_no, - double record_count, - double records) +/** + @brief + Choose the best range filter for the given access of the table + + @param access_key_no The index by which the table is accessed + @param records The estimated total number of key tuples with this access + + @details + The function looks through the array of cost info for range filters + and chooses the element for the range filter that promise the greatest + gain with the the ref or range access of the table by access_key_no. + As the array is sorted by cross_x in ascending order the function stops + the look through as soon as it reaches the first element with + cross_x > records because the range filter for this element and the + range filters for all remaining elements do not promise positive gains + + @retval Pointer to the cost info for the range filter that promises + the greatest gain, NULL if there is no such range filter +*/ + +Range_rowid_filter_cost_info * +TABLE::best_range_rowid_filter_for_partial_join(uint access_key_no, + double records) { - if (!this || range_filter_cost_info_elements == 0) + if (!this || range_rowid_filter_cost_info_elems == 0 || + covering_keys.is_set(access_key_no)) return 0; - double card= record_count*records; - Range_filter_cost_info *best_filter= &range_filter_cost_info[0]; - - if (card < best_filter->intersect_x_axis_abcissa) + /* + Currently we do not support usage of range filters if the table + is accessed by the clustered primary key. It does not make sense + if a full key is used. If the table is accessed by a partial + clustered primary key it would, but the current InnoDB code does not + allow it. Later this limitation will be lifted + */ + if (access_key_no == s->primary_key && file->primary_key_is_clustered()) return 0; - if (best_filter_count != 0) + + Range_rowid_filter_cost_info *best_filter= 0; + double best_filter_gain= 0; + + key_map *overlapped= &key_info[access_key_no].overlapped; + for (uint i= 0; i < range_rowid_filter_cost_info_elems ; i++) { - if (best_filter->key_no == ref_key_no) + double curr_gain = 0; + Range_rowid_filter_cost_info *filter= range_rowid_filter_cost_info_ptr[i]; + + /* + Do not use a range filter that uses an in index correlated with + the index by which the table is accessed + */ + if ((filter->key_no == access_key_no) || + overlapped->is_set(filter->key_no)) + continue; + + if (records < filter->cross_x) { - if (best_filter_count == 2) - { - best_filter= &range_filter_cost_info[1]; - if (card < best_filter->intersect_x_axis_abcissa) - return 0; - return best_filter; - } + /* Does not make sense to look through the remaining filters */ + break; + } + + curr_gain= filter->get_gain(records); + if (best_filter_gain < curr_gain) + { + best_filter_gain= curr_gain; + best_filter= filter; + } + } + return best_filter; +} + + +/** + @brief + Fill the range rowid filter performing the associated range index scan + + @details + This function performs the range index scan associated with this + range filter and place into the filter the rowids / primary keys + read from key tuples when doing this scan. + @retval + false on success + true otherwise + + @note + The function assumes that the quick select object to perform + the index range scan has been already created. + + @note + Currently the same table handler is used to access the joined table + and to perform range index scan filling the filter. + In the future two different handlers will be used for this + purposes to facilitate a lazy building of the filter. +*/ + +bool Range_rowid_filter::fill() +{ + int rc= 0; + handler *file= table->file; + THD *thd= table->in_use; + QUICK_RANGE_SELECT* quick= (QUICK_RANGE_SELECT*) select->quick; + + uint table_status_save= table->status; + Item *pushed_idx_cond_save= file->pushed_idx_cond; + uint pushed_idx_cond_keyno_save= file->pushed_idx_cond_keyno; + bool in_range_check_pushed_down_save= file->in_range_check_pushed_down; + + table->status= 0; + file->pushed_idx_cond= 0; + file->pushed_idx_cond_keyno= MAX_KEY; + file->in_range_check_pushed_down= false; + + /* We're going to just read rowids / primary keys */ + table->prepare_for_position(); + + table->file->ha_start_keyread(quick->index); + + if (quick->init() || quick->reset()) + rc= 1; + + while (!rc) + { + rc= quick->get_next(); + if (thd->killed) + rc= 1; + if (!rc) + { + file->position(quick->record); + if (container->add(NULL, (char*) file->ref)) + rc= 1; } + } + + quick->range_end(); + table->file->ha_end_keyread(); + + table->status= table_status_save; + file->pushed_idx_cond= pushed_idx_cond_save; + file->pushed_idx_cond_keyno= pushed_idx_cond_keyno_save; + file->in_range_check_pushed_down= in_range_check_pushed_down_save; + + if (rc != HA_ERR_END_OF_FILE) + return 1; + table->file->rowid_filter_is_active= true; + return 0; +} + + +/** + @brief + Binary search in the sorted array of a rowid filter + + @param ctxt context of the search + @parab elem rowid / primary key to look for + + @details + The function looks for the rowid / primary key ' elem' in this container + assuming that ctxt contains a pointer to the TABLE structure created + for the table to whose row elem refers to. + + @retval + true elem is found in the container + false otherwise +*/ + +bool Rowid_filter_sorted_array::check(void *ctxt, char *elem) +{ + TABLE *table= (TABLE *) ctxt; + if (!is_checked) + { + refpos_container.sort(refpos_order_cmp, (void *) (table->file)); + is_checked= true; + } + int l= 0; + int r= refpos_container.elements()-1; + while (l <= r) + { + int m= (l + r) / 2; + int cmp= refpos_order_cmp((void *) (table->file), + refpos_container.get_pos(m), elem); + if (cmp == 0) + return true; + if (cmp < 0) + l= m + 1; else - return best_filter; + r= m-1; } + return false; +} - double best_filter_improvement= 0.0; - best_filter= 0; - for (uint i= best_filter_count; i < range_filter_cost_info_elements; i++) +Range_rowid_filter::~Range_rowid_filter() +{ + delete container; + container= 0; + if (select) { - Range_filter_cost_info *filter= &range_filter_cost_info[i]; - if (card < filter->intersect_x_axis_abcissa) - break; - if (best_filter_improvement < filter->get_filter_gain(card)) + if (select->quick) { - best_filter_improvement= filter->get_filter_gain(card); - best_filter= filter; + delete select->quick; + select->quick= 0; } + delete select; + select= 0; } - return best_filter; } diff --git a/sql/rowid_filter.h b/sql/rowid_filter.h index 0d8520f25c5..3cc2c31555c 100644 --- a/sql/rowid_filter.h +++ b/sql/rowid_filter.h @@ -1,183 +1,451 @@ +/* + Copyright (c) 2018, 2019 MariaDB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + #ifndef ROWID_FILTER_INCLUDED #define ROWID_FILTER_INCLUDED -/** - It makes sense to apply filters for a certain join order when the following - inequality holds: - #T + c4*#T > #T*sel(Fi) + c4*#T*sel(Fi) + - I/O(Fi) + c1*#(Fi) + c2*#(Fi)*log(#(Fi)) + - c3*#T (1), +#include "mariadb.h" +#include "sql_array.h" + +/* + + What rowid / primary filters are + -------------------------------- + + Consider a join query Q of the form + SELECT * FROM T1, ... , Tk WHERE P. + + For any of the table reference Ti(Q) from the from clause of Q different + rowid / primary key filters (pk-filters for short) can be built. + A pk-filter F built for Ti(Q) is a set of rowids / primary keys of Ti + F= {pk1,...,pkN} such that for any row r=r1||...||rk from the result set of Q + ri's rowid / primary key pk(ri) is contained in F. + + When pk-filters are useful + -------------------------- + + If building a pk-filter F for Ti(Q )is not too costly and its cardinality #F + is much less than the cardinality of T - #T then using the pk-filter when + executing Q might be quite beneficial. + + Let r be a random row from Ti. Let s(F) be the probability that pk(r) + belongs to F. Let BC(F) be the cost of building F. + + Suppose that the optimizer has chosen for Q a plan with this join order + T1 => ... Tk and that the table Ti is accessed by a ref access using index I. + Let K = {k1,...,kM} be the set of all rowid/primary keys values used to access + rows of Ti when looking for matches in this table.to join Ti by index I. + + Let's assume that two set sets K and F are uncorrelated. With this assumption + if before accessing data from Ti by the rowid / primary key k we first + check whether k is in F then we can expect saving on M*(1-s(S)) accesses of + data rows from Ti. If we can guarantee that test whether k is in F is + relatively cheap then we can gain a lot assuming that BC(F) is much less + then the cost of fetching M*(1-s(S)) records from Ti and following + evaluation of conditions pushed into Ti. + + Making pk-filter test cheap + --------------------------- + + If the search structure to test whether an element is in F can be fully + placed in RAM then this test is expected to be be much cheaper than a random + access of a record from Ti. We'll consider two search structures for + pk-filters: ordered array and bloom filter. Ordered array is easy to + implement, but it's space consuming. If a filter contains primary keys + then at least space for each primary key from the filter must be allocated + in the search structure. On a the opposite a bloom filter requires a + fixed number of bits and this number does not depend on the cardinality + of the pk-filter (10 bits per element will serve pk-filter of any size). - where #T - the fanout of the partial join - Fi - a filter for the index with the number i in - the key_map of available indexes for this table - sel(Fi) - the selectivity of the index with the number - i - c4*#T, - c4*#T*sel(Fi) - a cost to apply available predicates - c4 - a constant to apply available predicates - I/O(Fi) - a cost of the I/O accesses to Fi - #(Fi) - a number of estimated records that range - access would use - c1*#(Fi) - a cost to write in Fi - c1 - a constant to write one element in Fi - c2*#(Fi)*log(#(Fi)) - a cost to sort in Fi - c2 - a sorting constant - c3*(#T) - a cost to look-up into a current partial join - c3 - a constant to look-up into Fi +*/ - Let's set a new variable FBCi (filter building cost for the filter with - index i): +/* + + How and when the optimizer builds and uses range rowid filters + -------------------------------------------------------------- + + 1. In make_join_statistics() + for each join table s + after the call of get_quick_record_count() + the TABLE::method init_cost_info_for_usable_range_rowid_filters() + is called + The method build an array of Range_rowid_filter_cost_info elements + containing the cost info on possible range filters for s->table. + The array is optimized for further usage. + + 2. For each partial join order when the optimizer considers joining + table s to this partial join + In the function best_access_path() + a. When evaluating a ref access r by index idx to join s + the optimizer estimates the effect of usage of each possible + range filter f and chooses one with the best gain. The gain + is taken into account when the cost of thr ref access r is + calculated. If it turns out that this is the best ref access + to join s then the info about the chosen filter together + with the info on r is remembered in the corresponding element + of the array of POSITION structures. + [We evaluate every pair (ref access, range_filter) rather then + every pair (best ref access, range filter) because if the index + ref_idx used for ref access r correlates with the index rf_idx + used by the filter f then the pair (r,f) is not evaluated + at all as we don't know how to estimate the effect of correlation + between ref_idx and rf_idx.] + b. When evaluating the best range access to join table s the + optimizer estimates the effect of usage of each possible + range filter f and chooses one with the best gain. + [Here we should have evaluated every pair (range access, + range filter) as well, but it's not done yet.] + + 3. When the cheapest execution plan has been chosen and after the + call of JOIN::get_best_combination() + The method JOIN::make_range_rowid_filters() is called + For each range rowid filter used in the chosen execution plan + the method creates a quick select object to be able to perform + index range scan to fill the filter at the execution stage. + The method also creates Range_rowid_filter objects that are + used at the execution stage. + + 4. Just before the execution stage + The method JOIN::init_range_rowid_filters() is called. + For each join table s that is to be accessed with usage of a range + filter the method allocates containers for the range filter and + it lets the engine know that the filter will be used when + accessing s. + + 5. At the execution stage + In the function sub_select() just before the first access of a join + table s employing a range filter + The method JOIN_TAB::build_range_rowid_filter_if_needed() is called + The method fills the filter using the quick select created by + JOIN::make_range_rowid_filters(). + + 6. The accessed key tuples are checked against the filter within the engine + using the info pushed into it. - FBCi = I/O(Fi) + c1*#(Fi) + c2*#(Fi)*log(#(Fi)) +*/ - It can be seen that FBCi doesn't depend on #T. +class TABLE; +class SQL_SELECT; +class Rowid_filter_container; +class Range_rowid_filter_cost_info; - So using this variable (1) can be rewritten: +/* Cost to write rowid into array */ +#define ARRAY_WRITE_COST 0.005 +/* Factor used to calculate cost of sorting rowids in array */ +#define ARRAY_SORT_C 0.01 +/* Cost to evaluate condition */ +#define COST_COND_EVAL 0.2 - #T + c4*#T > #T*sel(Fi) + c4*#T*sel(Fi) + - FBCi + - c3*#T +typedef enum +{ + SORTED_ARRAY_CONTAINER, + BLOOM_FILTER_CONTAINER +} Rowid_filter_container_type; - To get a possible cost improvement when a filter is used right part - of the (1) inequality should be deducted from the left part. - Denote it as G(#T): +/** + @class Rowid_filter_container - G(#T)= #T + c4*#T - (#T*sel(Fi) + c4*#T*sel(Fi) + FBCi + c3*#T) (2) + The interface for different types of containers to store info on the set + of rowids / primary keys that defines a pk-filter. - On the prepare stage when filters are created #T value isn't known. + There will be two implementations of this abstract class. + - sorted array + - bloom filter +*/ - To find out what filter is the best among available one for the table - (what filter gives the biggest gain) a knowledge about linear functions - can be used. Consider filter gain as a linear function: +class Rowid_filter_container : public Sql_alloc +{ +public: - Gi(#T)= ai*#T + bi (3) + virtual Rowid_filter_container_type get_type() = 0; - where ai= 1+c4-c3-sel(Fi)*(1+c4), - bi= -FBCi + /* Allocate memory for the container */ + virtual bool alloc() = 0; - Filter gain can be interpreted as an ordinate, #T as abscissa. + /* + @brief Add info on a rowid / primary to the container + @param ctxt The context info (opaque) + @param elem The rowid / primary key to be added to the container + @retval true if elem is successfully added + */ + virtual bool add(void *ctxt, char *elem) = 0; - So the aim is to find the linear function that has the biggest ordinate value - for each positive abscissa (because #T can't be negative) comparing with - the other available functions. + /* + @brief Check whether a rowid / primary key is in container + @param ctxt The context info (opaque) + @param elem The rowid / primary key to be checked against the container + @retval False if elem is definitely not in the container + */ + virtual bool check(void *ctxt, char *elem) = 0; - Consider two filters Fi, Fj or linear functions with a positive slope. - To find out which linear function is better let's find their intersection - point coordinates. + virtual ~Rowid_filter_container() {} +}; - Gi(#T0)= Gj(#T0) (using (2))=> - #T0= (bj - bi)/(ai - aj) (using (3)) - => - #T0= (BCFj-BCFi)/((sel(Fj)-sel(Fi))*(1+c4)) - If put #T0 value into the (3) formula G(#T0) can be easily found. +/** + @class Rowid_filter - It can be seen that if two linear functions intersect in II, III or IV - quadrants the linear function with a bigger slope value will always - be better. + The interface for different types of pk-filters - If two functions intersect in the I quadrant for #T1 < #T0 a function - with a smaller slope value will give a better gain and when #T1 > #T0 - function with a bigger slope will give better gain. + Currently we support only range pk filters. +*/ - for each #T1 > #T0 if (ai > aj) => (Gi(#T1) >= Gj(#T1)) - #T1 <= #T0 if (ai > aj) => (Gi(#T1) <= Gj(#T1)) +class Rowid_filter : public Sql_alloc +{ +protected: - So both linear functions should be saved. + /* The container to store info the set of elements in the filter */ + Rowid_filter_container *container; - Interesting cases: +public: + Rowid_filter(Rowid_filter_container *container_arg) + : container(container_arg) {} - 1. For Fi,Fj filters ai=aj. + /* + Build the filter : + fill it with info on the set of elements placed there + */ + virtual bool build() = 0; - In this case intercepts bi and bj should be compared. - The filter with the biggest intercept will give a better result. + /* + Check whether an element is in the filter. + Returns false is the elements is definitely not in the filter. + */ + virtual bool check(char *elem) = 0; - 2. Only one filter remains after the calculations and for some join order - it is equal to the index that is used to access table. Therefore, this - filter can't be used. - - In this case the gain is computed for every filter that can be constructed - for this table. + virtual ~Rowid_filter() {} - After information about filters is computed for each partial join order - it is checked if the filter can be applied to the current table. - If it gives a cost improvement it is saved as the best plan for this - partial join. -*/ + Rowid_filter_container *get_container() { return container; } +}; -#include "mariadb.h" -#include "sql_class.h" -#include "table.h" -/* Cost to write into filter */ -#define COST_WRITE 0.01 -/* Weight factor for filter sorting */ -#define CNST_SORT 0.01 -/* Cost to evaluate condition */ -#define COST_COND_EVAL 0.2 +/** + @class Rowid_filter_container -class QUICK_RANGE_SELECT; + The implementation of the Rowid_interface used for pk-filters + that are filled when performing range index scans. +*/ -class Range_filter_cost_info : public Sql_alloc +class Range_rowid_filter: public Rowid_filter { -public: + /* The table for which the rowid filter is built */ TABLE *table; - uint key_no; - double cardinality; - double b; // intercept of the linear function - double a; // slope of the linear function - double selectivity; - double intersect_x_axis_abcissa; + /* The select to perform the range scan to fill the filter */ + SQL_SELECT *select; + /* The cost info on the filter (used for EXPLAIN/ANALYZE) */ + Range_rowid_filter_cost_info *cost_info; + +public: + Range_rowid_filter(TABLE *tab, + Range_rowid_filter_cost_info *cost_arg, + Rowid_filter_container *container_arg, + SQL_SELECT *sel) + : Rowid_filter(container_arg), table(tab), select(sel), cost_info(cost_arg) + {} + + ~Range_rowid_filter(); + + bool build() { return fill(); } - /** - Filter cost functions + bool check(char *elem) { return container->check(table, elem); } + + bool fill(); + + SQL_SELECT *get_select() { return select; } +}; + + +/** + @class Refpos_container_sorted_array + + The wrapper class over Dynamic_array<char> to facilitate operations over + array of elements of the type char[N] where N is the same for all elements +*/ + +class Refpos_container_sorted_array : public Sql_alloc +{ + /* + Maximum number of elements in the array + (Now is used only at the initialization of the dynamic array) */ - /* Cost to lookup into filter */ - inline double lookup_cost() + uint max_elements; + /* Number of bytes allocated for an element */ + uint elem_size; + /* The dynamic array over which the wrapper is built */ + Dynamic_array<char> *array; + +public: + + Refpos_container_sorted_array(uint max_elems, uint elem_sz) + : max_elements(max_elems), elem_size(elem_sz), array(0) {} + + ~Refpos_container_sorted_array() { - return log(cardinality)*0.01; + delete array; + array= 0; } - /* IO accesses cost to access filter */ - inline double filter_io_cost() - { return table->quick_key_io[key_no]; } + bool alloc() + { + array= new Dynamic_array<char> (elem_size * max_elements, + elem_size * max_elements/sizeof(char) + 1); + return array == NULL; + } - /* Cost to write elements in filter */ - inline double filter_write_cost() - { return COST_WRITE*cardinality; } + bool add(char *elem) + { + for (uint i= 0; i < elem_size; i++) + { + if (array->append(elem[i])) + return true; + } + return false; + } - /* Cost to sort elements in filter */ - inline double filter_sort_cost() - { - return CNST_SORT*cardinality*log(cardinality); + char *get_pos(uint n) + { + return array->get_pos(n * elem_size); } - /* End of filter cost functions */ - Range_filter_cost_info() : table(0), key_no(0) {} + uint elements() { return array->elements() / elem_size; } + + void sort (int (*cmp) (void *ctxt, const void *el1, const void *el2), + void *cmp_arg) + { + my_qsort2(array->front(), array->elements()/elem_size, + elem_size, (qsort2_cmp) cmp, cmp_arg); + } +}; + + +/** + @class Rowid_filter_sorted_array + + The implementation of the Rowid_filter_container interface as + a sorted array container of rowids / primary keys +*/ + +class Rowid_filter_sorted_array: public Rowid_filter_container +{ + /* The dynamic array to store rowids / primary keys */ + Refpos_container_sorted_array refpos_container; + /* Initially false, becomes true after the first call of (check() */ + bool is_checked; + +public: + Rowid_filter_sorted_array(uint elems, uint elem_size) + : refpos_container(elems, elem_size), is_checked(false) {} + + Rowid_filter_container_type get_type() + { return SORTED_ARRAY_CONTAINER; } + + bool alloc() { return refpos_container.alloc(); } + + bool add(void *ctxt, char *elem) { return refpos_container.add(elem); } + + bool check(void *ctxt, char *elem); +}; + +/** + @class Range_rowid_filter_cost_info + + An objects of this class is created for each potentially usable + range filter. It contains the info that allows to figure out + whether usage of the range filter promises some gain. +*/ + +class Range_rowid_filter_cost_info : public Sql_alloc +{ + /* The table for which the range filter is to be built (if needed) */ + TABLE *table; + /* Estimated number of elements in the filter */ + double est_elements; + /* The cost of building the range filter */ + double b; + /* + a*N-b yields the gain of the filter + for N key tuples of the index key_no + */ + double a; + /* The value of N where the gain is 0 */ + double cross_x; + /* Used for pruning of the potential range filters */ + key_map abs_independent; + +public: + /* The type of the container of the range filter */ + Rowid_filter_container_type container_type; + /* The index whose range scan would be used to build the range filter */ + uint key_no; + /* The selectivity of the range filter */ + double selectivity; + + Range_rowid_filter_cost_info() : table(0), key_no(0) {} - void init(TABLE *tab, uint key_numb); + void init(Rowid_filter_container_type cont_type, + TABLE *tab, uint key_no); - inline double get_intersect_x(Range_filter_cost_info *filter) + double build_cost(Rowid_filter_container_type container_type); + + inline double lookup_cost(Rowid_filter_container_type cont_type); + + inline double + avg_access_and_eval_gain_per_row(Rowid_filter_container_type cont_type); + + /* Get the gain that usage of filter promises for 'rows' key tuples */ + inline double get_gain(double rows) { - if (a == filter->a) - return DBL_MAX; - return (b - filter->b)/(a - filter->a); + return rows * a - b; } - inline double get_intersect_y(double intersect_x) + + /* + The gain promised by usage of the filter at the assumption that + when the table is accessed without the filter at most worst_seeks + pages are fetched from disk to access the data rows of the table + */ + inline double get_adjusted_gain(double rows, double worst_seeks) { - if (intersect_x == DBL_MAX) - return DBL_MAX; - return intersect_x*a - b; + return get_gain(rows) - + (1 - selectivity) * (rows - MY_MIN(rows, worst_seeks)); } - /** - Get a gain that a usage of filter in some partial join order - with the cardinaly card gives + /* + The gain promised by usage of the filter + due to less condition evaluations */ - inline double get_filter_gain(double card) - { return card*a - b; } + inline double get_cmp_gain(double rows) + { + return rows * (1 - selectivity) / TIME_FOR_COMPARE; + } + + Rowid_filter_container *create_container(); + + double get_a() { return a; } + + friend + void TABLE::prune_range_rowid_filters(); + + friend + void TABLE::init_cost_info_for_usable_range_rowid_filters(THD *thd); + + friend + Range_rowid_filter_cost_info * + TABLE::best_range_rowid_filter_for_partial_join(uint access_key_no, + double records); }; #endif /* ROWID_FILTER_INCLUDED */ diff --git a/sql/sql_array.h b/sql/sql_array.h index 0e5246b7e2a..4a49ade5576 100644 --- a/sql/sql_array.h +++ b/sql/sql_array.h @@ -166,6 +166,19 @@ public: return ((const Elem*)array.buffer) + array.elements - 1; } + /// @returns pointer to n-th element + Elem *get_pos(size_t idx) + { + return ((Elem*)array.buffer) + idx; + } + + /// @returns pointer to n-th element + const Elem *get_pos(size_t idx) const + { + return ((const Elem*)array.buffer) + idx; + } + + /** @retval false ok @retval true OOM, @c my_error() has been called. diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 0dd82351719..eae7d988772 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -2673,7 +2673,7 @@ void THD::make_explain_field_list(List<Item> &field_list, uint8 explain_flags, mem_root); item->maybe_null=1; field_list.push_back(item=new (mem_root) - Item_empty_string(this, "ref|filter", + Item_empty_string(this, "ref", NAME_CHAR_LEN*MAX_REF_PARTS, cs), mem_root); item->maybe_null=1; diff --git a/sql/sql_const.h b/sql/sql_const.h index be26de872df..e6dcc3420cf 100644 --- a/sql/sql_const.h +++ b/sql/sql_const.h @@ -194,7 +194,11 @@ instead of reading with keys. The number says how many evaluation of the WHERE clause is comparable to reading one extra row from a table. */ -#define TIME_FOR_COMPARE 5 // 5 compares == one read +#define TIME_FOR_COMPARE 5 // 5 compares == one read +#define TIME_FOR_COMPARE_IDX 20 + +#define IDX_BLOCK_COPY_COST ((double) 1 / TIME_FOR_COMPARE) +#define IDX_LOOKUP_COST ((double) 1 / 8) /** Number of comparisons of table rowids equivalent to reading one row from a diff --git a/sql/sql_explain.cc b/sql/sql_explain.cc index 23bc1e906a0..c7c6f15f7cc 100644 --- a/sql/sql_explain.cc +++ b/sql/sql_explain.cc @@ -380,11 +380,13 @@ int print_explain_row(select_result_sink *result, item_list.push_back(item, mem_root); /* 'rows' */ + StringBuffer<64> rows_str; if (rows) { + rows_str.append_ulonglong((ulonglong)(*rows)); item_list.push_back(new (mem_root) - Item_int(thd, *rows, MY_INT64_NUM_DECIMAL_DIGITS), - mem_root); + Item_string_sys(thd, rows_str.ptr(), + rows_str.length()), mem_root); } else item_list.push_back(item_null, mem_root); @@ -1113,12 +1115,14 @@ void Explain_table_access::fill_key_str(String *key_str, bool is_json) const - this is just used key length for ref/range - for index_merge, it is a comma-separated list of lengths. - for hash join, it is key_len:pseudo_key_len + - [tabular form only] rowid filter length is added after "|". - The column looks identical in tabular and json forms. In JSON, we consider - the column legacy, it is superceded by used_key_parts. + In JSON, we consider this column to be legacy, it is superceded by + used_key_parts. */ -void Explain_table_access::fill_key_len_str(String *key_len_str) const +void Explain_table_access::fill_key_len_str(String *key_len_str, + bool is_json) const { bool is_hj= (type == JT_HASH || type == JT_HASH_NEXT || type == JT_HASH_RANGE || type == JT_HASH_INDEX_MERGE); @@ -1147,13 +1151,12 @@ void Explain_table_access::fill_key_len_str(String *key_len_str) const key_len_str->append(buf, length); } - if (key.get_filter_key_length() != (uint)-1) + if (!is_json && rowid_filter) { - char buf[64]; - size_t length; - key_len_str->append(','); - length= longlong10_to_str(key.get_filter_key_length(), buf, 10) - buf; - key_len_str->append(buf, length); + key_len_str->append('|'); + StringBuffer<64> filter_key_len; + rowid_filter->quick->print_key_len(&filter_key_len); + key_len_str->append(filter_key_len); } } @@ -1240,7 +1243,18 @@ int Explain_table_access::print_explain(select_result_sink *output, uint8 explai } /* `type` column */ - push_str(thd, &item_list, join_type_str[type]); + StringBuffer<64> join_type_buf; + if (rowid_filter == NULL) + push_str(thd, &item_list, join_type_str[type]); + else + { + join_type_buf.append(join_type_str[type]); + join_type_buf.append("|filter"); + item_list.push_back(new (mem_root) + Item_string_sys(thd, join_type_buf.ptr(), + join_type_buf.length()), + mem_root); + } /* `possible_keys` column */ StringBuffer<64> possible_keys_buf; @@ -1252,6 +1266,14 @@ int Explain_table_access::print_explain(select_result_sink *output, uint8 explai /* `key` */ StringBuffer<64> key_str; fill_key_str(&key_str, false); + + if (rowid_filter) + { + key_str.append("|"); + StringBuffer<64> rowid_key_str; + rowid_filter->quick->print_key(&rowid_key_str); + key_str.append(rowid_key_str); + } if (key_str.length() > 0) push_string(thd, &item_list, &key_str); @@ -1260,7 +1282,7 @@ int Explain_table_access::print_explain(select_result_sink *output, uint8 explai /* `key_len` */ StringBuffer<64> key_len_str; - fill_key_len_str(&key_len_str); + fill_key_len_str(&key_len_str, false); if (key_len_str.length() > 0) push_string(thd, &item_list, &key_len_str); @@ -1288,10 +1310,10 @@ int Explain_table_access::print_explain(select_result_sink *output, uint8 explai { rows_str.append_ulonglong((ulonglong)rows); - if (is_filter_set()) + if (rowid_filter) { rows_str.append(" ("); - rows_str.append_ulonglong(filter_perc); + rows_str.append_ulonglong(round(rowid_filter->selectivity * 100.0)); rows_str.append("%)"); } item_list.push_back(new (mem_root) @@ -1376,7 +1398,7 @@ int Explain_table_access::print_explain(select_result_sink *output, uint8 explai extra_buf.append(STRING_WITH_LEN("Using filesort")); } - if (is_filter_set()) + if (rowid_filter) { if (first) first= false; @@ -1573,6 +1595,19 @@ void add_json_keyset(Json_writer *writer, const char *elem_name, } +void Explain_rowid_filter::print_explain_json(Explain_query *query, + Json_writer *writer, + bool is_analyze) +{ + Json_writer_nesting_guard guard(writer); + writer->add_member("rowid_filter").start_object(); + quick->print_json(writer); + writer->add_member("rows").add_ll(rows); + writer->add_member("selectivity_pct").add_double(selectivity * 100.0); + writer->end_object(); // rowid_filter +} + + void Explain_table_access::print_explain_json(Explain_query *query, Json_writer *writer, bool is_analyze) @@ -1645,7 +1680,7 @@ void Explain_table_access::print_explain_json(Explain_query *query, /* `key_length` */ StringBuffer<64> key_len_str; - fill_key_len_str(&key_len_str); + fill_key_len_str(&key_len_str, true); if (key_len_str.length()) writer->add_member("key_length").add_str(key_len_str); @@ -1670,6 +1705,11 @@ void Explain_table_access::print_explain_json(Explain_query *query, if (!ref_list.is_empty()) print_json_array(writer, "ref", ref_list); + if (rowid_filter) + { + rowid_filter->print_explain_json(query, writer, is_analyze); + } + /* r_loops (not present in tabular output) */ if (is_analyze) { diff --git a/sql/sql_explain.h b/sql/sql_explain.h index 71f90477977..a161f6c1049 100644 --- a/sql/sql_explain.h +++ b/sql/sql_explain.h @@ -583,7 +583,8 @@ class Explain_index_use : public Sql_alloc { char *key_name; uint key_len; - uint key_len_for_filter; + char *filter_name; + uint filter_len; public: String_list key_parts_list; @@ -596,16 +597,43 @@ public: { key_name= NULL; key_len= (uint)-1; - key_len_for_filter= (uint)-1; + filter_name= NULL; + filter_len= (uint)-1; } bool set(MEM_ROOT *root, KEY *key_name, uint key_len_arg); bool set_pseudo_key(MEM_ROOT *root, const char *key_name); - void set_filter_key_length(uint key_length_arg) - { key_len_for_filter= key_length_arg; } inline const char *get_key_name() const { return key_name; } inline uint get_key_len() const { return key_len; } - inline uint get_filter_key_length() const { return key_len_for_filter; } + //inline const char *get_filter_name() const { return filter_name; } +}; + + +/* + Query Plan data structure for Rowid filter. +*/ +class Explain_rowid_filter : public Sql_alloc +{ +public: + /* Quick select used to collect the rowids into filter */ + Explain_quick_select *quick; + + /* How many rows the above quick select is expected to return */ + ha_rows rows; + + /* Expected selectivity for the filter */ + double selectivity; + + void print_explain_json(Explain_query *query, Json_writer *writer, + bool is_analyze); + + /* + TODO: + Here should be ANALYZE members: + - r_rows for the quick select + - An object that tracked the table access time + - real selectivity of the filter. + */ }; @@ -675,6 +703,7 @@ public: void print_json(Json_writer *writer, bool is_analyze); }; + /* EXPLAIN data structure for a single JOIN_TAB. */ @@ -695,7 +724,7 @@ public: pushed_index_cond(NULL), sjm_nest(NULL), pre_join_sort(NULL), - filter_perc(UINT_MAX) + rowid_filter(NULL) {} ~Explain_table_access() { delete sjm_nest; } @@ -802,12 +831,7 @@ public: Exec_time_tracker op_tracker; Table_access_tracker jbuf_tracker; - /** - How many rows are left after the filter was applied - to the initial rows count in percentages. - */ - double filter_perc; - inline bool is_filter_set() const { return (filter_perc != UINT_MAX); } + Explain_rowid_filter *rowid_filter; int print_explain(select_result_sink *output, uint8 explain_flags, bool is_analyze, @@ -819,7 +843,7 @@ public: private: void append_tag_name(String *str, enum explain_extra_tag tag); void fill_key_str(String *key_str, bool is_json) const; - void fill_key_len_str(String *key_len_str) const; + void fill_key_len_str(String *key_len_str, bool is_json) const; double get_r_filtered(); void tag_to_json(Json_writer *writer, enum explain_extra_tag tag); }; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 8f55497d8d0..b5b77c2c43b 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -101,6 +101,9 @@ static int sort_keyuse(KEYUSE *a,KEYUSE *b); static bool are_tables_local(JOIN_TAB *jtab, table_map used_tables); static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse, bool allow_full_scan, table_map used_tables); +static ha_rows get_quick_record_count(THD *thd, SQL_SELECT *select, + TABLE *table, + const key_map *keys,ha_rows limit); void best_access_path(JOIN *join, JOIN_TAB *s, table_map remaining_tables, uint idx, bool disable_jbuf, double record_count, @@ -1462,6 +1465,116 @@ int JOIN::optimize() } +/** + @brief + Create range filters objects needed in execution for all join tables + + @details + For each join table from the chosen execution plan such that a range filter + is used when joining this table the function creates a Rowid_filter object + for this range filter. In order to do this the function first constructs + a quick select to scan the range for this range filter. Then it creates + a container for the range filter and finally constructs a Range_rowid_filter + object a pointer to which is set in the field JOIN_TAB::rowid_filter of + the joined table. + + @retval false always +*/ + +bool JOIN::make_range_rowid_filters() +{ + DBUG_ENTER("make_range_rowid_filters"); + + JOIN_TAB *tab; + + for (tab= first_linear_tab(this, WITH_BUSH_ROOTS, WITHOUT_CONST_TABLES); + tab; + tab= next_linear_tab(this, tab, WITH_BUSH_ROOTS)) + { + if (!tab->range_rowid_filter_info) + continue; + int err; + SQL_SELECT *sel= NULL; + Rowid_filter_container *filter_container= NULL; + Item **sargable_cond= get_sargable_cond(this, tab->table); + sel= make_select(tab->table, const_table_map, const_table_map, + *sargable_cond, (SORT_INFO*) 0, 1, &err); + if (!sel) + continue; + + key_map filter_map; + filter_map.clear_all(); + filter_map.set_bit(tab->range_rowid_filter_info->key_no); + filter_map.merge(tab->table->with_impossible_ranges); + bool force_index_save= tab->table->force_index; + tab->table->force_index= true; + (void) sel->test_quick_select(thd, filter_map, (table_map) 0, + (ha_rows) HA_POS_ERROR, + true, false, true); + tab->table->force_index= force_index_save; + if (thd->is_error()) + goto no_filter; + DBUG_ASSERT(sel->quick); + filter_container= + tab->range_rowid_filter_info->create_container(); + if (filter_container) + { + tab->rowid_filter= + new (thd->mem_root) Range_rowid_filter(tab->table, + tab->range_rowid_filter_info, + filter_container, sel); + if (tab->rowid_filter) + continue; + } + no_filter: + if (sel->quick) + delete sel->quick; + delete sel; + } + + DBUG_RETURN(0); +} + + +/** + @brief + Allocate memory the rowid containers of the used the range filters + + @details + For each join table from the chosen execution plan such that a range filter + is used when joining this table the function allocate memory for the + rowid container employed by the filter. On success it lets the table engine + know that what rowid filter will be used when accessing the table rows. + + @retval false always +*/ + +bool +JOIN::init_range_rowid_filters() +{ + DBUG_ENTER("init_range_rowid_filters"); + + JOIN_TAB *tab; + + for (tab= first_linear_tab(this, WITH_BUSH_ROOTS, WITHOUT_CONST_TABLES); + tab; + tab= next_linear_tab(this, tab, WITH_BUSH_ROOTS)) + { + if (!tab->rowid_filter) + continue; + if (tab->rowid_filter->get_container()->alloc()) + { + delete tab->rowid_filter; + tab->rowid_filter= 0; + continue; + } + tab->table->file->rowid_filter_push(tab->rowid_filter); + tab->is_rowid_filter_built= false; + } + DBUG_RETURN(0); +} + + int JOIN::init_join_caches() { JOIN_TAB *tab; @@ -1980,6 +2093,9 @@ int JOIN::optimize_stage2() if (get_best_combination()) DBUG_RETURN(1); + if (make_range_rowid_filters()) + DBUG_RETURN(1); + if (select_lex->handle_derived(thd->lex, DT_OPTIMIZE)) DBUG_RETURN(1); @@ -2644,6 +2760,9 @@ int JOIN::optimize_stage2() if (init_join_caches()) DBUG_RETURN(1); + if (init_range_rowid_filters()) + DBUG_RETURN(1); + error= 0; if (select_options & SELECT_DESCRIBE) @@ -5035,9 +5154,8 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list, select->quick=0; impossible_range= records == 0 && s->table->reginfo.impossible_range; if (join->thd->lex->sql_command == SQLCOM_SELECT && - join->table_count > 1 && optimizer_flag(join->thd, OPTIMIZER_SWITCH_USE_ROWID_FILTER)) - s->table->select_usable_range_filters(join->thd); + s->table->init_cost_info_for_usable_range_rowid_filters(join->thd); } if (!impossible_range) { @@ -6843,14 +6961,14 @@ best_access_path(JOIN *join, double best_time= DBL_MAX; double records= DBL_MAX; table_map best_ref_depends_map= 0; - Range_filter_cost_info *best_filter= 0; + Range_rowid_filter_cost_info *best_filter= 0; double tmp; ha_rows rec; bool best_uses_jbuf= FALSE; MY_BITMAP *eq_join_set= &s->table->eq_join_set; KEYUSE *hj_start_key= 0; SplM_plan_info *spl_plan= 0; - Range_filter_cost_info *filter= 0; + Range_rowid_filter_cost_info *filter= 0; disable_jbuf= disable_jbuf || idx == join->const_tables; @@ -7243,11 +7361,18 @@ best_access_path(JOIN *join, loose_scan_opt.check_ref_access_part2(key, start_key, records, tmp); } /* not ft_key */ - filter= table->best_filter_for_current_join_order(start_key->key, - records, - record_count); - if (filter && (filter->get_filter_gain(record_count*records) < tmp)) - tmp= tmp - filter->get_filter_gain(record_count*records); + if (records < DBL_MAX) + { + double rows= record_count * records; + filter= + table->best_range_rowid_filter_for_partial_join(start_key->key, rows); + if (filter) + { + tmp-= filter->get_adjusted_gain(rows, s->worst_seeks) - + filter->get_cmp_gain(rows); + DBUG_ASSERT(tmp >= 0); + } + } if (tmp + 0.0001 < best_time - records/(double) TIME_FOR_COMPARE) { @@ -7352,6 +7477,7 @@ best_access_path(JOIN *join, Here we estimate its cost. */ + filter= 0; if (s->quick) { /* @@ -7367,6 +7493,19 @@ best_access_path(JOIN *join, (s->quick->read_time + (s->found_records - rnd_records)/(double) TIME_FOR_COMPARE); + if ( s->quick->get_type() == QUICK_SELECT_I::QS_TYPE_RANGE) + { + double rows= record_count * s->found_records; + uint key_no= s->quick->index; + filter= s->table->best_range_rowid_filter_for_partial_join(key_no, + rows); + if (filter) + { + tmp-= filter->get_gain(rows); + DBUG_ASSERT(tmp >= 0); + } + } + loose_scan_opt.check_range_access(join, idx, s->quick); } else @@ -7412,21 +7551,23 @@ best_access_path(JOIN *join, else tmp+= s->startup_cost; - filter= s->table->best_filter_for_current_join_order(MAX_KEY, - rnd_records, - record_count); - if (filter && (filter->get_filter_gain(record_count*rnd_records) < tmp)) - tmp= tmp - filter->get_filter_gain(record_count*rnd_records); - /* We estimate the cost of evaluating WHERE clause for found records as record_count * rnd_records / TIME_FOR_COMPARE. This cost plus tmp give us total cost of using TABLE SCAN */ + + double filter_cmp_gain= 0; + if (filter) + { + filter_cmp_gain= filter->get_cmp_gain(record_count * s->found_records); + } + if (best == DBL_MAX || (tmp + record_count/(double) TIME_FOR_COMPARE*rnd_records < (best_key->is_for_hash_join() ? best_time : - best + record_count/(double) TIME_FOR_COMPARE*records))) + best + record_count/(double) TIME_FOR_COMPARE*records - + filter_cmp_gain))) { /* If the table has a range (s->quick is set) make_join_select() @@ -7435,7 +7576,9 @@ best_access_path(JOIN *join, best= tmp; records= best_records; best_key= 0; - best_filter= filter; + best_filter= 0; + if (s->quick && s->quick->get_type() == QUICK_SELECT_I::QS_TYPE_RANGE) + best_filter= filter; /* range/index_merge/ALL/index access method are "independent", so: */ best_ref_depends_map= 0; best_uses_jbuf= MY_TEST(!disable_jbuf && !((s->table->map & @@ -7453,7 +7596,7 @@ best_access_path(JOIN *join, pos->loosescan_picker.loosescan_key= MAX_KEY; pos->use_join_buffer= best_uses_jbuf; pos->spl_plan= spl_plan; - pos->filter= best_filter; + pos->range_rowid_filter_info= best_filter; loose_scan_opt.save_to_position(s, loose_scan_pos); @@ -9719,7 +9862,7 @@ bool JOIN::get_best_combination() is_hash_join_key_no(j->ref.key)) hash_join= TRUE; - j->filter= best_positions[tablenr].filter; + j->range_rowid_filter_info= best_positions[tablenr].range_rowid_filter_info; loop_end: /* @@ -10782,6 +10925,11 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) sel->quick=tab->quick; // Use value from get_quick_... sel->quick_keys.clear_all(); sel->needed_reg.clear_all(); + if (is_hj && tab->rowid_filter) + { + delete tab->rowid_filter; + tab->rowid_filter= 0; + } } else { @@ -12455,6 +12603,23 @@ bool error_if_full_join(JOIN *join) } +void JOIN_TAB::build_range_rowid_filter_if_needed() +{ + if (rowid_filter && !is_rowid_filter_built) + { + if (!rowid_filter->build()) + { + is_rowid_filter_built= true; + } + else + { + delete rowid_filter; + rowid_filter= 0; + } + } +} + + /** cleanup JOIN_TAB. @@ -12478,6 +12643,11 @@ void JOIN_TAB::cleanup() select= 0; delete quick; quick= 0; + if (rowid_filter) + { + delete rowid_filter; + rowid_filter= 0; + } if (cache) { cache->free(); @@ -12589,9 +12759,7 @@ ha_rows JOIN_TAB::get_examined_rows() double examined_rows; SQL_SELECT *sel= filesort? filesort->select : this->select; - if (filter) - examined_rows= records_read; - else if (sel && sel->quick && use_quick != 2) + if (sel && sel->quick && use_quick != 2) examined_rows= (double)sel->quick->records; else if (type == JT_NEXT || type == JT_ALL || type == JT_HASH || type ==JT_HASH_NEXT) @@ -19361,6 +19529,8 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records) if (!join_tab->preread_init_done && join_tab->preread_init()) DBUG_RETURN(NESTED_LOOP_ERROR); + join_tab->build_range_rowid_filter_if_needed(); + join->return_tab= join_tab; if (join_tab->last_inner) @@ -20305,6 +20475,8 @@ int join_init_read_record(JOIN_TAB *tab) if (tab->filesort && tab->sort_table()) // Sort table. return 1; + tab->build_range_rowid_filter_if_needed(); + DBUG_EXECUTE_IF("kill_join_init_read_record", tab->join->thd->set_killed(KILL_QUERY);); if (tab->select && tab->select->quick && tab->select->quick->reset()) @@ -20319,6 +20491,8 @@ int join_init_read_record(JOIN_TAB *tab) tab->join->thd->reset_killed();); if (!tab->preread_init_done && tab->preread_init()) return 1; + + if (init_read_record(&tab->read_record, tab->join->thd, tab->table, tab->select, tab->filesort_result, 1,1, FALSE)) return 1; @@ -22352,6 +22526,12 @@ check_reverse_order: tab->use_quick=1; tab->ref.key= -1; tab->ref.key_parts=0; // Don't use ref key. + tab->range_rowid_filter_info= 0; + if (tab->rowid_filter) + { + delete tab->rowid_filter; + tab->rowid_filter= 0; + } tab->read_first_record= join_init_read_record; if (tab->is_using_loose_index_scan()) tab->join->tmp_table_param.precomputed_group_by= TRUE; @@ -24977,11 +25157,13 @@ int print_explain_message_line(select_result_sink *result, item_list.push_back(item_null, mem_root); /* `rows` */ + StringBuffer<64> rows_str; if (rows) { - item_list.push_back(new (mem_root) Item_int(thd, *rows, - MY_INT64_NUM_DECIMAL_DIGITS), - mem_root); + rows_str.append_ulonglong((ulonglong)(*rows)); + item_list.push_back(new (mem_root) + Item_string_sys(thd, rows_str.ptr(), + rows_str.length()), mem_root); } else item_list.push_back(item_null, mem_root); @@ -25046,31 +25228,6 @@ int append_possible_keys(MEM_ROOT *alloc, String_list &list, TABLE *table, } -/** - This method saves the data that should be printed in EXPLAIN - if any filter was used for this table. -*/ - -bool JOIN_TAB::save_filter_explain_data(Explain_table_access *eta) -{ - if (!filter) - return 0; - KEY *pk_key= get_keyinfo_by_key_no(filter->key_no); - StringBuffer<64> buff_for_pk; - const char *tmp_buff; - buff_for_pk.append("filter:"); - tmp_buff= pk_key->name.str; - buff_for_pk.append(tmp_buff, strlen(tmp_buff), system_charset_info); - if (!(eta->ref_list.append_str(join->thd->mem_root, - buff_for_pk.c_ptr_safe()))) - return 1; - eta->key.set_filter_key_length(pk_key->key_length); - (filter->selectivity*100 >= 1) ? eta->filter_perc= round(filter->selectivity*100) : - eta->filter_perc= 1; - return 0; -} - - bool JOIN_TAB::save_explain_data(Explain_table_access *eta, table_map prefix_tables, bool distinct_arg, JOIN_TAB *first_top_tab) @@ -25106,7 +25263,7 @@ bool JOIN_TAB::save_explain_data(Explain_table_access *eta, filesort))) return 1; } - + // psergey-todo: data for filtering! tracker= &eta->tracker; jbuf_tracker= &eta->jbuf_tracker; @@ -25207,6 +25364,20 @@ bool JOIN_TAB::save_explain_data(Explain_table_access *eta, // psergey-todo: ^ check for error return code /* Build "key", "key_len", and "ref" */ + + if (rowid_filter) + { + Range_rowid_filter *range_filter= (Range_rowid_filter *) rowid_filter; + QUICK_SELECT_I *quick= range_filter->get_select()->quick; + + Explain_rowid_filter *erf= new (thd->mem_root) Explain_rowid_filter; + erf->quick= quick->get_explain(thd->mem_root); + erf->selectivity= range_rowid_filter_info->selectivity; + erf->rows= quick->records; + eta->rowid_filter= erf; + //psergey-todo: also do setup for ANALYZE here. + } + if (tab_type == JT_NEXT) { key_info= table->key_info+index; @@ -25326,13 +25497,6 @@ bool JOIN_TAB::save_explain_data(Explain_table_access *eta, eta->filtered= f; } - if ((tab_select && tab_select->quick && tab_type != JT_CONST) || - (key_info && ref.key_parts && tab_type != JT_FT)) - { - if (save_filter_explain_data(eta)) - return 1; - } - /* Build "Extra" field and save it */ key_read= table->file->keyread_enabled(); if ((tab_type == JT_NEXT || tab_type == JT_CONST) && diff --git a/sql/sql_select.h b/sql/sql_select.h index 1d08b746279..3de0e894c93 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -510,9 +510,18 @@ typedef struct st_join_table { uint n_sj_tables; bool preread_init_done; - /* Copy of POSITION::filter, set by get_best_combination() */ - Range_filter_cost_info *filter; - Dynamic_array<char*> rowid_filter_pk; + + /* + Cost info to the range filter used when joining this join table + (Defined when the best join order has been already chosen) + */ + Range_rowid_filter_cost_info *range_rowid_filter_info; + /* Rowid filter to be used when joining this join table */ + Rowid_filter *rowid_filter; + /* Becomes true just after the used range filter has been built / filled */ + bool is_rowid_filter_built; + + void build_range_rowid_filter_if_needed(); void cleanup(); inline bool is_using_loose_index_scan() @@ -663,7 +672,6 @@ typedef struct st_join_table { SplM_plan_info *choose_best_splitting(double record_count, table_map remaining_tables); bool fix_splitting(SplM_plan_info *spl_plan, table_map remaining_tables); - bool save_filter_explain_data(Explain_table_access *eta); } JOIN_TAB; @@ -889,7 +897,8 @@ public: }; -class Range_filter_cost_info; +class Range_rowid_filter_cost_info; +class Rowid_filter; /** @@ -974,8 +983,10 @@ typedef struct st_position /* Info on splitting plan used at this position */ SplM_plan_info *spl_plan; - /* The index for which filter can be built */ - Range_filter_cost_info *filter; + + /* Cost info for the range filter used at this position */ + Range_rowid_filter_cost_info *range_rowid_filter_info; + } POSITION; typedef Bounds_checked_array<Item_null_result*> Item_null_array; @@ -1625,6 +1636,8 @@ public: bool optimize_unflattened_subqueries(); bool optimize_constant_subqueries(); int init_join_caches(); + bool make_range_rowid_filters(); + bool init_range_rowid_filters(); bool make_sum_func_list(List<Item> &all_fields, List<Item> &send_fields, bool before_group_by, bool recompute= FALSE); diff --git a/sql/structs.h b/sql/structs.h index 9ff52bccb40..12b5dee0055 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -27,6 +27,15 @@ #include "thr_lock.h" /* thr_lock_type */ #include "my_base.h" /* ha_rows, ha_key_alg */ #include <mysql_com.h> /* USERNAME_LENGTH */ +#include "sql_bitmap.h" + +#if MAX_INDEXES <= 64 +typedef Bitmap<64> key_map; /* Used for finding keys */ +#elif MAX_INDEXES > 128 +#error "MAX_INDEXES values greater than 128 is not supported." +#else +typedef Bitmap<((MAX_INDEXES+7)/8*8)> key_map; /* Used for finding keys */ +#endif struct TABLE; class Type_handler; @@ -111,6 +120,11 @@ typedef struct st_key { */ LEX_CSTRING name; key_part_map ext_key_part_map; + /* + Bitmap of indexes having common parts with this index + (only key parts from key definitions are taken into account) + */ + key_map overlapped; uint block_size; enum ha_key_alg algorithm; /* diff --git a/sql/table.cc b/sql/table.cc index 18be06c0b95..3df4c9f543a 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1227,6 +1227,44 @@ static const Type_handler *old_frm_type_handler(uint pack_flag, return Type_handler::get_handler_by_real_type(field_type); } +/* Set overlapped bitmaps for each index */ + +void TABLE_SHARE::set_overlapped_keys() +{ + KEY *key1= key_info; + for (uint i= 0; i < keys; i++, key1++) + { + key1->overlapped.clear_all(); + key1->overlapped.set_bit(i); + } + key1= key_info; + for (uint i= 0; i < keys; i++, key1++) + { + KEY *key2= key1 + 1; + for (uint j= i+1; j < keys; j++, key2++) + { + KEY_PART_INFO *key_part1= key1->key_part; + uint n1= key1->user_defined_key_parts; + uint n2= key2->user_defined_key_parts; + for (uint k= 0; k < n1; k++, key_part1++) + { + KEY_PART_INFO *key_part2= key2->key_part; + for (uint l= 0; l < n2; l++, key_part2++) + { + if (key_part1->fieldnr == key_part2->fieldnr) + { + key1->overlapped.set_bit(j); + key2->overlapped.set_bit(i); + goto end_checking_overlap; + } + } + } + end_checking_overlap: + ; + } + } +} + /** Read data from a binary .frm file image into a TABLE_SHARE @@ -2522,6 +2560,8 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, null_length, 255); } + set_overlapped_keys(); + /* Handle virtual expressions */ if (vcol_screen_length && share->frm_version >= FRM_VER_EXPRESSSIONS) { @@ -4656,8 +4696,9 @@ void TABLE::init(THD *thd, TABLE_LIST *tl) created= TRUE; cond_selectivity= 1.0; cond_selectivity_sampling_explain= NULL; - best_filter_count= 0; - range_filter_cost_info_elements= 0; + range_rowid_filter_cost_info_elems= 0; + range_rowid_filter_cost_info_ptr= NULL; + range_rowid_filter_cost_info= NULL; #ifdef HAVE_REPLICATION /* used in RBR Triggers */ master_had_triggers= 0; diff --git a/sql/table.h b/sql/table.h index 3c782c34bc3..1b8b837c35b 100644 --- a/sql/table.h +++ b/sql/table.h @@ -55,7 +55,7 @@ class Virtual_column_info; class Table_triggers_list; class TMP_TABLE_PARAM; class SEQUENCE; -class Range_filter_cost_info; +class Range_rowid_filter_cost_info; /* Used to identify NESTED_JOIN structures within a join (applicable only to @@ -1002,6 +1002,8 @@ struct TABLE_SHARE /* frees the memory allocated in read_frm_image */ void free_frm_image(const uchar *frm); + + void set_overlapped_keys(); }; @@ -1193,7 +1195,14 @@ public: and max #key parts that range access would use. */ ha_rows quick_rows[MAX_KEY]; + uint quick_key_parts[MAX_KEY]; + double quick_costs[MAX_KEY]; + /* + If there is a range access by i-th index then the cost of + index only access for it is stored in quick_index_only_costs[i] + */ + double quick_index_only_costs[MAX_KEY]; /* Bitmaps of key parts that =const for the duration of join execution. If @@ -1202,10 +1211,7 @@ public: */ key_part_map const_key_parts[MAX_KEY]; - uint quick_key_parts[MAX_KEY]; uint quick_n_ranges[MAX_KEY]; - /* For each key I/O access cost is stored */ - double quick_key_io[MAX_KEY]; /* Estimate of number of records that satisfy SARGable part of the table @@ -1497,21 +1503,21 @@ public: double get_materialization_cost(); // Now used only if is_splittable()==true void add_splitting_info_for_key_field(struct KEY_FIELD *key_field); + key_map with_impossible_ranges; + + /* Number of cost info elements for possible range filters */ + uint range_rowid_filter_cost_info_elems; + /* Pointer to the array of cost info elements for range filters */ + Range_rowid_filter_cost_info *range_rowid_filter_cost_info; + /* The array of pointers to cost info elements for range filters */ + Range_rowid_filter_cost_info **range_rowid_filter_cost_info_ptr; + + void init_cost_info_for_usable_range_rowid_filters(THD *thd); + void prune_range_rowid_filters(); + Range_rowid_filter_cost_info * + best_range_rowid_filter_for_partial_join(uint access_key_no, + double records); - /** - Range filter info - */ - /* Minimum possible #T value to apply filter*/ - uint best_filter_count; - uint range_filter_cost_info_elements; - Range_filter_cost_info *range_filter_cost_info; - Range_filter_cost_info - *best_filter_for_current_join_order(uint ref_key_no, - double record_count, - double records); - void sort_range_filter_cost_info_array(); - void prune_range_filters(); - void select_usable_range_filters(THD *thd); /** System Versioning support */ diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 6dedef20c05..0b4880b0205 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -3461,6 +3461,10 @@ ha_innobase::reset_template(void) in ha_innobase::write_row(). */ m_prebuilt->template_type = ROW_MYSQL_NO_TEMPLATE; } + if (m_prebuilt->pk_filter) { + m_prebuilt->pk_filter = NULL; + m_prebuilt->template_type = ROW_MYSQL_NO_TEMPLATE; + } } /*****************************************************************//** @@ -5246,7 +5250,8 @@ ha_innobase::index_flags( ulong flags = HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER | HA_READ_RANGE | HA_KEYREAD_ONLY | extra_flag - | HA_DO_INDEX_COND_PUSHDOWN; + | HA_DO_INDEX_COND_PUSHDOWN + | HA_DO_RANGE_FILTER_PUSHDOWN; /* For spatial index, we don't support descending scan and ICP so far. */ @@ -7553,6 +7558,13 @@ ha_innobase::build_template( /* Below we check column by column if we need to access the clustered index. */ + if (pushed_rowid_filter && rowid_filter_is_active) { + fetch_primary_key_cols = TRUE; + m_prebuilt->pk_filter = this; + } else { + m_prebuilt->pk_filter = NULL; + } + n_fields = (ulint) mysql_fields(table); if (!m_prebuilt->mysql_template) { @@ -7573,8 +7585,9 @@ ha_innobase::build_template( /* Note that in InnoDB, i is the column number in the table. MySQL calls columns 'fields'. */ - if (active_index != MAX_KEY - && active_index == pushed_idx_cond_keyno) { + if ((active_index != MAX_KEY + && active_index == pushed_idx_cond_keyno) || + (pushed_rowid_filter && rowid_filter_is_active)) { ulint num_v = 0; /* Push down an index condition or an end_range check. */ @@ -7768,8 +7781,9 @@ ha_innobase::build_template( } } } - - m_prebuilt->idx_cond = this; + if (active_index == pushed_idx_cond_keyno) { + m_prebuilt->idx_cond = this; + } } else { no_icp: mysql_row_templ_t* templ; @@ -20318,6 +20332,22 @@ innobase_index_cond( return handler_index_cond_check(file); } +bool +innobase_pk_filter( +/*===============*/ + void* file) /*!< in/out: pointer to ha_innobase */ +{ + return handler_rowid_filter_check(file); +} + +bool +innobase_pk_filter_is_active( +/*==========================*/ + void* file) /*!< in/out: pointer to ha_innobase */ +{ + return handler_rowid_filter_is_active(file); +} + /** Parse the table file name into table name and database name. @param[in] tbl_name InnoDB table name @param[out] dbname database name buffer (NAME_LEN + 1 bytes) @@ -20853,6 +20883,21 @@ ha_innobase::idx_cond_push( DBUG_RETURN(NULL); } + +/** Push primary key filter. +@param[in] pk_filter PK filter against which primary keys + are to be checked */ + +bool +ha_innobase::rowid_filter_push( + class Rowid_filter* pk_filter) +{ + DBUG_ENTER("ha_innobase::rowid_filter_push"); + DBUG_ASSERT(pk_filter != NULL); + pushed_rowid_filter= pk_filter; + DBUG_RETURN(FALSE); +} + /******************************************************************//** Use this when the args are passed to the format string from errmsg-utf8.txt directly as is. diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h index 7bec858b5af..d6c1154ba8f 100644 --- a/storage/innobase/handler/ha_innodb.h +++ b/storage/innobase/handler/ha_innodb.h @@ -417,6 +417,12 @@ public: Item* idx_cond_push(uint keyno, Item* idx_cond); /* @} */ + /** Attempt to push down a rowid filter + @param[in] pk_filter Handle of the rowid filter to be pushed. + #return 0 pk-filter is pushed; NULL if not pushed */ + bool rowid_filter_push(class Rowid_filter *rowid_filter); + /* @} */ + protected: /** diff --git a/storage/innobase/include/ha_prototypes.h b/storage/innobase/include/ha_prototypes.h index 15107a93807..574526ebc82 100644 --- a/storage/innobase/include/ha_prototypes.h +++ b/storage/innobase/include/ha_prototypes.h @@ -556,6 +556,23 @@ innobase_index_cond( void* file) /*!< in/out: pointer to ha_innobase */ MY_ATTRIBUTE((warn_unused_result)); +/*************************************************************//** +InnoDB Rowid filter check defined in ha_innodb.cc */ + +bool +innobase_pk_filter( +/*================*/ + void* file) /*!< in/out: pointer to ha_innobase */ + MY_ATTRIBUTE((warn_unused_result)); + +/*************************************************************//** +InnoDB check whether pk-filter is active */ + +bool +innobase_pk_filter_is_active( +/*==========================*/ + void* file); /*!< in/out: pointer to ha_innobase */ + /******************************************************************//** Gets information on the durability property requested by thread. Used when writing either a prepare or commit record to the log diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h index cabca5699c4..c5c96818d04 100644 --- a/storage/innobase/include/row0mysql.h +++ b/storage/innobase/include/row0mysql.h @@ -828,6 +828,10 @@ struct row_prebuilt_t { 0 if and only if idx_cond == NULL. */ /*----------------------*/ + void* pk_filter; /*!< In PK-filters, pointer to a ha_innobase, + passed to innobase_pk_filter(). + NULL if no PK-filter is pushed. */ + /*----------------------*/ rtr_info_t* rtr_info; /*!< R-tree Search Info */ /*----------------------*/ diff --git a/storage/innobase/include/srv0mon.h b/storage/innobase/include/srv0mon.h index 48dffe04197..0433ed5dcfd 100644 --- a/storage/innobase/include/srv0mon.h +++ b/storage/innobase/include/srv0mon.h @@ -444,6 +444,11 @@ enum monitor_id_t { MONITOR_ICP_OUT_OF_RANGE, MONITOR_ICP_MATCH, + MONITOR_MODULE_PK_FILTER, + MONITOR_PK_FILTER_CHECKS, + MONITOR_PK_FILTER_POSITIVE, + MONITOR_PK_FILTER_NEGATIVE, + /* Mutex/RW-Lock related counters */ MONITOR_MODULE_LATCHES, MONITOR_LATCHES, diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc index a8787574e5a..73c21d938ae 100644 --- a/storage/innobase/row/row0sel.cc +++ b/storage/innobase/row/row0sel.cc @@ -3816,7 +3816,7 @@ row_sel_enqueue_cache_row_for_mysql( /* For non ICP code path the row should already exist in the next fetch cache slot. */ - if (prebuilt->idx_cond != NULL) { + if (prebuilt->idx_cond != NULL || prebuilt->pk_filter != NULL ) { byte* dest = row_sel_fetch_last_buf(prebuilt); ut_memcpy(dest, mysql_rec, prebuilt->mysql_row_len); @@ -3920,10 +3920,12 @@ row_search_idx_cond_check( ut_ad(rec_offs_validate(rec, prebuilt->index, offsets)); if (!prebuilt->idx_cond) { - return(ICP_MATCH); - } - - MONITOR_INC(MONITOR_ICP_ATTEMPTS); + if (!(innobase_pk_filter_is_active(prebuilt->pk_filter))) { + return(ICP_MATCH); + } + } else { + MONITOR_INC(MONITOR_ICP_ATTEMPTS); + } /* Convert to MySQL format those fields that are needed for evaluating the index condition. */ @@ -3954,9 +3956,25 @@ row_search_idx_cond_check( index, if the case of the column has been updated in the past, or a record has been deleted and a record inserted in a different case. */ - result = innobase_index_cond(prebuilt->idx_cond); + if (prebuilt->idx_cond) { + result = innobase_index_cond(prebuilt->idx_cond); + } else { + result = ICP_MATCH; + } switch (result) { case ICP_MATCH: + if (innobase_pk_filter_is_active(prebuilt->pk_filter)) { + bool pkf_result; + MONITOR_INC(MONITOR_PK_FILTER_CHECKS); + pkf_result = innobase_pk_filter(prebuilt->pk_filter); + if (pkf_result) { + MONITOR_INC(MONITOR_PK_FILTER_POSITIVE); + } else { + MONITOR_INC(MONITOR_PK_FILTER_NEGATIVE); + MONITOR_INC(MONITOR_ICP_MATCH); + return(ICP_NO_MATCH); + } + } /* Convert the remaining fields to MySQL format. If this is a secondary index record, we must defer this until we have fetched the clustered index record. */ @@ -4409,7 +4427,7 @@ row_search_mvcc( mtr.commit(). */ ut_ad(!rec_get_deleted_flag(rec, comp)); - if (prebuilt->idx_cond) { + if (prebuilt->idx_cond || prebuilt->pk_filter) { switch (row_search_idx_cond_check( buf, prebuilt, rec, offsets)) { @@ -5341,7 +5359,7 @@ requires_clust_rec: result_rec = clust_rec; ut_ad(rec_offs_validate(result_rec, clust_index, offsets)); - if (prebuilt->idx_cond) { + if (prebuilt->idx_cond || prebuilt->pk_filter) { /* Convert the record to MySQL format. We were unable to do this in row_search_idx_cond_check(), because the condition is on the secondary index @@ -5402,7 +5420,7 @@ use_covering_index: /* We only convert from InnoDB row format to MySQL row format when ICP is disabled. */ - if (!prebuilt->idx_cond) { + if (!(prebuilt->idx_cond || prebuilt->pk_filter)) { /* We use next_buf to track the allocation of buffers where we store and enqueue the buffers for our @@ -5475,7 +5493,7 @@ use_covering_index: rec_offs_size(offsets)); mach_write_to_4(buf, rec_offs_extra_size(offsets) + 4); - } else if (!prebuilt->idx_cond) { + } else if (!(prebuilt->idx_cond || prebuilt->pk_filter)) { /* The record was not yet converted to MySQL format. */ if (!row_sel_store_mysql_rec( buf, prebuilt, result_rec, vrow, @@ -5709,7 +5727,7 @@ normal_return: DEBUG_SYNC_C("row_search_for_mysql_before_return"); - if (prebuilt->idx_cond != 0) { + if (prebuilt->idx_cond != 0 || prebuilt->pk_filter != 0) { /* When ICP is active we don't write to the MySQL buffer directly, only to buffers that are enqueued in the pre-fetch diff --git a/storage/innobase/srv/srv0mon.cc b/storage/innobase/srv/srv0mon.cc index 8c62d61423f..9215a46cb51 100644 --- a/storage/innobase/srv/srv0mon.cc +++ b/storage/innobase/srv/srv0mon.cc @@ -1405,6 +1405,24 @@ static monitor_info_t innodb_counter_info[] = MONITOR_NONE, MONITOR_DEFAULT_START, MONITOR_ICP_MATCH}, + /* ===== Counters for PK-filters Module ===== */ + {"module_pk-filter", "pk-filter", "Primary Keys Filtering", + MONITOR_MODULE, + MONITOR_DEFAULT_START, MONITOR_MODULE_PK_FILTER}, + + {"pk-filter checks", "pk-filter", + "Number of lookups into PK-filters", + MONITOR_NONE, + MONITOR_DEFAULT_START, MONITOR_PK_FILTER_CHECKS}, + + {"pk-filter_positive", "pk-filter", "PK-filter test is positive", + MONITOR_NONE, + MONITOR_DEFAULT_START, MONITOR_PK_FILTER_POSITIVE}, + + {"pk-filter_negarive", "pk-filter", "PK-filter test is negative", + MONITOR_NONE, + MONITOR_DEFAULT_START, MONITOR_PK_FILTER_NEGATIVE}, + /* ========== Mutex monitoring on/off ========== */ {"latch_status", "Latch counters", "Collect latch counters to display via SHOW ENGING INNODB MUTEX", diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 9ab7d156251..012691ef2da 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -769,7 +769,8 @@ ulong ha_myisam::index_flags(uint inx, uint part, bool all_parts) const else { flags= HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE | - HA_READ_ORDER | HA_KEYREAD_ONLY | HA_DO_INDEX_COND_PUSHDOWN; + HA_READ_ORDER | HA_KEYREAD_ONLY | HA_DO_INDEX_COND_PUSHDOWN | + HA_DO_RANGE_FILTER_PUSHDOWN; } return flags; } @@ -1880,6 +1881,9 @@ int ha_myisam::index_init(uint idx, bool sorted) active_index=idx; if (pushed_idx_cond_keyno == idx) mi_set_index_cond_func(file, handler_index_cond_check, this); + if (pushed_rowid_filter) + mi_set_rowid_filter_func(file, handler_rowid_filter_check, + handler_rowid_filter_is_active, this); return 0; } @@ -1891,6 +1895,7 @@ int ha_myisam::index_end() //pushed_idx_cond_keyno= MAX_KEY; mi_set_index_cond_func(file, NULL, 0); in_range_check_pushed_down= FALSE; + mi_set_rowid_filter_func(file, NULL, NULL, 0); ds_mrr.dsmrr_close(); #if !defined(DBUG_OFF) && defined(SQL_SELECT_FIXED_FOR_UPDATE) file->update&= ~HA_STATE_AKTIV; // Forget active row @@ -1926,6 +1931,9 @@ int ha_myisam::index_read_idx_map(uchar *buf, uint index, const uchar *key, end_range= NULL; if (index == pushed_idx_cond_keyno) mi_set_index_cond_func(file, handler_index_cond_check, this); + if (pushed_rowid_filter) + mi_set_rowid_filter_func(file, handler_rowid_filter_check, + handler_rowid_filter_is_active, this); res= mi_rkey(file, buf, index, key, keypart_map, find_flag); mi_set_index_cond_func(file, NULL, 0); return res; @@ -2591,6 +2599,14 @@ Item *ha_myisam::idx_cond_push(uint keyno_arg, Item* idx_cond_arg) return NULL; } +bool ha_myisam::rowid_filter_push(Rowid_filter* rowid_filter) +{ + pushed_rowid_filter= rowid_filter; + mi_set_rowid_filter_func(file, handler_rowid_filter_check, + handler_rowid_filter_is_active, this); + return false; +} + struct st_mysql_storage_engine myisam_storage_engine= { MYSQL_HANDLERTON_INTERFACE_VERSION }; @@ -2681,7 +2697,7 @@ my_bool ha_myisam::register_query_cache_table(THD *thd, const char *table_name, If the table size is unknown the SELECT statement can't be cached. - When concurrent inserts are disabled at table open, mi_open() + When concurrent inserts are disabled at table open, mi_ondopen() does not assign a get_status() function. In this case the local ("current") status is never updated. We would wrongly think that we cannot cache the statement. diff --git a/storage/myisam/ha_myisam.h b/storage/myisam/ha_myisam.h index 804963f5efc..f9f11b6f480 100644 --- a/storage/myisam/ha_myisam.h +++ b/storage/myisam/ha_myisam.h @@ -172,6 +172,8 @@ public: /* Index condition pushdown implementation */ Item *idx_cond_push(uint keyno, Item* idx_cond); + bool rowid_filter_push(Rowid_filter* rowid_filter); + private: DsMrr_impl ds_mrr; friend ICP_RESULT index_cond_func_myisam(void *arg); diff --git a/storage/myisam/mi_extra.c b/storage/myisam/mi_extra.c index c10bf61a477..e28b9be501e 100644 --- a/storage/myisam/mi_extra.c +++ b/storage/myisam/mi_extra.c @@ -418,6 +418,16 @@ void mi_set_index_cond_func(MI_INFO *info, index_cond_func_t func, info->index_cond_func_arg= func_arg; } +void mi_set_rowid_filter_func(MI_INFO *info, + rowid_filter_func_t check_func, + rowid_filter_func_t is_active_func, + void *func_arg) +{ + info->rowid_filter_func= check_func; + info->rowid_filter_is_active_func= is_active_func; + info->rowid_filter_func_arg= func_arg; +} + /* Start/Stop Inserting Duplicates Into a Table, WL#1648. */ diff --git a/storage/myisam/mi_key.c b/storage/myisam/mi_key.c index 4bd01dcbfa0..8bf63af8f5f 100644 --- a/storage/myisam/mi_key.c +++ b/storage/myisam/mi_key.c @@ -529,6 +529,19 @@ ICP_RESULT mi_check_index_cond(register MI_INFO *info, uint keynr, return res; } + +int mi_check_rowid_filter(MI_INFO *info) +{ + return info->rowid_filter_func(info->rowid_filter_func_arg); +} + +int mi_check_rowid_filter_is_active(MI_INFO *info) +{ + if (info->rowid_filter_is_active_func == NULL) + return 0; + return info->rowid_filter_is_active_func(info->rowid_filter_func_arg); +} + /* Retrieve auto_increment info diff --git a/storage/myisam/mi_range.c b/storage/myisam/mi_range.c index 2074c873979..185f2ca61fa 100644 --- a/storage/myisam/mi_range.c +++ b/storage/myisam/mi_range.c @@ -22,9 +22,10 @@ #include "myisamdef.h" #include "rt_index.h" -static ha_rows _mi_record_pos(MI_INFO *, const uchar *, key_part_map, - enum ha_rkey_function); -static double _mi_search_pos(MI_INFO *,MI_KEYDEF *,uchar *, uint,uint,my_off_t); +static double _mi_record_pos(MI_INFO *, const uchar *, key_part_map, + enum ha_rkey_function); +static double _mi_search_pos(MI_INFO *,MI_KEYDEF *,uchar *, uint,uint, + my_off_t,my_bool); static uint _mi_keynr(MI_INFO *info,MI_KEYDEF *,uchar *, uchar *,uint *); /* @@ -48,7 +49,8 @@ static uint _mi_keynr(MI_INFO *info,MI_KEYDEF *,uchar *, uchar *,uint *); ha_rows mi_records_in_range(MI_INFO *info, int inx, key_range *min_key, key_range *max_key) { - ha_rows start_pos,end_pos,res; + ha_rows res; + double start_pos,end_pos,diff; DBUG_ENTER("mi_records_in_range"); if ((inx = _mi_check_index(info,inx)) < 0) @@ -94,16 +96,27 @@ ha_rows mi_records_in_range(MI_INFO *info, int inx, #endif case HA_KEY_ALG_BTREE: default: - start_pos= (min_key ? _mi_record_pos(info, min_key->key, - min_key->keypart_map, min_key->flag) - : (ha_rows) 0); + start_pos= (min_key ?_mi_record_pos(info, min_key->key, + min_key->keypart_map, min_key->flag) + : (double) 0); end_pos= (max_key ? _mi_record_pos(info, max_key->key, max_key->keypart_map, max_key->flag) - : info->state->records + (ha_rows) 1); + : (double) info->state->records); res= (end_pos < start_pos ? (ha_rows) 0 : (end_pos == start_pos ? (ha_rows) 1 : end_pos-start_pos)); if (start_pos == HA_POS_ERROR || end_pos == HA_POS_ERROR) res=HA_POS_ERROR; + else + { + diff= end_pos - start_pos; + if (diff >= 0) + { + if (!(res= (diff + 0.5))) + res= 1; + } + else + res= 0; + } } if (info->s->concurrent_insert) @@ -115,11 +128,25 @@ ha_rows mi_records_in_range(MI_INFO *info, int inx, } - /* Find relative position (in records) for key in index-tree */ +/* + To find an approximate relative position of a key tuple among all index + key tuples would not be hard if we considered B-trees where all key + tuples were contained only in leaf nodes. If we consider a B-tree where + key tuples are stored also in non-leaf nodes we have to convert such + tree into the tree of the first type. The transformation procedure is + simple: the key tuple k goes alter the last key tuple in the most right + sub-tree pointer to which is coupled with k. As a result of this + transformation each leaf node except the most right one in the tree will + contain one extra key tuple following those originally belonging to + the leaf. +*/ + + +/* Find relative position (in records) for key in index-tree */ -static ha_rows _mi_record_pos(MI_INFO *info, const uchar *key, - key_part_map keypart_map, - enum ha_rkey_function search_flag) +static double _mi_record_pos(MI_INFO *info, const uchar *key, + key_part_map keypart_map, + enum ha_rkey_function search_flag) { uint inx=(uint) info->lastinx, nextflag, key_len; MI_KEYDEF *keyinfo=info->s->keyinfo+inx; @@ -175,11 +202,11 @@ static ha_rows _mi_record_pos(MI_INFO *info, const uchar *key, */ pos=_mi_search_pos(info,keyinfo,key_buff,key_len, nextflag | SEARCH_SAVE_BUFF | SEARCH_UPDATE, - info->s->state.key_root[inx]); + info->s->state.key_root[inx], TRUE); if (pos >= 0.0) { - DBUG_PRINT("exit",("pos: %ld",(ulong) (pos*info->state->records))); - DBUG_RETURN((ulong) (pos*info->state->records+0.5)); + DBUG_PRINT("exit",("pos: %g",(pos*info->state->records))); + DBUG_RETURN(pos*info->state->records); } DBUG_RETURN(HA_POS_ERROR); } @@ -191,7 +218,7 @@ static ha_rows _mi_record_pos(MI_INFO *info, const uchar *key, static double _mi_search_pos(register MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *key, uint key_len, uint nextflag, - register my_off_t pos) + register my_off_t pos, my_bool last_in_level) { int flag; uint nod_flag,keynr,UNINIT_VAR(max_keynr); @@ -222,7 +249,8 @@ static double _mi_search_pos(register MI_INFO *info, if (flag > 0 && ! nod_flag) offset= 1.0; else if ((offset=_mi_search_pos(info,keyinfo,key,key_len,nextflag, - _mi_kpos(nod_flag,keypos))) < 0) + _mi_kpos(nod_flag,keypos), + last_in_level && after_key)) < 0) DBUG_RETURN(offset); } else @@ -241,13 +269,15 @@ static double _mi_search_pos(register MI_INFO *info, Matches keynr + [0-1] */ if ((offset=_mi_search_pos(info,keyinfo,key,key_len,SEARCH_FIND, - _mi_kpos(nod_flag,keypos))) < 0) + _mi_kpos(nod_flag,keypos), + last_in_level && after_key)) < 0) DBUG_RETURN(offset); /* Read error */ } } DBUG_PRINT("info",("keynr: %d offset: %g max_keynr: %d nod: %d flag: %d", keynr,offset,max_keynr,nod_flag,flag)); - DBUG_RETURN((keynr+offset)/(max_keynr+1)); + DBUG_RETURN((keynr+offset-MY_TEST(!nod_flag))/ + (max_keynr+MY_TEST(nod_flag || !last_in_level))); err: DBUG_PRINT("exit",("Error: %d",my_errno)); DBUG_RETURN (-1.0); diff --git a/storage/myisam/mi_rkey.c b/storage/myisam/mi_rkey.c index 1dddb8b49ad..c0f9b2046fc 100644 --- a/storage/myisam/mi_rkey.c +++ b/storage/myisam/mi_rkey.c @@ -120,7 +120,9 @@ int mi_rkey(MI_INFO *info, uchar *buf, int inx, const uchar *key, (search_flag != HA_READ_KEY_EXACT || last_used_keyseg != keyinfo->seg + keyinfo->keysegs)) || (info->index_cond_func && - (res= mi_check_index_cond(info, inx, buf)) == ICP_NO_MATCH)) + (res= mi_check_index_cond(info, inx, buf)) == ICP_NO_MATCH) || + (mi_check_rowid_filter_is_active(info) && + !mi_check_rowid_filter(info))) { uint not_used[2]; /* diff --git a/storage/myisam/mi_rnext.c b/storage/myisam/mi_rnext.c index 6e3701abe6b..c3af209fd71 100644 --- a/storage/myisam/mi_rnext.c +++ b/storage/myisam/mi_rnext.c @@ -102,7 +102,9 @@ int mi_rnext(MI_INFO *info, uchar *buf, int inx) while ((info->s->concurrent_insert && info->lastpos >= info->state->data_file_length) || (info->index_cond_func && - (icp_res= mi_check_index_cond(info, inx, buf)) == ICP_NO_MATCH)) + (icp_res= mi_check_index_cond(info, inx, buf)) == ICP_NO_MATCH) || + (mi_check_rowid_filter_is_active(info) && + !mi_check_rowid_filter(info))) { /* If we are at the last key on the key page, allow writers to diff --git a/storage/myisam/mi_rnext_same.c b/storage/myisam/mi_rnext_same.c index d6856459ae7..ac818bfa2da 100644 --- a/storage/myisam/mi_rnext_same.c +++ b/storage/myisam/mi_rnext_same.c @@ -95,7 +95,9 @@ int mi_rnext_same(MI_INFO *info, uchar *buf) */ if (info->lastpos < info->state->data_file_length && (!info->index_cond_func || - (icp_res= mi_check_index_cond(info, inx, buf)) != ICP_NO_MATCH)) + (icp_res= mi_check_index_cond(info, inx, buf)) != ICP_NO_MATCH) && + (!mi_check_rowid_filter_is_active(info) || + mi_check_rowid_filter(info))) break; } } diff --git a/storage/myisam/mi_rprev.c b/storage/myisam/mi_rprev.c index 27fbda95574..a78bab6a040 100644 --- a/storage/myisam/mi_rprev.c +++ b/storage/myisam/mi_rprev.c @@ -59,7 +59,9 @@ int mi_rprev(MI_INFO *info, uchar *buf, int inx) while ((share->concurrent_insert && info->lastpos >= info->state->data_file_length) || (info->index_cond_func && - (icp_res= mi_check_index_cond(info, inx, buf)) == ICP_NO_MATCH)) + (icp_res= mi_check_index_cond(info, inx, buf)) == ICP_NO_MATCH) || + (mi_check_rowid_filter_is_active(info) && + !mi_check_rowid_filter(info))) { /* If we are at the last (i.e. first?) key on the key page, diff --git a/storage/myisam/myisamdef.h b/storage/myisam/myisamdef.h index e350626f192..d51e0f9f9e1 100644 --- a/storage/myisam/myisamdef.h +++ b/storage/myisam/myisamdef.h @@ -305,6 +305,9 @@ struct st_myisam_info my_bool create_unique_index_by_sort; index_cond_func_t index_cond_func; /* Index condition function */ void *index_cond_func_arg; /* parameter for the func */ + rowid_filter_func_t rowid_filter_func; /* rowid filter check function */ + rowid_filter_func_t rowid_filter_is_active_func; /* is activefunction */ + void *rowid_filter_func_arg; /* parameter for the func */ THR_LOCK_DATA lock; uchar *rtree_recursion_state; /* For RTREE */ int rtree_recursion_depth; @@ -724,14 +727,20 @@ int mi_munmap_file(MI_INFO *info); void mi_remap_file(MI_INFO *info, my_off_t size); ICP_RESULT mi_check_index_cond(MI_INFO *info, uint keynr, uchar *record); +int mi_check_rowid_filter(MI_INFO *info); +int mi_check_rowid_filter_is_active(MI_INFO *info); /* Functions needed by mi_check */ int killed_ptr(HA_CHECK *param); void mi_check_print_error(HA_CHECK *param, const char *fmt, ...); void mi_check_print_warning(HA_CHECK *param, const char *fmt, ...); void mi_check_print_info(HA_CHECK *param, const char *fmt, ...); pthread_handler_t thr_find_all_keys(void *arg); -extern void mi_set_index_cond_func(MI_INFO *info, index_cond_func_t func, +extern void mi_set_index_cond_func(MI_INFO *info, index_cond_func_t check_func, void *func_arg); +extern void mi_set_rowid_filter_func(MI_INFO *info, + rowid_filter_func_t check_func, + rowid_filter_func_t is_active_func, + void *func_arg); int flush_blocks(HA_CHECK *param, KEY_CACHE *key_cache, File file, ulonglong *dirty_part_map); diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index cbf3dad0965..90c8b503a05 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -7606,8 +7606,8 @@ static void test_explain_bug() verify_prepare_field(result, 7, "ref", "", MYSQL_TYPE_VAR_STRING, "", "", "", NAME_CHAR_LEN * HA_MAX_KEY_SEG, 0); - verify_prepare_field(result, 8, "rows", "", MYSQL_TYPE_LONGLONG, - "", "", "", 10, 0); + verify_prepare_field(result, 8, "rows", "", MYSQL_TYPE_VAR_STRING, + "", "", "", NAME_CHAR_LEN, 0); verify_prepare_field(result, 9, "Extra", "", MYSQL_TYPE_VAR_STRING, "", "", "", 255, 0); |