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.

521 lines
20 KiB

Fixed bug mdev-3913. The wrong result set returned by the left join query from the bug test case happened due to several inconsistencies and bugs of the legacy mysql code. The bug test case uses an execution plan that employs a scan of a materialized IN subquery from the WHERE condition. When materializing such an IN- subquery the optimizer injects additional equalities into the WHERE clause. These equalities express the constraints imposed by the subquery predicate. The injected equality of the query in the test case happens to belong to the same equality class, and a new equality imposing a condition on the rows of the materialized subquery is inferred from this class. Simultaneously the multiple equality is added to the ON expression of the LEFT JOIN used in the main query. The inferred equality of the form f1=f2 is taken into account when optimizing the scan of the rows the temporary table that is the result of the subquery materialization: only the values of the field f1 are read from the table into the record buffer. Meanwhile the inferred equality is removed from the WHERE conditions altogether as a constraint on the fields of the temporary table that has been used when filling this table. This equality is supposed to be removed from the ON expression when the multiple equalities of the ON expression are converted into an optimal set of equality predicates. It supposed to be removed from the ON expression as an equality inferred from only equalities of the WHERE condition. Yet, it did not happened due to the following bug in the code. Erroneously the code tried to build multiple equality for ON expression twice: the first time, when it called optimize_cond() for the WHERE condition, the second time, when it called this function for the HAVING condition. When executing optimize_con() for the WHERE condition a reference to the multiple equality of the WHERE condition is set in the multiple equality of the ON expression. This reference would allow later to convert multiple equalities of the ON expression into equality predicates. However the the second call of build_equal_items() for the ON expression that happened when optimize_cond() was called for the HAVING condition reset this reference to NULL. This bug fix blocks calling build_equal_items() for ON expressions for the second time. In general, it will be beneficial for many queries as it removes from ON expressions any equalities that are to be checked for the WHERE condition. The patch also fixes two bugs in the list manipulation operations and a bug in the function substitute_for_best_equal_field() that resulted in passing wrong reference to the multiple equalities of where conditions when processing multiple equalities of ON expressions. The code of substitute_for_best_equal_field() and the code the helper function eliminate_item_equal() were also streamlined and cleaned up. Now the conversion of the multiple equalities into an optimal set of equality predicates first produces the sequence of the all equalities processing multiple equalities one by one, and, only after this, it inserts the equalities at the beginning of the other conditions. The multiple changes in the output of EXPLAIN EXTENDED are mainly the result of this streamlining, but in some cases is the result of the removal of unneeded equalities from ON expressions. In some test cases this removal were reflected in the output of EXPLAIN resulted in disappearance of “Using where” in some rows of the execution plans.
13 years ago
Patch for mdev-287: CHEAP SQ: A query with subquery in SELECT list, EXISTS, inner joins takes hundreds times longer Analysis: The fix for lp:944706 introduces early subquery optimization. While a subquery is being optimized some of its predicates may be removed. In the test case, the EXISTS subquery is constant, and is evaluated to TRUE. As a result the whole OR is TRUE, and thus the correlated condition "b = alias1.b" is optimized away. The subquery becomes non-correlated. The subquery cache is designed to work only for correlated subqueries. If constant subquery optimization is disallowed, then the constant subquery is not evaluated, the subquery remains correlated, and its execution is cached. As a result execution is fast. However, when the constant subquery was optimized away, it was neither cached by the subquery cache, nor it was cached by the internal subquery caching. The latter was due to the fact that the subquery still appeared as correlated to the subselect_XYZ_engine::exec methods, and they re-executed the subquery on each call to Item_subselect::exec. Solution: The solution is to update the correlated status of the subquery after it has been optimized. This status consists of: - st_select_lex::is_correlated - Item_subselect::is_correlated - SELECT_LEX::uncacheable - SELECT_LEX_UNIT::uncacheable The status is updated by st_select_lex::update_correlated_cache(), and its caller st_select_lex::optimize_unflattened_subqueries. The solution relies on the fact that the optimizer already called st_select_lex::update_used_tables() for each subquery. This allows to efficiently update the correlated status of each subquery without walking the whole subquery tree. Notice that his patch is an improvement over MySQL 5.6 and older, where subqueries are not pre-optimized, and the above analysis is not possible.
14 years ago
15 years ago
14 years ago
15 years ago
15 years ago
  1. #
  2. # LP BUG#643424 valgrind warning in choose_subquery_plan()
  3. #
  4. CREATE TABLE t1 (
  5. pk int(11) NOT NULL AUTO_INCREMENT,
  6. c1 int(11) DEFAULT NULL,
  7. c2 int(11) DEFAULT NULL,
  8. PRIMARY KEY (pk),
  9. KEY c2 (c2));
  10. INSERT INTO t1 VALUES (1,NULL,2);
  11. INSERT INTO t1 VALUES (2,7,9);
  12. INSERT INTO t1 VALUES (9,NULL,8);
  13. CREATE TABLE t2 (
  14. pk int(11) NOT NULL AUTO_INCREMENT,
  15. c1 int(11) DEFAULT NULL,
  16. c2 int(11) DEFAULT NULL,
  17. PRIMARY KEY (pk),
  18. KEY c2 (c2));
  19. INSERT INTO t2 VALUES (1,1,7);
  20. set @save_optimizer_switch=@@optimizer_switch;
  21. set @@optimizer_switch='materialization=on,in_to_exists=on,semijoin=off';
  22. SELECT pk FROM t1 WHERE (c2, c1) IN (SELECT c2, c2 FROM t2);
  23. pk
  24. set session optimizer_switch=@save_optimizer_switch;
  25. drop table t1, t2;
  26. #
  27. # LP BUG#652727 Crash in create_ref_for_key()
  28. #
  29. CREATE TABLE t2 (
  30. pk int(11) NOT NULL AUTO_INCREMENT,
  31. c1 int(11) DEFAULT NULL,
  32. PRIMARY KEY (pk));
  33. INSERT INTO t2 VALUES (10,7);
  34. INSERT INTO t2 VALUES (11,1);
  35. INSERT INTO t2 VALUES (17,NULL);
  36. CREATE TABLE t1 (
  37. pk int(11) NOT NULL AUTO_INCREMENT,
  38. c1 int(11) DEFAULT NULL,
  39. PRIMARY KEY (pk));
  40. INSERT INTO t1 VALUES (15,1);
  41. INSERT INTO t1 VALUES (19,NULL);
  42. CREATE TABLE t3 (c2 int(11) DEFAULT NULL, KEY c2 (c2));
  43. INSERT INTO t3 VALUES (1);
  44. set @save_optimizer_switch=@@optimizer_switch;
  45. set @@optimizer_switch='materialization=on,in_to_exists=on,semijoin=off';
  46. SELECT c2
  47. FROM t3
  48. WHERE (2, 6) IN (SELECT t1.c1, t1.c1 FROM t1 STRAIGHT_JOIN t2 ON t2.pk = t1.pk);
  49. c2
  50. set session optimizer_switch=@save_optimizer_switch;
  51. drop table t1, t2, t3;
  52. #
  53. # LP BUG#641245 Crash in Item_equal::contains
  54. #
  55. CREATE TABLE t1 (
  56. pk int(11) NOT NULL AUTO_INCREMENT,
  57. c1 int(11) DEFAULT NULL,
  58. c2 int(11) DEFAULT NULL,
  59. c3 varchar(1) DEFAULT NULL,
  60. c4 varchar(1) DEFAULT NULL,
  61. PRIMARY KEY (pk),
  62. KEY c2 (c2),
  63. KEY c3 (c3,c2));
  64. INSERT INTO t1 VALUES (10,7,8,'v','v');
  65. INSERT INTO t1 VALUES (11,1,9,'r','r');
  66. INSERT INTO t1 VALUES (12,5,9,'a','a');
  67. INSERT INTO t1 VALUES (13,7,18,'v','v');
  68. INSERT INTO t1 VALUES (14,1,19,'r','r');
  69. INSERT INTO t1 VALUES (15,5,29,'a','a');
  70. INSERT INTO t1 VALUES (17,7,38,'v','v');
  71. INSERT INTO t1 VALUES (18,1,39,'r','r');
  72. INSERT INTO t1 VALUES (19,5,49,'a','a');
  73. create table t1a like t1;
  74. insert into t1a select * from t1;
  75. create table t1b like t1;
  76. insert into t1b select * from t1;
  77. CREATE TABLE t2 (
  78. pk int(11) NOT NULL AUTO_INCREMENT,
  79. c1 int(11) DEFAULT NULL,
  80. c2 int(11) DEFAULT NULL,
  81. c3 varchar(1) DEFAULT NULL,
  82. c4 varchar(1) DEFAULT NULL,
  83. PRIMARY KEY (pk),
  84. KEY c2 (c2),
  85. KEY c3 (c3,c2));
  86. INSERT INTO t2 VALUES (1,NULL,2,'w','w');
  87. INSERT INTO t2 VALUES (2,7,9,'m','m');
  88. set @@optimizer_switch='materialization=off,in_to_exists=on,semijoin=off';
  89. EXPLAIN EXTENDED SELECT pk
  90. FROM t1
  91. WHERE c1 IN
  92. (SELECT t1a.c1
  93. FROM (t1b JOIN t2 ON t2.c3 = t1b.c4) LEFT JOIN
  94. t1a ON (t1a.c2 = t1b.pk AND 2)
  95. WHERE t1.pk) ;
  96. id select_type table type possible_keys key key_len ref rows filtered Extra
  97. 1 PRIMARY t1 ALL NULL NULL NULL NULL 9 100.00 Using where
  98. 2 DEPENDENT SUBQUERY t1b ALL NULL NULL NULL NULL 9 100.00
  99. 2 DEPENDENT SUBQUERY t1a ref c2 c2 5 test.t1b.pk 1 100.00 Using where
  100. 2 DEPENDENT SUBQUERY t2 index c3 c3 9 NULL 2 100.00 Using where; Using index; Using join buffer (flat, BNL join)
  101. Warnings:
  102. Note 1276 Field or reference 'test.t1.pk' of SELECT #2 was resolved in SELECT #1
  103. Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` where <expr_cache><`test`.`t1`.`c1`,`test`.`t1`.`pk`>(<in_optimizer>(`test`.`t1`.`c1`,<exists>(select `test`.`t1a`.`c1` from `test`.`t1b` join `test`.`t2` left join `test`.`t1a` on(((`test`.`t1a`.`c2` = `test`.`t1b`.`pk`) and 2)) where ((`test`.`t1`.`pk` <> 0) and (<cache>(`test`.`t1`.`c1`) = `test`.`t1a`.`c1`) and (`test`.`t2`.`c3` = `test`.`t1b`.`c4`)))))
  104. SELECT pk
  105. FROM t1
  106. WHERE c1 IN
  107. (SELECT t1a.c1
  108. FROM (t1b JOIN t2 ON t2.c3 = t1b.c4) LEFT JOIN
  109. t1a ON (t1a.c2 = t1b.pk AND 2)
  110. WHERE t1.pk) ;
  111. pk
  112. DROP TABLE t1, t1a, t1b, t2;
  113. #
  114. # LP BUG#714808 Assertion `outer_lookup_keys <= outer_record_count'
  115. # failed with materialization
  116. CREATE TABLE t1 ( pk int(11), PRIMARY KEY (pk)) ;
  117. CREATE TABLE t2 ( f2 int(11)) ;
  118. CREATE TABLE t3 ( f1 int(11), f3 varchar(1), KEY (f1)) ;
  119. INSERT INTO t3 VALUES (7,'f');
  120. set @@optimizer_switch='materialization=on,in_to_exists=on,semijoin=off';
  121. EXPLAIN
  122. SELECT t1.*
  123. FROM t3 RIGHT JOIN t1 ON t1.pk = t3.f1
  124. WHERE t3.f3 OR ( 3 ) IN ( SELECT f2 FROM t2 );
  125. id select_type table type possible_keys key key_len ref rows Extra
  126. 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
  127. 2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
  128. SELECT t1.*
  129. FROM t3 RIGHT JOIN t1 ON t1.pk = t3.f1
  130. WHERE t3.f3 OR ( 3 ) IN ( SELECT f2 FROM t2 );
  131. pk
  132. drop table t1,t2,t3;
  133. #
  134. # LP BUG#714999 Second crash in select_describe() with nested subqueries
  135. #
  136. CREATE TABLE t1 ( pk int(11)) ;
  137. INSERT INTO t1 VALUES (29);
  138. CREATE TABLE t2 ( f1 varchar(1)) ;
  139. INSERT INTO t2 VALUES ('f'),('d');
  140. CREATE TABLE t3 ( f2 varchar(1)) ;
  141. EXPLAIN SELECT f2 FROM t3 WHERE (
  142. SELECT MAX( pk ) FROM t1
  143. WHERE EXISTS (
  144. SELECT max(f1)
  145. FROM t2 GROUP BY f1
  146. )
  147. ) IS NULL ;
  148. id select_type table type possible_keys key key_len ref rows Extra
  149. 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
  150. 2 SUBQUERY t1 system NULL NULL NULL NULL 1
  151. 3 SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
  152. drop table t1, t2, t3;
  153. #
  154. # LP BUG#715034 Item_sum_distinct::clear(): Assertion `tree != 0' failed
  155. #
  156. CREATE TABLE t2 ( f2 int(11)) ;
  157. CREATE TABLE t1 ( f3 int(11), KEY (f3)) ;
  158. INSERT INTO t1 VALUES (6),(4);
  159. set @tmp_optimizer_switch=@@optimizer_switch;
  160. set optimizer_switch='derived_merge=off,derived_with_keys=off';
  161. EXPLAIN
  162. SELECT * FROM (SELECT * FROM t2) AS a2
  163. WHERE (SELECT distinct SUM(distinct f3 ) FROM t1);
  164. id select_type table type possible_keys key key_len ref rows Extra
  165. 1 PRIMARY <derived2> system NULL NULL NULL NULL 0 const row not found
  166. 3 SUBQUERY t1 index NULL f3 5 NULL 2 Using index
  167. 2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
  168. insert into t2 values (1),(2);
  169. EXPLAIN
  170. SELECT * FROM (SELECT * FROM t2) AS a2
  171. WHERE (SELECT distinct SUM(distinct f3 ) FROM t1);
  172. id select_type table type possible_keys key key_len ref rows Extra
  173. 1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
  174. 3 SUBQUERY t1 index NULL f3 5 NULL 2 Using index
  175. 2 DERIVED t2 ALL NULL NULL NULL NULL 2
  176. set optimizer_switch=@tmp_optimizer_switch;
  177. drop table t1,t2;
  178. #
  179. # LP BUG#715027 Assertion `!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))' failed
  180. #
  181. CREATE TABLE t1 ( f1 int(11), PRIMARY KEY (f1)) ;
  182. INSERT INTO t1 VALUES (28),(29);
  183. CREATE TABLE t2 ( f2 int(11), f3 int(11), f10 varchar(1)) ;
  184. INSERT INTO t2 VALUES (NULL,6,'f'),(4,2,'d');
  185. set @tmp_optimizer_switch=@@optimizer_switch;
  186. set optimizer_switch='derived_merge=off,derived_with_keys=off';
  187. EXPLAIN
  188. SELECT alias2.f2 AS field1
  189. FROM t1 AS alias1 JOIN ( SELECT * FROM t2 ) AS alias2 ON alias2.f3 = alias1.f1
  190. WHERE (
  191. SELECT t2.f2
  192. FROM t2 JOIN t1 ON t1.f1
  193. WHERE t1.f1 AND alias2.f10
  194. )
  195. ORDER BY field1 ;
  196. id select_type table type possible_keys key key_len ref rows Extra
  197. 1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 Using where; Using filesort
  198. 1 PRIMARY alias1 eq_ref PRIMARY PRIMARY 4 alias2.f3 1 Using index
  199. 3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2
  200. 3 DEPENDENT SUBQUERY t1 index PRIMARY PRIMARY 4 NULL 2 Using where; Using index; Using join buffer (flat, BNL join)
  201. 2 DERIVED t2 ALL NULL NULL NULL NULL 2
  202. SELECT alias2.f2 AS field1
  203. FROM t1 AS alias1 JOIN ( SELECT * FROM t2 ) AS alias2 ON alias2.f3 = alias1.f1
  204. WHERE (
  205. SELECT t2.f2
  206. FROM t2 JOIN t1 ON t1.f1
  207. WHERE t1.f1 AND alias2.f10
  208. )
  209. ORDER BY field1 ;
  210. field1
  211. Warnings:
  212. Warning 1292 Truncated incorrect DOUBLE value: 'f'
  213. Warning 1292 Truncated incorrect DOUBLE value: 'd'
  214. set optimizer_switch=@tmp_optimizer_switch;
  215. drop table t1,t2;
  216. #
  217. # LP BUG#718578 Yet another Assertion `!table ||
  218. # (!table->read_set || bitmap_is_set(table->read_set, field_index))'
  219. CREATE TABLE t1 ( f1 int(11), f2 int(11), f3 int(11)) ;
  220. INSERT IGNORE INTO t1 VALUES (28,5,6),(29,NULL,4);
  221. CREATE TABLE t2 ( f10 varchar(1) );
  222. INSERT IGNORE INTO t2 VALUES (NULL);
  223. SELECT f1 AS field1
  224. FROM ( SELECT * FROM t1 ) AS alias1
  225. WHERE (SELECT t1.f1
  226. FROM t2 JOIN t1 ON t1.f2
  227. WHERE alias1.f3 AND t1.f3) AND f2
  228. ORDER BY field1;
  229. field1
  230. 28
  231. drop table t1,t2;
  232. #
  233. # LP BUG#601124 Bug in eliminate_item_equal
  234. # leads to crash in Item_func::Item_func
  235. CREATE TABLE t1 ( f1 int(11), f3 varchar(1)) ;
  236. INSERT INTO t1 VALUES (5,'m'),(NULL,'c');
  237. CREATE TABLE t2 ( f2 int(11), f3 varchar(1)) ;
  238. INSERT INTO t2 VALUES (6,'f'),(2,'d');
  239. CREATE TABLE t3 ( f2 int(11), f3 varchar(1)) ;
  240. INSERT INTO t3 VALUES (6,'f'),(2,'d');
  241. SELECT * FROM t3
  242. WHERE ( f2 ) IN (SELECT t1.f1
  243. FROM t1 STRAIGHT_JOIN t2 ON t2.f3 = t1.f3
  244. WHERE t2.f3 = 'c');
  245. f2 f3
  246. drop table t1,t2,t3;
  247. #
  248. # LP BUG#718593 Crash in substitute_for_best_equal_field -> eliminate_item_equal ->
  249. # Item_field::find_item_equal -> Item_equal::contains
  250. #
  251. set @save_optimizer_switch=@@optimizer_switch;
  252. SET @@optimizer_switch = 'semijoin=off';
  253. CREATE TABLE t1 ( f3 int(11), f10 varchar(1), f11 varchar(1)) ;
  254. INSERT IGNORE INTO t1 VALUES (6,'f','f'),(2,'d','d');
  255. CREATE TABLE t2 ( f12 int(11), f13 int(11)) ;
  256. insert into t2 values (1,2), (3,4);
  257. EXPLAIN
  258. SELECT * FROM t2
  259. WHERE ( f12 ) IN (
  260. SELECT alias2.f3
  261. FROM t1 AS alias1 JOIN t1 AS alias2 ON alias2.f10 = alias1.f11
  262. WHERE alias1.f11 OR alias1.f3 = 50 AND alias1.f10
  263. );
  264. id select_type table type possible_keys key key_len ref rows Extra
  265. 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
  266. 2 MATERIALIZED alias1 ALL NULL NULL NULL NULL 2 Using where
  267. 2 MATERIALIZED alias2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
  268. SELECT * FROM t2
  269. WHERE ( f12 ) IN (
  270. SELECT alias2.f3
  271. FROM t1 AS alias1 JOIN t1 AS alias2 ON alias2.f10 = alias1.f11
  272. WHERE alias1.f11 OR alias1.f3 = 50 AND alias1.f10
  273. );
  274. f12 f13
  275. Warnings:
  276. Warning 1292 Truncated incorrect DOUBLE value: 'f'
  277. Warning 1292 Truncated incorrect DOUBLE value: 'd'
  278. EXPLAIN
  279. SELECT * FROM t2
  280. WHERE ( f12 ) IN (
  281. SELECT alias2.f3
  282. FROM t1 AS alias1, t1 AS alias2
  283. WHERE (alias2.f10 = alias1.f11) AND (alias1.f11 OR alias1.f3 = 50 AND alias1.f10));
  284. id select_type table type possible_keys key key_len ref rows Extra
  285. 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
  286. 2 MATERIALIZED alias1 ALL NULL NULL NULL NULL 2 Using where
  287. 2 MATERIALIZED alias2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
  288. SELECT * FROM t2
  289. WHERE ( f12 ) IN (
  290. SELECT alias2.f3
  291. FROM t1 AS alias1, t1 AS alias2
  292. WHERE (alias2.f10 = alias1.f11) AND (alias1.f11 OR alias1.f3 = 50 AND alias1.f10));
  293. f12 f13
  294. Warnings:
  295. Warning 1292 Truncated incorrect DOUBLE value: 'f'
  296. Warning 1292 Truncated incorrect DOUBLE value: 'd'
  297. set @@optimizer_switch=@save_optimizer_switch;
  298. drop table t1, t2;
  299. #
  300. # MWL#89: test introduced after Sergey Petrunia's review - test that
  301. # keyparts wihtout index prefix are used with the IN-EXISTS strategy.
  302. #
  303. create table t1 (c1 int);
  304. insert into t1 values (1), (2), (3);
  305. create table t2 (kp1 int, kp2 int, c2 int, filler char(100));
  306. insert into t2 values (0,0,0,'filler'),(0,1,1,'filler'),(0,2,2,'filler'),(0,3,3,'filler');
  307. create index key1 on t2 (kp1, kp2);
  308. create index key2 on t2 (kp1);
  309. create index key3 on t2 (kp2);
  310. SET @@optimizer_switch='materialization=off,semijoin=off,in_to_exists=on';
  311. analyze table t2;
  312. Table Op Msg_type Msg_text
  313. test.t2 analyze status OK
  314. explain
  315. select c1 from t1 where c1 in (select kp1 from t2 where kp2 = 10 and c2 = 4) or c1 > 7;
  316. id select_type table type possible_keys key key_len ref rows Extra
  317. 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
  318. 2 DEPENDENT SUBQUERY t2 index_subquery key1,key2,key3 key1 10 func,const 1 Using where
  319. select c1 from t1 where c1 in (select kp1 from t2 where kp2 = 10 and c2 = 4) or c1 > 7;
  320. c1
  321. set @@optimizer_switch='default';
  322. drop table t1, t2;
  323. #
  324. # LP BUG#800679: Assertion `outer_join->table_count > 0' failed in
  325. # JOIN::choose_subquery_plan() with materialization=on,semijoin=off
  326. #
  327. CREATE TABLE t1 ( f1 int);
  328. insert into t1 values (1),(2);
  329. CREATE TABLE t2 ( f1 int);
  330. insert into t2 values (1),(2);
  331. SET @@optimizer_switch='materialization=on,semijoin=off';
  332. EXPLAIN
  333. SELECT * FROM t1
  334. WHERE (f1) IN (SELECT f1 FROM t2)
  335. LIMIT 0;
  336. id select_type table type possible_keys key key_len ref rows Extra
  337. 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Zero limit
  338. 2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
  339. SELECT * FROM t1
  340. WHERE (f1) IN (SELECT f1 FROM t2)
  341. LIMIT 0;
  342. f1
  343. set @@optimizer_switch='default';
  344. drop table t1, t2;
  345. #
  346. # LP BUG#834492: Crash in fix_semijoin_strategies_for_picked_join_order
  347. # with nested subqueries and LooseScan=ON
  348. #
  349. CREATE TABLE t3 (b int) ;
  350. INSERT INTO t3 VALUES (0),(0);
  351. CREATE TABLE t4 (a int, b int, c int, d int, PRIMARY KEY (a)) ;
  352. INSERT INTO t4 VALUES (28,0,0,0),(29,3,0,0);
  353. CREATE TABLE t5 (a int, b int, c int, d int, KEY (c,b)) ;
  354. INSERT INTO t5 VALUES (28,0,0,0),(29,3,0,0);
  355. SET @@optimizer_switch='semijoin=ON,loosescan=ON,firstmatch=OFF,materialization=OFF';
  356. EXPLAIN SELECT *
  357. FROM t3
  358. WHERE t3.b > ALL (
  359. SELECT c
  360. FROM t4
  361. WHERE t4.a >= t3.b
  362. AND a = SOME (SELECT b FROM t5));
  363. id select_type table type possible_keys key key_len ref rows Extra
  364. 1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where
  365. 2 DEPENDENT SUBQUERY t5 index c c 10 NULL 2 Using where; Using index; Start temporary
  366. 2 DEPENDENT SUBQUERY t4 eq_ref PRIMARY PRIMARY 4 test.t5.b 1 Using index condition; Using where; End temporary
  367. SELECT *
  368. FROM t3
  369. WHERE t3.b > ALL (
  370. SELECT c
  371. FROM t4
  372. WHERE t4.a >= t3.b
  373. AND a = SOME (SELECT b FROM t5));
  374. b
  375. 0
  376. 0
  377. set @@optimizer_switch='default';
  378. drop table t3, t4, t5;
  379. #
  380. # LP BUG#858038 The result of a query with NOT IN subquery depends on the state of the optimizer switch
  381. #
  382. set @optimizer_switch_save= @@optimizer_switch;
  383. create table t1 (c1 char(2) not null, c2 char(2));
  384. create table t2 (c3 char(2), c4 char(2));
  385. insert into t1 values ('a1', 'b1');
  386. insert into t1 values ('a2', 'b2');
  387. insert into t2 values ('x1', 'y1');
  388. insert into t2 values ('a2', null);
  389. set @@optimizer_switch='in_to_exists=off,materialization=on,partial_match_rowid_merge=off,partial_match_table_scan=on';
  390. explain select * from t1 where c1 = 'a2' and (c1, c2) not in (select * from t2);
  391. id select_type table type possible_keys key key_len ref rows Extra
  392. 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
  393. 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
  394. select * from t1 where c1 = 'a2' and (c1, c2) not in (select * from t2);
  395. c1 c2
  396. set @@optimizer_switch='in_to_exists=off,materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off';
  397. explain select * from t1 where c1 = 'a2' and (c1, c2) not in (select * from t2);
  398. id select_type table type possible_keys key key_len ref rows Extra
  399. 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
  400. 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
  401. select * from t1 where c1 = 'a2' and (c1, c2) not in (select * from t2);
  402. c1 c2
  403. drop table t1, t2;
  404. set optimizer_switch= @optimizer_switch_save;
  405. #
  406. # MDEV-12673: cost-based choice between materialization and in-to-exists
  407. #
  408. CREATE TABLE t1 (
  409. pk1 int, a1 varchar(3), b1 varchar(3), PRIMARY KEY (pk1), KEY(a1), KEY(b1)
  410. ) ENGINE=MyISAM;
  411. INSERT INTO t1 VALUES (1,'foo','bar'),(2,'bar','foo');
  412. CREATE TABLE t2 (pk2 INT PRIMARY KEY, a2 VARCHAR(3), KEY(a2)) ENGINE=MyISAM;
  413. INSERT INTO t2 VALUES (1,'abc'),(2,'xyz'),(3,'foo');
  414. SELECT 'qux' IN ( SELECT a1 FROM t1 INNER JOIN t2 WHERE a2 = b1 AND pk2 = 3 );
  415. 'qux' IN ( SELECT a1 FROM t1 INNER JOIN t2 WHERE a2 = b1 AND pk2 = 3 )
  416. 0
  417. SELECT 'bar' IN ( SELECT a1 FROM t1 INNER JOIN t2 WHERE a2 = b1 AND pk2 = 3 );
  418. 'bar' IN ( SELECT a1 FROM t1 INNER JOIN t2 WHERE a2 = b1 AND pk2 = 3 )
  419. 1
  420. EXPLAIN
  421. SELECT 'bar' IN ( SELECT a1 FROM t1 INNER JOIN t2 WHERE a2 = b1 AND pk2 = 3 );
  422. id select_type table type possible_keys key key_len ref rows Extra
  423. 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
  424. 2 SUBQUERY t2 const PRIMARY,a2 PRIMARY 4 const 1
  425. 2 SUBQUERY t1 ref a1,b1 b1 6 const 1 Using where
  426. DROP TABLE t1,t2;
  427. CREATE TABLE t1 (i1 INT) ENGINE=MyISAM;
  428. INSERT INTO t1 VALUES (1);
  429. CREATE TABLE t2 (i2 int, c2 varchar(3), KEY(i2,c2)) ENGINE=MyISAM;
  430. INSERT INTO t2 VALUES (1,'abc'),(2,'foo');
  431. CREATE TABLE t3 (pk3 int PRIMARY KEY, c3 varchar(3)) ENGINE=MyISAM;
  432. INSERT INTO t3 VALUES (1,'foo'),(2,'bar');
  433. SELECT * FROM t1 WHERE i1 NOT IN (
  434. SELECT i2 FROM t2 RIGHT JOIN t3 ON (c3 = c2) WHERE pk3 = i1
  435. );
  436. i1
  437. 1
  438. EXPLAIN
  439. SELECT * FROM t1 WHERE i1 NOT IN (
  440. SELECT i2 FROM t2 RIGHT JOIN t3 ON (c3 = c2) WHERE pk3 = i1
  441. );
  442. id select_type table type possible_keys key key_len ref rows Extra
  443. 1 PRIMARY t1 system NULL NULL NULL NULL 1
  444. 2 DEPENDENT SUBQUERY t3 const PRIMARY PRIMARY 4 const 1
  445. 2 DEPENDENT SUBQUERY t2 index NULL i2 11 NULL 2 Using where; Using index
  446. DROP TABLE t1,t2,t3;
  447. #
  448. # MDEV-7599: in-to-exists chosen after min/max optimization
  449. #
  450. set @optimizer_switch_save= @@optimizer_switch;
  451. CREATE TABLE t1 (a INT, KEY(a)) ENGINE=MyISAM;
  452. INSERT INTO t1 VALUES (1),(2);
  453. CREATE TABLE t2 (b INT, c INT) ENGINE=MyISAM;
  454. INSERT INTO t2 VALUES (1,6),(2,4), (8,9);
  455. SELECT * FROM t2 WHERE b != ALL (SELECT MIN(a) FROM t1, t2 WHERE t2.c = t2.b);
  456. b c
  457. EXPLAIN EXTENDED SELECT * FROM t2 WHERE b != ALL (SELECT MIN(a) FROM t1, t2 WHERE t2.c = t2.b);
  458. id select_type table type possible_keys key key_len ref rows filtered Extra
  459. 1 PRIMARY t2 ALL NULL NULL NULL NULL 3 100.00 Using where
  460. 2 MATERIALIZED t1 index NULL a 5 NULL 2 100.00 Using index
  461. 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
  462. Warnings:
  463. Note 1003 select `test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t2` where (not(<expr_cache><`test`.`t2`.`b`>(<in_optimizer>(`test`.`t2`.`b`,`test`.`t2`.`b` in ( <materialize> (select min(`test`.`t1`.`a`) from `test`.`t1` join `test`.`t2` where (`test`.`t2`.`c` = `test`.`t2`.`b`) ), <primary_index_lookup>(`test`.`t2`.`b` in <temporary table> on distinct_key where ((`test`.`t2`.`b` = `<subquery2>`.`MIN(a)`))))))))
  464. set optimizer_switch= 'materialization=off';
  465. SELECT * FROM t2 WHERE b != ALL (SELECT MIN(a) FROM t1, t2 WHERE t2.c = t2.b);
  466. b c
  467. EXPLAIN EXTENDED SELECT * FROM t2 WHERE b != ALL (SELECT MIN(a) FROM t1, t2 WHERE t2.c = t2.b);
  468. id select_type table type possible_keys key key_len ref rows filtered Extra
  469. 1 PRIMARY t2 ALL NULL NULL NULL NULL 3 100.00 Using where
  470. 2 DEPENDENT SUBQUERY t1 index NULL a 5 NULL 2 100.00 Using index
  471. 2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
  472. Warnings:
  473. Note 1003 select `test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t2` where (not(<expr_cache><`test`.`t2`.`b`>(<in_optimizer>(`test`.`t2`.`b`,<exists>(select min(`test`.`t1`.`a`) from `test`.`t1` join `test`.`t2` where (`test`.`t2`.`c` = `test`.`t2`.`b`) having trigcond((<cache>(`test`.`t2`.`b`) = <ref_null_helper>(min(`test`.`t1`.`a`)))))))))
  474. set optimizer_switch= @optimizer_switch_save;
  475. DROP TABLE t1,t2;
  476. CREATE TABLE t1 (f1 varchar(10)) ENGINE=MyISAM;
  477. INSERT INTO t1 VALUES ('foo'),('bar');
  478. CREATE TABLE t2 (f2 varchar(10), key(f2)) ENGINE=MyISAM;
  479. INSERT INTO t2 VALUES ('baz'),('qux');
  480. CREATE TABLE t3 (f3 varchar(10)) ENGINE=MyISAM;
  481. INSERT INTO t3 VALUES ('abc'),('def');
  482. SELECT * FROM t1
  483. WHERE f1 = ALL( SELECT MAX(t2a.f2)
  484. FROM t2 AS t2a INNER JOIN t2 t2b INNER JOIN t3
  485. ON (f3 = t2b.f2) );
  486. f1
  487. DROP TABLE t1,t2,t3;
  488. #
  489. # MDEV-12963: min/max optimization optimizing away all tables employed
  490. # for uncorrelated IN subquery used in a disjunct of WHERE
  491. #
  492. create table t1 (a int, index idx(a)) engine=myisam;
  493. insert into t1 values (4),(7),(1),(3),(9);
  494. select * from t1 where a in (select max(a) from t1 where a < 4) or a > 5;
  495. a
  496. 3
  497. 7
  498. 9
  499. explain
  500. select * from t1 where a in (select max(a) from t1 where a < 4) or a > 5;
  501. id select_type table type possible_keys key key_len ref rows Extra
  502. 1 PRIMARY t1 index idx idx 5 NULL 5 Using where; Using index
  503. 2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
  504. drop table t1;
  505. #
  506. # MDEV-13135: subquery with ON expression subject to
  507. # semi-join optimizations
  508. #
  509. CREATE TABLE t1 (a INT);
  510. CREATE ALGORITHM=MERGE VIEW v1 AS SELECT a AS v_a FROM t1;
  511. INSERT INTO t1 VALUES (1),(3);
  512. CREATE TABLE t2 (b INT, KEY(b));
  513. INSERT INTO t2 VALUES (3),(4);
  514. SELECT * FROM t1 WHERE a NOT IN (
  515. SELECT b FROM t2 INNER JOIN v1 ON (b IN ( SELECT a FROM t1 ))
  516. WHERE v_a = b
  517. );
  518. a
  519. 1
  520. DROP VIEW v1;
  521. DROP TABLE t1,t2;