1 # Test for optimizer tracing of range analysis
3 --source include/have_optimizer_trace.inc
4 # InnoDB page size influences cost => makes trace vary.
5 --source include/have_innodb_16k.inc
7 SET optimizer_trace_max_mem_size=1048576; # 1MB
8 SET end_markers_in_json=on;
9 SET optimizer_trace=
"enabled=on,one_line=off";
17 --echo Inserting 1024 records into t1
20 INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8);
26 EVAL INSERT INTO t1 SELECT key1+@d FROM t1;
32 ALTER
TABLE t1 ADD key2 INT NOT NULL, ADD INDEX i2(key2);
33 ALTER
TABLE t1 ADD key3 INT NOT NULL, ADD INDEX i3(key3);
34 ALTER
TABLE t1 ADD key4 INT NOT NULL, ADD INDEX i4(key4);
35 ALTER
TABLE t1 ADD key5 INT NOT NULL, ADD INDEX i5(key5);
36 ALTER
TABLE t1 ADD key6 INT NOT NULL, ADD INDEX i6(key6);
37 ALTER
TABLE t1 ADD key7 INT NOT NULL, ADD INDEX i7(key7);
38 ALTER
TABLE t1 ADD key8 INT NOT NULL, ADD INDEX i8(key8);
56 primary key i1a (key1a, key1b),
57 INDEX i1b (key1b, key1a),
58 INDEX i2_1(key2, key2_1),
59 INDEX i2_2(key2, key2_1)
62 INSERT INTO t2 SELECT key1,key1,key1 div 10, key1 % 10, key1 % 10, key1 FROM t1;
64 # multiple ranges on one key
66 EXPLAIN SELECT * FROM t1 WHERE key2 < 5 OR key2 > 1020;
68 SELECT * FROM information_schema.OPTIMIZER_TRACE;
70 # multiple ranges on one key, turn off range_optimizer tracing
71 set @@optimizer_trace_features=
"range_optimizer=off";
73 EXPLAIN SELECT * FROM t1 WHERE key2 < 5 OR key2 > 1020;
75 SELECT * FROM information_schema.OPTIMIZER_TRACE;
76 set @@optimizer_trace_features=
"range_optimizer=on";
81 EXPLAIN SELECT * FROM t1 WHERE key1 < 3 OR key2 > 1020;
83 SELECT * FROM information_schema.OPTIMIZER_TRACE;
87 EXPLAIN SELECT key2, MIN(key2_1) FROM t2 GROUP BY key2;
89 SELECT * FROM information_schema.OPTIMIZER_TRACE;
91 # distinct - group quick select without grouping attribute
92 EXPLAIN SELECT DISTINCT key2 FROM t2;
94 SELECT * FROM information_schema.OPTIMIZER_TRACE;
98 EXPLAIN SELECT key2, MIN(key2_1) FROM t2
99 WHERE key2 = 5 or key2 = 4 or key2 = 3 or key2 = 2 or key2 = 1
102 SELECT * FROM information_schema.OPTIMIZER_TRACE;
106 EXPLAIN SELECT * FROM t2 WHERE key2 = 1 AND (key2_1 = 1 OR key3 = 5);
108 SELECT * FROM information_schema.OPTIMIZER_TRACE;
112 EXPLAIN SELECT * FROM t1 WHERE key2=10 OR key3=3 OR key4 <=> null;
114 SELECT * FROM information_schema.OPTIMIZER_TRACE;
116 # range_scan_possible=false
118 EXPLAIN SELECT * FROM t2 WHERE key2_1 < 79 OR key2 = 2;
120 SELECT * FROM information_schema.OPTIMIZER_TRACE;
122 # Multiple key parts in same index
124 EXPLAIN SELECT * FROM t2 WHERE key1a = 5 and key1b < 10;
126 SELECT * FROM information_schema.OPTIMIZER_TRACE;
128 # Multiple ranges on key parts in same index
130 EXPLAIN SELECT * FROM t2 WHERE (key1a = 5 and key1b < 10 and key1b > 2) or
131 (key1a = 4 and key1b < 7 and key1b > 3);
133 SELECT * FROM information_schema.OPTIMIZER_TRACE;
135 # Multiple ranges on key parts in same index
137 EXPLAIN SELECT * FROM t2 WHERE (key1b < 10 and key1b > 7) and
138 (key1a = 4 or key1a = 5);
140 SELECT * FROM information_schema.OPTIMIZER_TRACE;
142 # more_expensive_than_table_scan
144 EXPLAIN SELECT * FROM t1 WHERE (key1 > 1 OR key2 > 2);
146 SELECT * FROM information_schema.OPTIMIZER_TRACE;
148 # Range analysis on straight join
150 EXPLAIN SELECT STRAIGHT_JOIN * FROM t1, t2
151 WHERE t1.key1=t2.key1a AND t1.key2 > 1020;
153 SELECT * FROM information_schema.OPTIMIZER_TRACE;
158 cola
char(3) not null,
159 colb
char(3) not null,
164 INSERT INTO t1 VALUES (
'foo',
'bar',
'ZZ'),(
'fuz',
'baz',
'ZZ');
166 --echo Inserting records
171 eval INSERT INTO t1 SELECT * FROM t1 WHERE cola =
'foo';
177 eval INSERT INTO t1 SELECT * FROM t1 WHERE cola <>
'foo';
184 # Index roworder intersect
185 EXPLAIN SELECT * FROM t1 WHERE cola =
'foo' AND colb =
'bar';
187 SELECT * FROM information_schema.OPTIMIZER_TRACE;
190 # Range with escaped character should be printed escaped
191 EXPLAIN SELECT * FROM t1 WHERE cola =
'f\no';
193 SELECT * FROM information_schema.OPTIMIZER_TRACE;
197 # Test that range optimization is not shown for every outer record
198 # when there is a dynamic range.
199 CREATE
TABLE t1(c INT);
200 INSERT INTO t1 VALUES (),();
202 INSERT INTO t2 VALUES (),(),();
204 # First, enable dynamic range optimization tracing
205 SET optimizer_trace_features=
"greedy_search=off,dynamic_range=on";
206 EXPLAIN SELECT 1 FROM
207 (SELECT 1 FROM t2,t1 WHERE b < c GROUP BY 1 LIMIT 1) AS d2;
209 SELECT * FROM information_schema.OPTIMIZER_TRACE;
212 # Second, disable dynamic range optimization tracing
213 SET optimizer_trace_features=
"greedy_search=off,dynamic_range=off";
214 EXPLAIN SELECT 1 FROM
215 (SELECT 1 FROM t2,t1 WHERE b < c GROUP BY 1 LIMIT 1) AS d2;
217 SELECT * FROM information_schema.OPTIMIZER_TRACE;
222 SET optimizer_trace_features=
default;
224 # Range analysis in test_if_skip_sort_order
225 # (records_estimation_for_index_ordering)
233 INSERT INTO t1 VALUES (0,1,
'2'),(3,2,
'1');
235 EXPLAIN SELECT * FROM t1 WHERE i1 >
'2' ORDER BY i1, i2;
237 SELECT * FROM information_schema.OPTIMIZER_TRACE;
240 EXPLAIN SELECT DISTINCT i1 FROM t1 WHERE i1 >=
'1' ORDER BY i1 DESC;
242 SELECT * FROM information_schema.OPTIMIZER_TRACE;
247 # Analyze whether to use covering roworder intersect
257 INSERT INTO t1 VALUES (1, 1, 9,'a'), (2, 2, 8,'b'), (3, 3, 7,'c'),
258 (4, 4, 6,'d'), (5, 5, 5,'e');
261 -- disable_result_log
267 --echo
# Covering ROR intersect not chosen: only one scan used
268 EXPLAIN SELECT v FROM t1 WHERE i1 = 1 AND v =
'a' AND pk < 3;
270 SELECT * FROM information_schema.OPTIMIZER_TRACE;
272 DROP INDEX i1_idx ON t1;
273 CREATE INDEX i1_i2_idx ON t1 (i2,i1);
278 --echo # Covering ROR intersect not chosen: cost
279 EXPLAIN SELECT v FROM t1 WHERE i1 = 1 AND i2 = 1 AND v =
'a' AND pk < 3;
281 SELECT * FROM information_schema.OPTIMIZER_TRACE;
283 # Todo: make a test case that chooses ROR intersect
288 # Optimizer first decides to use ref, then changes mind to use range instead
289 CREATE
TABLE t1 (a
int, b
int, PRIMARY KEY (a,b), KEY b (b)) ENGINE=InnoDB STATS_PERSISTENT=0;
290 INSERT INTO t1 VALUES (1,1),(1,2),(1,0),(1,3);
292 # -- disable_query_log
293 # -- disable_result_log
295 # -- enable_result_log
296 # -- enable_query_log
299 --echo #
Test trace
for "access_type_changed 'ref' to 'range'"
300 EXPLAIN SELECT MAX(b), a FROM t1 WHERE b < 2 AND a = 1 GROUP BY a;
302 SELECT * FROM information_schema.OPTIMIZER_TRACE;
309 --echo
# index and we abandon ICP,
310 --echo # see
"disabling_pushed_condition_on_old_index" in trace.
314 c1 VARCHAR(2) NOT NULL,
316 c2 VARCHAR(2) NOT NULL,
321 INSERT INTO t1 VALUES (
'0',3,
'0'),(
'0',2,
'1');
323 EXPLAIN SELECT * FROM t1 WHERE c1 =
'1' ORDER BY i1;
325 SELECT * FROM information_schema.OPTIMIZER_TRACE;