mirror of https://github.com/MariaDB/server
				
				
			
			You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							1053 lines
						
					
					
						
							27 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							1053 lines
						
					
					
						
							27 KiB
						
					
					
				| drop table if exists t0,t1,t2; | |
| create table t0(a int); | |
| insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); | |
| explain format=json select * from t0; | |
| EXPLAIN | |
| { | |
|   "query_block": { | |
|     "select_id": 1, | |
|     "table": { | |
|       "table_name": "t0", | |
|       "access_type": "ALL", | |
|       "rows": 10, | |
|       "filtered": 100 | |
|     } | |
|   } | |
| } | |
| explain format=json select * from t0 where 1>2; | |
| EXPLAIN | |
| { | |
|   "query_block": { | |
|     "select_id": 1, | |
|     "table": { | |
|       "message": "Impossible WHERE" | |
|     } | |
|   } | |
| } | |
| explain format=json select * from t0 where a<3; | |
| EXPLAIN | |
| { | |
|   "query_block": { | |
|     "select_id": 1, | |
|     "table": { | |
|       "table_name": "t0", | |
|       "access_type": "ALL", | |
|       "rows": 10, | |
|       "filtered": 100, | |
|       "attached_condition": "(t0.a < 3)" | |
|     } | |
|   } | |
| } | |
| # Try a basic join | |
| create table t1 (a int, b int, filler char(32), key(a)); | |
| insert into t1  | |
| select  | |
| a.a + b.a* 10 + c.a * 100,  | |
| a.a + b.a* 10 + c.a * 100, | |
| 'filler' | |
| from t0 a, t0 b, t0 c; | |
| explain format=json select * from t0,t1 where t1.a=t0.a; | |
| EXPLAIN | |
| { | |
|   "query_block": { | |
|     "select_id": 1, | |
|     "table": { | |
|       "table_name": "t0", | |
|       "access_type": "ALL", | |
|       "rows": 10, | |
|       "filtered": 100, | |
|       "attached_condition": "(t0.a is not null)" | |
|     }, | |
|     "table": { | |
|       "table_name": "t1", | |
|       "access_type": "ref", | |
|       "possible_keys": ["a"], | |
|       "key": "a", | |
|       "key_length": "5", | |
|       "used_key_parts": ["a"], | |
|       "ref": ["test.t0.a"], | |
|       "rows": 1, | |
|       "filtered": 100 | |
|     } | |
|   } | |
| } | |
| # Try range and index_merge | |
| create table t2 (a1 int, a2 int, b1 int, b2 int, key(a1,a2), key(b1,b2)); | |
| insert into t2 select a,a,a,a from t1; | |
| explain format=json select * from t2 where a1<5; | |
| EXPLAIN | |
| { | |
|   "query_block": { | |
|     "select_id": 1, | |
|     "table": { | |
|       "table_name": "t2", | |
|       "access_type": "range", | |
|       "possible_keys": ["a1"], | |
|       "key": "a1", | |
|       "key_length": "5", | |
|       "used_key_parts": ["a1"], | |
|       "rows": 5, | |
|       "filtered": 100, | |
|       "index_condition": "(t2.a1 < 5)" | |
|     } | |
|   } | |
| } | |
| explain format=json select * from t2 where a1=1 or b1=2; | |
| EXPLAIN | |
| { | |
|   "query_block": { | |
|     "select_id": 1, | |
|     "table": { | |
|       "table_name": "t2", | |
|       "access_type": "index_merge", | |
|       "possible_keys": ["a1", "b1"], | |
|       "key_length": "5,5", | |
|       "index_merge": { | |
|         "sort_union": { | |
|           "range": { | |
|             "key": "a1", | |
|             "used_key_parts": ["a1"] | |
|           }, | |
|           "range": { | |
|             "key": "b1", | |
|             "used_key_parts": ["b1"] | |
|           } | |
|         } | |
|       }, | |
|       "rows": 2, | |
|       "filtered": 100, | |
|       "attached_condition": "((t2.a1 = 1) or (t2.b1 = 2))" | |
|     } | |
|   } | |
| } | |
| explain format=json select * from t2 where a1=1 or (b1=2 and b2=3); | |
| EXPLAIN | |
| { | |
|   "query_block": { | |
|     "select_id": 1, | |
|     "table": { | |
|       "table_name": "t2", | |
|       "access_type": "index_merge", | |
|       "possible_keys": ["a1", "b1"], | |
|       "key_length": "5,10", | |
|       "index_merge": { | |
|         "sort_union": { | |
|           "range": { | |
|             "key": "a1", | |
|             "used_key_parts": ["a1"] | |
|           }, | |
|           "range": { | |
|             "key": "b1", | |
|             "used_key_parts": ["b1", "b2"] | |
|           } | |
|         } | |
|       }, | |
|       "rows": 2, | |
|       "filtered": 100, | |
|       "attached_condition": "((t2.a1 = 1) or ((t2.b1 = 2) and (t2.b2 = 3)))" | |
|     } | |
|   } | |
| } | |
| explain format=json select * from t2 where (a1=1 and a2=1) or  | |
| (b1=2 and b2=1); | |
| EXPLAIN | |
| { | |
|   "query_block": { | |
|     "select_id": 1, | |
|     "table": { | |
|       "table_name": "t2", | |
|       "access_type": "index_merge", | |
|       "possible_keys": ["a1", "b1"], | |
|       "key_length": "10,10", | |
|       "index_merge": { | |
|         "union": { | |
|           "range": { | |
|             "key": "a1", | |
|             "used_key_parts": ["a1", "a2"] | |
|           }, | |
|           "range": { | |
|             "key": "b1", | |
|             "used_key_parts": ["b1", "b2"] | |
|           } | |
|         } | |
|       }, | |
|       "rows": 2, | |
|       "filtered": 100, | |
|       "attached_condition": "(((t2.a1 = 1) and (t2.a2 = 1)) or ((t2.b1 = 2) and (t2.b2 = 1)))" | |
|     } | |
|   } | |
| } | |
| # Try ref access on two key components | |
| explain format=json select * from t0,t2 where t2.b1=t0.a and t2.b2=4; | |
| EXPLAIN | |
| { | |
|   "query_block": { | |
|     "select_id": 1, | |
|     "table": { | |
|       "table_name": "t0", | |
|       "access_type": "ALL", | |
|       "rows": 10, | |
|       "filtered": 100, | |
|       "attached_condition": "(t0.a is not null)" | |
|     }, | |
|     "table": { | |
|       "table_name": "t2", | |
|       "access_type": "ref", | |
|       "possible_keys": ["b1"], | |
|       "key": "b1", | |
|       "key_length": "10", | |
|       "used_key_parts": ["b1", "b2"], | |
|       "ref": ["test.t0.a", "const"], | |
|       "rows": 1, | |
|       "filtered": 100 | |
|     } | |
|   } | |
| } | |
| drop table t1,t2; | |
| # | |
| # Try a UNION | |
| # | |
| explain format=json select * from t0 A union     select * from t0 B; | |
| EXPLAIN | |
| { | |
|   "query_block": { | |
|     "union_result": { | |
|       "table_name": "<union1,2>", | |
|       "access_type": "ALL", | |
|       "query_specifications": [ | |
|         { | |
|           "query_block": { | |
|             "select_id": 1, | |
|             "table": { | |
|               "table_name": "A", | |
|               "access_type": "ALL", | |
|               "rows": 10, | |
|               "filtered": 100 | |
|             } | |
|           } | |
|         }, | |
|         { | |
|           "query_block": { | |
|             "select_id": 2, | |
|             "table": { | |
|               "table_name": "B", | |
|               "access_type": "ALL", | |
|               "rows": 10, | |
|               "filtered": 100 | |
|             } | |
|           } | |
|         } | |
|       ] | |
|     } | |
|   } | |
| } | |
| explain format=json select * from t0 A union all select * from t0 B; | |
| EXPLAIN | |
| { | |
|   "query_block": { | |
|     "union_result": { | |
|       "table_name": "<union1,2>", | |
|       "access_type": "ALL", | |
|       "query_specifications": [ | |
|         { | |
|           "query_block": { | |
|             "select_id": 1, | |
|             "table": { | |
|               "table_name": "A", | |
|               "access_type": "ALL", | |
|               "rows": 10, | |
|               "filtered": 100 | |
|             } | |
|           } | |
|         }, | |
|         { | |
|           "query_block": { | |
|             "select_id": 2, | |
|             "table": { | |
|               "table_name": "B", | |
|               "access_type": "ALL", | |
|               "rows": 10, | |
|               "filtered": 100 | |
|             } | |
|           } | |
|         } | |
|       ] | |
|     } | |
|   } | |
| } | |
| # | |
| # Subqueries | |
| # | |
| create table t1 (a int, b int); | |
| insert into t1 select a,a from t0; | |
| explain format=json select a, a > (select max(b) from t1 where t1.b=t0.a) from t0; | |
| EXPLAIN | |
| { | |
|   "query_block": { | |
|     "select_id": 1, | |
|     "table": { | |
|       "table_name": "t0", | |
|       "access_type": "ALL", | |
|       "rows": 10, | |
|       "filtered": 100 | |
|     }, | |
|     "subqueries": [ | |
|       { | |
|         "query_block": { | |
|           "select_id": 2, | |
|           "table": { | |
|             "table_name": "t1", | |
|             "access_type": "ALL", | |
|             "rows": 10, | |
|             "filtered": 100, | |
|             "attached_condition": "(t1.b = t0.a)" | |
|           } | |
|         } | |
|       } | |
|     ] | |
|   } | |
| } | |
| explain format=json  | |
| select * from t0 where  | |
| a > (select max(b) from t1 where t1.b=t0.a) or a < 3 ; | |
| EXPLAIN | |
| { | |
|   "query_block": { | |
|     "select_id": 1, | |
|     "table": { | |
|       "table_name": "t0", | |
|       "access_type": "ALL", | |
|       "rows": 10, | |
|       "filtered": 100, | |
|       "attached_condition": "((t0.a > (subquery#2)) or (t0.a < 3))" | |
|     }, | |
|     "subqueries": [ | |
|       { | |
|         "query_block": { | |
|           "select_id": 2, | |
|           "table": { | |
|             "table_name": "t1", | |
|             "access_type": "ALL", | |
|             "rows": 10, | |
|             "filtered": 100, | |
|             "attached_condition": "(t1.b = t0.a)" | |
|           } | |
|         } | |
|       } | |
|     ] | |
|   } | |
| } | |
| drop table t1; | |
| # | |
| # Join buffering | |
| # | |
| create table t1 (a int, b int); | |
| insert into t1 select tbl1.a+10*tbl2.a, tbl1.a+10*tbl2.a from t0 tbl1, t0 tbl2; | |
| explain format=json | |
| select * from t1 tbl1, t1 tbl2 where tbl1.a=tbl2.a and tbl1.b < 3 and tbl2.b < 5; | |
| EXPLAIN | |
| { | |
|   "query_block": { | |
|     "select_id": 1, | |
|     "table": { | |
|       "table_name": "tbl1", | |
|       "access_type": "ALL", | |
|       "rows": 100, | |
|       "filtered": 100, | |
|       "attached_condition": "(tbl1.b < 3)" | |
|     }, | |
|     "block-nl-join": { | |
|       "table": { | |
|         "table_name": "tbl2", | |
|         "access_type": "ALL", | |
|         "rows": 100, | |
|         "filtered": 100, | |
|         "attached_condition": "(tbl2.b < 5)" | |
|       }, | |
|       "buffer_type": "flat", | |
|       "buffer_size": "128Kb", | |
|       "join_type": "BNL", | |
|       "attached_condition": "(tbl2.a = tbl1.a)" | |
|     } | |
|   } | |
| } | |
| drop table t1; | |
| # | |
| # Single-table UPDATE/DELETE, INSERT | |
| # | |
| explain format=json delete from t0; | |
| EXPLAIN | |
| { | |
|   "query_block": { | |
|     "select_id": 1, | |
|     "table": { | |
|       "message": "Deleting all rows" | |
|     } | |
|   } | |
| } | |
| explain format=json delete from t0 where 1 > 2; | |
| EXPLAIN | |
| { | |
|   "query_block": { | |
|     "select_id": 1, | |
|     "table": { | |
|       "message": "Impossible WHERE" | |
|     } | |
|   } | |
| } | |
| explain format=json delete from t0 where a < 3; | |
| EXPLAIN | |
| { | |
|   "query_block": { | |
|     "select_id": 1, | |
|     "table": { | |
|       "delete": 1, | |
|       "table_name": "t0", | |
|       "access_type": "ALL", | |
|       "rows": 10, | |
|       "attached_condition": "(t0.a < 3)" | |
|     } | |
|   } | |
| } | |
| explain format=json update t0 set a=3 where a in (2,3,4); | |
| EXPLAIN | |
| { | |
|   "query_block": { | |
|     "select_id": 1, | |
|     "table": { | |
|       "update": 1, | |
|       "table_name": "t0", | |
|       "access_type": "ALL", | |
|       "rows": 10, | |
|       "attached_condition": "(t0.a in (2,3,4))" | |
|     } | |
|   } | |
| } | |
| explain format=json insert into t0 values (1); | |
| EXPLAIN | |
| { | |
|   "query_block": { | |
|     "select_id": 1, | |
|     "table": { | |
|       "table_name": "t0" | |
|     } | |
|   } | |
| } | |
| create table t1 like t0; | |
| explain format=json insert into t1 values ((select max(a) from t0)); | |
| EXPLAIN | |
| { | |
|   "query_block": { | |
|     "select_id": 1, | |
|     "table": { | |
|       "table_name": "t1" | |
|     }, | |
|     "subqueries": [ | |
|       { | |
|         "query_block": { | |
|           "select_id": 2, | |
|           "table": { | |
|             "table_name": "t0", | |
|             "access_type": "ALL", | |
|             "rows": 10, | |
|             "filtered": 100 | |
|           } | |
|         } | |
|       } | |
|     ] | |
|   } | |
| } | |
| drop table t1; | |
| # | |
| # A derived table | |
| # | |
| create table t1 (a int, b int); | |
| insert into t1 select a,a from t0; | |
| explain format=json | |
| select * from (select a, count(*) as cnt from t1 group by a) as tbl | |
| where cnt>0; | |
| EXPLAIN | |
| { | |
|   "query_block": { | |
|     "select_id": 1, | |
|     "table": { | |
|       "table_name": "<derived2>", | |
|       "access_type": "ALL", | |
|       "rows": 10, | |
|       "filtered": 100, | |
|       "attached_condition": "(tbl.cnt > 0)", | |
|       "materialized": { | |
|         "query_block": { | |
|           "select_id": 2, | |
|           "table": { | |
|             "table_name": "t1", | |
|             "access_type": "ALL", | |
|             "rows": 10, | |
|             "filtered": 100 | |
|           } | |
|         } | |
|       } | |
|     } | |
|   } | |
| } | |
| explain format=json | |
| select * from (select a, count(*) as cnt from t1 group by a) as tbl1, t1 as | |
| tbl2 where cnt=tbl2.a; | |
| EXPLAIN | |
| { | |
|   "query_block": { | |
|     "select_id": 1, | |
|     "table": { | |
|       "table_name": "tbl2", | |
|       "access_type": "ALL", | |
|       "rows": 10, | |
|       "filtered": 100, | |
|       "attached_condition": "(tbl2.a is not null)" | |
|     }, | |
|     "table": { | |
|       "table_name": "<derived2>", | |
|       "access_type": "ref", | |
|       "possible_keys": ["key0"], | |
|       "key": "key0", | |
|       "key_length": "8", | |
|       "used_key_parts": ["cnt"], | |
|       "ref": ["test.tbl2.a"], | |
|       "rows": 2, | |
|       "filtered": 100, | |
|       "attached_condition": "(tbl1.cnt = tbl2.a)", | |
|       "materialized": { | |
|         "query_block": { | |
|           "select_id": 2, | |
|           "table": { | |
|             "table_name": "t1", | |
|             "access_type": "ALL", | |
|             "rows": 10, | |
|             "filtered": 100 | |
|           } | |
|         } | |
|       } | |
|     } | |
|   } | |
| } | |
| # | |
| # Non-merged semi-join (aka JTBM) | |
| # | |
| explain format=json  | |
| select * from t1 where a in (select max(a) from t1 group by b); | |
| EXPLAIN | |
| { | |
|   "query_block": { | |
|     "select_id": 1, | |
|     "table": { | |
|       "table_name": "t1", | |
|       "access_type": "ALL", | |
|       "rows": 10, | |
|       "filtered": 100, | |
|       "attached_condition": "(t1.a is not null)" | |
|     }, | |
|     "table": { | |
|       "table_name": "<subquery2>", | |
|       "access_type": "eq_ref", | |
|       "possible_keys": ["distinct_key"], | |
|       "key": "distinct_key", | |
|       "key_length": "4", | |
|       "used_key_parts": ["max(a)"], | |
|       "ref": ["test.t1.a"], | |
|       "rows": 1, | |
|       "filtered": 100, | |
|       "materialized": { | |
|         "unique": 1, | |
|         "query_block": { | |
|           "select_id": 2, | |
|           "table": { | |
|             "table_name": "t1", | |
|             "access_type": "ALL", | |
|             "rows": 10, | |
|             "filtered": 100 | |
|           } | |
|         } | |
|       } | |
|     } | |
|   } | |
| } | |
| # | |
| # Semi-join Materialization | |
| # | |
| create table t2 like t1; | |
| insert into t2 select * from t1; | |
| explain format=json | |
| select * from t1,t2 where t1.a in ( select a from t0); | |
| EXPLAIN | |
| { | |
|   "query_block": { | |
|     "select_id": 1, | |
|     "const_condition": "1", | |
|     "table": { | |
|       "table_name": "t1", | |
|       "access_type": "ALL", | |
|       "rows": 10, | |
|       "filtered": 100 | |
|     }, | |
|     "table": { | |
|       "table_name": "<subquery2>", | |
|       "access_type": "eq_ref", | |
|       "possible_keys": ["distinct_key"], | |
|       "key": "distinct_key", | |
|       "key_length": "4", | |
|       "used_key_parts": ["a"], | |
|       "ref": ["func"], | |
|       "rows": 1, | |
|       "filtered": 100, | |
|       "materialized": { | |
|         "unique": 1, | |
|         "query_block": { | |
|           "select_id": 2, | |
|           "table": { | |
|             "table_name": "t0", | |
|             "access_type": "ALL", | |
|             "rows": 10, | |
|             "filtered": 100 | |
|           } | |
|         } | |
|       } | |
|     }, | |
|     "block-nl-join": { | |
|       "table": { | |
|         "table_name": "t2", | |
|         "access_type": "ALL", | |
|         "rows": 10, | |
|         "filtered": 100 | |
|       }, | |
|       "buffer_type": "flat", | |
|       "buffer_size": "128Kb", | |
|       "join_type": "BNL" | |
|     } | |
|   } | |
| } | |
| #  | |
| # First-Match | |
| #  | |
| explain | |
| select * from t2 where t2.a in ( select a from t1 where t1.b=t2.b); | |
| id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra | |
| 1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	10	 | |
| 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	10	Using where; FirstMatch(t2); Using join buffer (flat, BNL join) | |
| explain format=json | |
| select * from t2 where t2.a in ( select a from t1 where t1.b=t2.b); | |
| EXPLAIN | |
| { | |
|   "query_block": { | |
|     "select_id": 1, | |
|     "table": { | |
|       "table_name": "t2", | |
|       "access_type": "ALL", | |
|       "rows": 10, | |
|       "filtered": 100 | |
|     }, | |
|     "block-nl-join": { | |
|       "table": { | |
|         "table_name": "t1", | |
|         "access_type": "ALL", | |
|         "rows": 10, | |
|         "filtered": 100, | |
|         "first_match": "t2" | |
|       }, | |
|       "buffer_type": "flat", | |
|       "buffer_size": "128Kb", | |
|       "join_type": "BNL", | |
|       "attached_condition": "((t1.b = t2.b) and (t1.a = t2.a))" | |
|     } | |
|   } | |
| } | |
| #  | |
| # Duplicate Weedout | |
| #  | |
| set @tmp= @@optimizer_switch; | |
| set optimizer_switch='firstmatch=off'; | |
| explain | |
| select * from t2 where t2.a in ( select a from t1 where t1.b=t2.b); | |
| id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra | |
| 1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	10	 | |
| 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	10	Using where; Start temporary; End temporary; Using join buffer (flat, BNL join) | |
| explain format=json | |
| select * from t2 where t2.a in ( select a from t1 where t1.b=t2.b); | |
| EXPLAIN | |
| { | |
|   "query_block": { | |
|     "select_id": 1, | |
|     "table": { | |
|       "table_name": "t2", | |
|       "access_type": "ALL", | |
|       "rows": 10, | |
|       "filtered": 100 | |
|     }, | |
|     "duplicates_removal": { | |
|       "block-nl-join": { | |
|         "table": { | |
|           "table_name": "t1", | |
|           "access_type": "ALL", | |
|           "rows": 10, | |
|           "filtered": 100 | |
|         }, | |
|         "buffer_type": "flat", | |
|         "buffer_size": "128Kb", | |
|         "join_type": "BNL", | |
|         "attached_condition": "((t1.b = t2.b) and (t1.a = t2.a))" | |
|       } | |
|     } | |
|   } | |
| } | |
| set optimizer_switch=@tmp; | |
| drop table t1,t2; | |
| # | |
| # MRR for range access (no BKA, just MRR) | |
| # | |
| create table t1 (a int, b int, key(a)); | |
| insert into t1 select tbl1.a+10*tbl2.a, 12345 from t0 tbl1, t0 tbl2; | |
| set @tmp= @@optimizer_switch; | |
| set optimizer_switch='mrr=on,mrr_sort_keys=on'; | |
| explain format=json select * from t1 where a < 3; | |
| EXPLAIN | |
| { | |
|   "query_block": { | |
|     "select_id": 1, | |
|     "table": { | |
|       "table_name": "t1", | |
|       "access_type": "range", | |
|       "possible_keys": ["a"], | |
|       "key": "a", | |
|       "key_length": "5", | |
|       "used_key_parts": ["a"], | |
|       "rows": 1, | |
|       "filtered": 100, | |
|       "index_condition": "(t1.a < 3)", | |
|       "mrr_type": "Rowid-ordered scan" | |
|     } | |
|   } | |
| } | |
| # 'Range checked for each record' | |
| set optimizer_switch=@tmp; | |
| explain format=json | |
| select * from t1 tbl1, t1 tbl2 where tbl2.a < tbl1.b; | |
| EXPLAIN | |
| { | |
|   "query_block": { | |
|     "select_id": 1, | |
|     "table": { | |
|       "table_name": "tbl1", | |
|       "access_type": "ALL", | |
|       "rows": 100, | |
|       "filtered": 100 | |
|     }, | |
|     "range-checked-for-each-record": { | |
|       "keys": ["a"], | |
|       "table": { | |
|         "table_name": "tbl2", | |
|         "access_type": "ALL", | |
|         "possible_keys": ["a"], | |
|         "rows": 100, | |
|         "filtered": 100 | |
|       } | |
|     } | |
|   } | |
| } | |
| drop table t1; | |
| drop table t0; | |
| # | |
| # MDEV-7265: "Full scan on NULL key", the join case | |
| # | |
| CREATE TABLE t1 (a INT, KEY(a)); | |
| INSERT INTO t1 VALUES (1),(2); | |
| CREATE TABLE t2 (b INT); | |
| INSERT INTO t2 VALUES (3),(4); | |
| EXPLAIN FORMAT=JSON SELECT * FROM t1 AS outer_t1 WHERE a <> ALL ( SELECT a FROM t1, t2 WHERE b <> outer_t1.a ); | |
| EXPLAIN | |
| { | |
|   "query_block": { | |
|     "select_id": 1, | |
|     "table": { | |
|       "table_name": "outer_t1", | |
|       "access_type": "index", | |
|       "key": "a", | |
|       "key_length": "5", | |
|       "used_key_parts": ["a"], | |
|       "rows": 2, | |
|       "filtered": 100, | |
|       "attached_condition": "(not(<in_optimizer>(outer_t1.a,<exists>(subquery#2))))", | |
|       "using_index": true | |
|     }, | |
|     "subqueries": [ | |
|       { | |
|         "query_block": { | |
|           "select_id": 2, | |
|           "full-scan-on-null_key": { | |
|             "table": { | |
|               "table_name": "t1", | |
|               "access_type": "ref_or_null", | |
|               "possible_keys": ["a"], | |
|               "key": "a", | |
|               "key_length": "5", | |
|               "used_key_parts": ["a"], | |
|               "ref": ["func"], | |
|               "rows": 2, | |
|               "filtered": 100, | |
|               "attached_condition": "trigcond(((<cache>(outer_t1.a) = t1.a) or isnull(t1.a)))", | |
|               "using_index": true | |
|             } | |
|           }, | |
|           "block-nl-join": { | |
|             "table": { | |
|               "table_name": "t2", | |
|               "access_type": "ALL", | |
|               "rows": 2, | |
|               "filtered": 100 | |
|             }, | |
|             "buffer_type": "flat", | |
|             "buffer_size": "128Kb", | |
|             "join_type": "BNL", | |
|             "attached_condition": "((t2.b <> outer_t1.a) and trigcond(((<cache>(outer_t1.a) = t1.a) or isnull(t1.a))))" | |
|           } | |
|         } | |
|       } | |
|     ] | |
|   } | |
| } | |
| DROP TABLE t1,t2; | |
| # | |
| # Join's constant expression | |
| # | |
| create table t0(a int); | |
| insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); | |
| create table t1(a int, b int); | |
| insert into t1 select tbl1.a+10*tbl2.a, 1234 from t0 tbl1, t0 tbl2; | |
| explain format=json  | |
| select * from t0  | |
| where  | |
| 20000 > all (select max(tbl1.a + tbl2.a) | |
| from t1 tbl1, t1 tbl2 where tbl1.b=tbl2.b); | |
| EXPLAIN | |
| { | |
|   "query_block": { | |
|     "select_id": 1, | |
|     "const_condition": "<not>(<in_optimizer>(20000,(<max>(subquery#2) >= 20000)))", | |
|     "table": { | |
|       "table_name": "t0", | |
|       "access_type": "ALL", | |
|       "rows": 10, | |
|       "filtered": 100 | |
|     }, | |
|     "subqueries": [ | |
|       { | |
|         "query_block": { | |
|           "select_id": 2, | |
|           "table": { | |
|             "table_name": "tbl1", | |
|             "access_type": "ALL", | |
|             "rows": 100, | |
|             "filtered": 100 | |
|           }, | |
|           "block-nl-join": { | |
|             "table": { | |
|               "table_name": "tbl2", | |
|               "access_type": "ALL", | |
|               "rows": 100, | |
|               "filtered": 100 | |
|             }, | |
|             "buffer_type": "flat", | |
|             "buffer_size": "128Kb", | |
|             "join_type": "BNL", | |
|             "attached_condition": "(tbl2.b = tbl1.b)" | |
|           } | |
|         } | |
|       } | |
|     ] | |
|   } | |
| } | |
| drop table t1; | |
| drop table t0; | |
| #  | |
| # MDEV-7264: Assertion `0' failed in subselect_engine::get_identifier() on EXPLAIN JSON | |
| #  | |
| CREATE TABLE t1 (a INT); | |
| INSERT INTO t1 VALUES (1),(2); | |
| CREATE TABLE t2 (b INT); | |
| INSERT INTO t2 VALUES (3),(4); | |
| EXPLAIN FORMAT=JSON SELECT * FROM t1 WHERE a <> ALL ( SELECT b FROM t2 ); | |
| EXPLAIN | |
| { | |
|   "query_block": { | |
|     "select_id": 1, | |
|     "table": { | |
|       "table_name": "t1", | |
|       "access_type": "ALL", | |
|       "rows": 2, | |
|       "filtered": 100, | |
|       "attached_condition": "(not(<in_optimizer>(t1.a,t1.a in (subquery#2))))" | |
|     }, | |
|     "subqueries": [ | |
|       { | |
|         "query_block": { | |
|           "select_id": 2, | |
|           "table": { | |
|             "table_name": "t2", | |
|             "access_type": "ALL", | |
|             "rows": 2, | |
|             "filtered": 100 | |
|           } | |
|         } | |
|       } | |
|     ] | |
|   } | |
| } | |
| DROP TABLE t1, t2; | |
| # | |
| # MDEV-7927: Server crashes in in Time_and_counter_tracker::incr_loops | |
| # | |
| CREATE TABLE t1 (i INT); | |
| INSERT INTO t1 VALUES (1),(2); | |
| EXPLAIN SELECT * FROM t1 WHERE 3 IN ( SELECT 4 UNION SELECT 5 ); | |
| 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	NULL	NULL	NULL	NULL	NULL	NULL	NULL	No tables used | |
| 3	UNION	NULL	NULL	NULL	NULL	NULL	NULL	NULL	No tables used | |
| NULL	UNION RESULT	<union2,3>	ALL	NULL	NULL	NULL	NULL	NULL	 | |
| DROP TABLE t1; | |
| # | |
| # MDEV-7860: EXPLAIN FORMAT=JSON crashes for loose scan query | |
| # | |
| create table t2(a int); | |
| insert into t2 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); | |
| create table t1 (a int, b int, c int, d int, key(a,b,c)); | |
| insert into t1 select  A.a, B.a, C.a, D.a from t2 A, t2 B, t2 C, t2 D; | |
| 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	101	Using index for group-by | |
| explain format=json select count(distinct b) from t1 group by a; | |
| EXPLAIN | |
| { | |
|   "query_block": { | |
|     "select_id": 1, | |
|     "table": { | |
|       "table_name": "t1", | |
|       "access_type": "range", | |
|       "key": "a", | |
|       "key_length": "10", | |
|       "used_key_parts": ["a", "b"], | |
|       "rows": 101, | |
|       "filtered": 100, | |
|       "using_index_for_group_by": true | |
|     } | |
|   } | |
| } | |
| analyze format=json select count(distinct b) from t1 group by a; | |
| ANALYZE | |
| { | |
|   "query_block": { | |
|     "select_id": 1, | |
|     "r_loops": 1, | |
|     "r_total_time_ms": "REPLACED", | |
|     "table": { | |
|       "table_name": "t1", | |
|       "access_type": "range", | |
|       "key": "a", | |
|       "key_length": "10", | |
|       "used_key_parts": ["a", "b"], | |
|       "r_loops": 1, | |
|       "rows": 101, | |
|       "r_rows": 100, | |
|       "r_total_time_ms": "REPLACED", | |
|       "filtered": 100, | |
|       "r_filtered": 100, | |
|       "using_index_for_group_by": true | |
|     } | |
|   } | |
| } | |
| drop table t1,t2; | |
| # | |
| # Try both variants of LooseScan (data/queries borrowed from group_min_max.test) | |
| # | |
| create table t1 ( | |
| a1 char(64), a2 char(64), b char(16), c char(16) not null, d char(16), dummy char(248) default ' ' | |
| ); | |
| insert into t1 (a1, a2, b, c, d) values | |
| ('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'), | |
| ('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'), | |
| ('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'), | |
| ('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'), | |
| ('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'), | |
| ('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'), | |
| ('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'), | |
| ('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'), | |
| ('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'), | |
| ('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'), | |
| ('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'), | |
| ('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4'), | |
| ('d','a','a','a411','xy1'),('d','a','a','b411','xy2'),('d','a','a','c411','xy3'),('d','a','a','d411','xy4'), | |
| ('d','a','b','e412','xy1'),('d','a','b','f412','xy2'),('d','a','b','g412','xy3'),('d','a','b','h412','xy4'), | |
| ('d','b','a','i421','xy1'),('d','b','a','j421','xy2'),('d','b','a','k421','xy3'),('d','b','a','l421','xy4'), | |
| ('d','b','b','m422','xy1'),('d','b','b','n422','xy2'),('d','b','b','o422','xy3'),('d','b','b','p422','xy4'), | |
| ('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'), | |
| ('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'), | |
| ('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'), | |
| ('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'), | |
| ('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'), | |
| ('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'), | |
| ('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'), | |
| ('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'), | |
| ('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'), | |
| ('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'), | |
| ('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'), | |
| ('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4'), | |
| ('d','a','a','a411','xy1'),('d','a','a','b411','xy2'),('d','a','a','c411','xy3'),('d','a','a','d411','xy4'), | |
| ('d','a','b','e412','xy1'),('d','a','b','f412','xy2'),('d','a','b','g412','xy3'),('d','a','b','h412','xy4'), | |
| ('d','b','a','i421','xy1'),('d','b','a','j421','xy2'),('d','b','a','k421','xy3'),('d','b','a','l421','xy4'), | |
| ('d','b','b','m422','xy1'),('d','b','b','n422','xy2'),('d','b','b','o422','xy3'),('d','b','b','p422','xy4'); | |
| create index idx_t1_0 on t1 (a1); | |
| create index idx_t1_1 on t1 (a1,a2,b,c); | |
| create index idx_t1_2 on t1 (a1,a2,b); | |
| analyze table t1; | |
| Table	Op	Msg_type	Msg_text | |
| test.t1	analyze	status	Table is already up to date | |
| explain select count(distinct a1,a2,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	range	NULL	idx_t1_1	147	NULL	17	Using where; Using index for group-by | |
| explain select count(distinct a1,a2,b,c) from t1 where (a2 >= 'b') and (b = 'a') and (c = 'i121'); | |
| 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 format=json select count(distinct a1,a2,b) from t1 where (a2 >= 'b') and (b = 'a'); | |
| EXPLAIN | |
| { | |
|   "query_block": { | |
|     "select_id": 1, | |
|     "table": { | |
|       "table_name": "t1", | |
|       "access_type": "range", | |
|       "key": "idx_t1_1", | |
|       "key_length": "147", | |
|       "used_key_parts": ["a1", "a2", "b"], | |
|       "rows": 17, | |
|       "filtered": 100, | |
|       "attached_condition": "((t1.b = 'a') and (t1.a2 >= 'b'))", | |
|       "using_index_for_group_by": true | |
|     } | |
|   } | |
| } | |
| explain format=json select count(distinct a1,a2,b,c) from t1 where (a2 >= 'b') and (b = 'a') and (c = 'i121'); | |
| EXPLAIN | |
| { | |
|   "query_block": { | |
|     "select_id": 1, | |
|     "table": { | |
|       "table_name": "t1", | |
|       "access_type": "range", | |
|       "key": "idx_t1_1", | |
|       "key_length": "163", | |
|       "used_key_parts": ["a1", "a2", "b", "c"], | |
|       "rows": 65, | |
|       "filtered": 100, | |
|       "attached_condition": "((t1.b = 'a') and (t1.c = 'i121') and (t1.a2 >= 'b'))", | |
|       "using_index_for_group_by": "scanning" | |
|     } | |
|   } | |
| } | |
| drop table t1;
 |