Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-30538

Plans for SELECT and multi-table UPDATE/DELETE unexpectedly differ

Details

    Description

      For the following query with SELECT:

      explain 
      select * 
       from v1,t3
      where
        v1.c2 = t3.c2 and 
        v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                  and v1.c1 < 10 and
                  exists (select 'X' from v2 where c1 = v1.c1);
      

      EXPLAIN produces:

      MariaDB [test]> explain 
          -> select * 
          ->  from v1,t3
          -> where
          ->   v1.c2 = t3.c2 and 
          ->   v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
          ->             and v1.c1 < 10 and
          ->             exists (select 'X' from v2 where c1 = v1.c1);
      +------+--------------------+-------------+--------+---------------+--------------+---------+-------+------+-------------------------------------------------+
      | id   | select_type        | table       | type   | possible_keys | key          | key_len | ref   | rows | Extra                                           |
      +------+--------------------+-------------+--------+---------------+--------------+---------+-------+------+-------------------------------------------------+
      |    1 | PRIMARY            | t1          | ref    | t1_c2         | t1_c2        | 5       | const | 2    | Using where                                     |
      |    1 | PRIMARY            | <subquery3> | eq_ref | distinct_key  | distinct_key | 4       | func  | 1    |                                                 |
      |    1 | PRIMARY            | t3          | ALL    | NULL          | NULL         | NULL    | NULL  | 8    | Using where; Using join buffer (flat, BNL join) |
      |    3 | MATERIALIZED       | t2          | ref    | t2_c2         | t2_c2        | 5       | const | 2    |                                                 |
      |    2 | DEPENDENT SUBQUERY | t2          | ALL    | NULL          | NULL         | NULL    | NULL  | 8    | Using where                                     |
      +------+--------------------+-------------+--------+---------------+--------------+---------+-------+------+-------------------------------------------------+
      

      For the queries with DELETE and UPDATE based on previous SELECT:

      delete
       from v1
       using v1,t3
      where
        v1.c2 = t3.c2 and 
        v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                  and v1.c1 < 10 and
                  exists (select 'X' from v2 where c1 = v1.c1);
      

      update v1,t3
      set v1.c1 = 15
      where
        v1.c2 = t3.c2 and 
        v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                  and v1.c1 < 10 and
                  exists (select 'X' from v2 where c1 = v1.c1);
      

      EXPLAIN produces:

      MariaDB [test]> explain 
          -> delete
          ->  from v1
          ->  using v1,t3
          -> where
          ->   v1.c2 = t3.c2 and 
          ->   v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
          ->             and v1.c1 < 10 and
          ->             exists (select 'X' from v2 where c1 = v1.c1);
      +------+--------------------+-------+------+---------------+-------+---------+-------+------+-------------+
      | id   | select_type        | table | type | possible_keys | key   | key_len | ref   | rows | Extra       |
      +------+--------------------+-------+------+---------------+-------+---------+-------+------+-------------+
      |    1 | PRIMARY            | t1    | ref  | t1_c2         | t1_c2 | 5       | const | 2    | Using where |
      |    1 | PRIMARY            | t3    | ALL  | NULL          | NULL  | NULL    | NULL  | 8    | Using where |
      |    3 | DEPENDENT SUBQUERY | t2    | ref  | t2_c2         | t2_c2 | 5       | const | 2    | Using where |
      |    2 | DEPENDENT SUBQUERY | t2    | ALL  | NULL          | NULL  | NULL    | NULL  | 8    | Using where |
      +------+--------------------+-------+------+---------------+-------+---------+-------+------+-------------+
       
      MariaDB [test]> explain 
          -> update v1,t3
          -> set v1.c1 = 15
          -> where
          ->   v1.c2 = t3.c2 and 
          ->   v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
          ->             and v1.c1 < 10 and
          ->             exists (select 'X' from v2 where c1 = v1.c1);
      +------+--------------------+-------+------+---------------+-------+---------+-------+------+-------------+
      | id   | select_type        | table | type | possible_keys | key   | key_len | ref   | rows | Extra       |
      +------+--------------------+-------+------+---------------+-------+---------+-------+------+-------------+
      |    1 | PRIMARY            | t1    | ref  | t1_c2         | t1_c2 | 5       | const | 2    | Using where |
      |    1 | PRIMARY            | t3    | ALL  | NULL          | NULL  | NULL    | NULL  | 8    | Using where |
      |    3 | DEPENDENT SUBQUERY | t2    | ref  | t2_c2         | t2_c2 | 5       | const | 2    | Using where |
      |    2 | DEPENDENT SUBQUERY | t2    | ALL  | NULL          | NULL  | NULL    | NULL  | 8    | Using where |
      +------+--------------------+-------+------+---------------+-------+---------+-------+------+-------------+
      
      

      but it is expected that the plan will be similar to the plan for SELECT

      MTR test case:

       
      create table t1 (c1 integer, c2 integer, c3 integer) ;
      insert into t1(c1,c2,c3)
      values (1,1,1),(1,2,2),(1,3,3),
      (2,1,4),(2,2,5),(2,3,6),
      (2,4,7),(2,5,8);
      create view v1 as select * from t1 where c2=2;
      create index t1_c2 on t1 (c2);
      analyze table t1 persistent for all;
       
      create table t2 (c1 integer, c2 integer, c3 integer) ;
      insert into t2(c1,c2,c3)
      values (1,1,1),(1,2,2),(1,3,3),
      (2,1,4),(2,2,5),(2,3,6),
      (2,4,7),(2,5,8);
      create view v2 as select * from t2 where c2=2;
      create index t2_c2 on t2 (c2);
      analyze table t2 persistent for all;
       
      create table t3 (c1 integer, c2 integer, c3 integer) ;
      insert into t3(c1,c2,c3)
      values (1,1,1),(1,2,2),(1,3,3),
      (2,1,4),(2,2,5),(2,3,6),
      (2,4,7),(2,5,8);
      analyze table t3 persistent for all;
       
      explain 
      select * 
       from v1,t3
      where
        v1.c2 = t3.c2 and 
        v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                  and v1.c1 < 10 and
                  exists (select 'X' from v2 where c1 = v1.c1);
       
      explain 
      delete
       from v1
       using v1,t3
      where
        v1.c2 = t3.c2 and 
        v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                  and v1.c1 < 10 and
                  exists (select 'X' from v2 where c1 = v1.c1);
       
      explain 
      update v1,t3
      set v1.c1 = 15
      where
        v1.c2 = t3.c2 and 
        v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                  and v1.c1 < 10 and
                  exists (select 'X' from v2 where c1 = v1.c1);
       
      drop view v1, v2;
      drop table t1, t2, t3;
      

      Attachments

        Activity

          lstartseva Lena Startseva created issue -
          lstartseva Lena Startseva made changes -
          Field Original Value New Value
          Description For the following query with SELECT:
          {code:sql}
          select *
           from v1,t3
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      v1.c1 in (select c1 from v2);
          {code}

          EXPLAIN produces:
          {code:sql}
          id select_type table type possible_keys key key_len ref rows Extra
          1 PRIMARY t1 ref t1_c2 t1_c2 5 const 2 Using where
          1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func 1
          1 PRIMARY t3 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
          3 MATERIALIZED t2 ref t2_c2 t2_c2 5 const 2
          2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 8 Using where
          {code}

          For the queries with DELETE and UPDATE based on previous SELECT:
          {code:sql}
          delete
           from v1
           using v1,t3
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      exists (select 'X' from v2 where c1 = v1.c1);
          {code}

          {code:sql}
          update v1,t3
          set v1.c1 = 15, t3.c1=21
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      exists (select 'X' from v2 where c1 = v1.c1);
          {code}

          EXPLAIN produces:
          {code:sql}
          id select_type table type possible_keys key key_len ref rows Extra
          1 PRIMARY t1 ref t1_c2 t1_c2 5 const 2 Using where
          1 PRIMARY t3 ALL NULL NULL NULL NULL 8 Using where
          3 DEPENDENT SUBQUERY t2 ref t2_c2 t2_c2 5 const 2 Using where
          2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 8 Using where
          {code}

          *but it is expected that the plan will be the same as plan for select.*

          MTR test case:
          {code:sql}
          --source include/have_innodb.inc

          create table t1 (c1 integer, c2 integer, c3 integer) engine=innodb;
          insert into t1(c1,c2,c3)
          values (1,1,1),(1,2,2),(1,3,3),
          (2,1,4),(2,2,5),(2,3,6),
          (2,4,7),(2,5,8);
          create view v1 as select * from t1 where c2=2;
          create index t1_c2 on t1 (c2);
          analyze table t1 persistent for all;

          create table t2 (c1 integer, c2 integer, c3 integer) engine=innodb;
          insert into t2(c1,c2,c3)
          values (1,1,1),(1,2,2),(1,3,3),
          (2,1,4),(2,2,5),(2,3,6),
          (2,4,7),(2,5,8);
          create view v2 as select * from t2 where c2=2;
          create index t2_c2 on t2 (c2);
          analyze table t2 persistent for all;

          create table t3 (c1 integer, c2 integer, c3 integer) engine=innodb;
          insert into t3(c1,c2,c3)
          values (1,1,1),(1,2,2),(1,3,3),
          (2,1,4),(2,2,5),(2,3,6),
          (2,4,7),(2,5,8);
          analyze table t3 persistent for all;

          explain
          select *
           from v1,t3
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      v1.c1 in (select c1 from v2);

          explain
          delete
           from v1
           using v1,t3
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      exists (select 'X' from v2 where c1 = v1.c1);

          explain
          update v1,t3
          set v1.c1 = 15, t3.c1=21
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      exists (select 'X' from v2 where c1 = v1.c1);

          drop view v1, v2;
          drop table t1, t2, t3;
          {code}
          For the following query with SELECT:
          {code:sql}
          select *
           from v1,t3
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      v1.c1 in (select c1 from v2);
          {code}

          EXPLAIN produces:
          {code:sql}
          id select_type table type possible_keys key key_len ref rows Extra
          1 PRIMARY t1 ref t1_c2 t1_c2 5 const 2 Using where
          1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func 1
          1 PRIMARY t3 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
          3 MATERIALIZED t2 ref t2_c2 t2_c2 5 const 2
          2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 8 Using where
          {code}

          For the queries with DELETE and UPDATE based on previous SELECT:
          {code:sql}
          delete
           from v1
           using v1,t3
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      exists (select 'X' from v2 where c1 = v1.c1);
          {code}

          {code:sql}
          update v1,t3
          set v1.c1 = 15, t3.c1=21
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      exists (select 'X' from v2 where c1 = v1.c1);
          {code}

          EXPLAIN produces:
          {code:sql}
          id select_type table type possible_keys key key_len ref rows Extra
          1 PRIMARY t1 ref t1_c2 t1_c2 5 const 2 Using where
          1 PRIMARY t3 ALL NULL NULL NULL NULL 8 Using where
          3 DEPENDENT SUBQUERY t2 ref t2_c2 t2_c2 5 const 2 Using where
          2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 8 Using where
          {code}

          *but it is expected that the plan will be the same as plan for SELECT*

          MTR test case:
          {code:sql}
          --source include/have_innodb.inc

          create table t1 (c1 integer, c2 integer, c3 integer) engine=innodb;
          insert into t1(c1,c2,c3)
          values (1,1,1),(1,2,2),(1,3,3),
          (2,1,4),(2,2,5),(2,3,6),
          (2,4,7),(2,5,8);
          create view v1 as select * from t1 where c2=2;
          create index t1_c2 on t1 (c2);
          analyze table t1 persistent for all;

          create table t2 (c1 integer, c2 integer, c3 integer) engine=innodb;
          insert into t2(c1,c2,c3)
          values (1,1,1),(1,2,2),(1,3,3),
          (2,1,4),(2,2,5),(2,3,6),
          (2,4,7),(2,5,8);
          create view v2 as select * from t2 where c2=2;
          create index t2_c2 on t2 (c2);
          analyze table t2 persistent for all;

          create table t3 (c1 integer, c2 integer, c3 integer) engine=innodb;
          insert into t3(c1,c2,c3)
          values (1,1,1),(1,2,2),(1,3,3),
          (2,1,4),(2,2,5),(2,3,6),
          (2,4,7),(2,5,8);
          analyze table t3 persistent for all;

          explain
          select *
           from v1,t3
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      v1.c1 in (select c1 from v2);

          explain
          delete
           from v1
           using v1,t3
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      exists (select 'X' from v2 where c1 = v1.c1);

          explain
          update v1,t3
          set v1.c1 = 15, t3.c1=21
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      exists (select 'X' from v2 where c1 = v1.c1);

          drop view v1, v2;
          drop table t1, t2, t3;
          {code}
          lstartseva Lena Startseva made changes -
          Assignee Igor Babaev [ igor ]
          lstartseva Lena Startseva made changes -
          Component/s Optimizer [ 10200 ]
          igor Igor Babaev (Inactive) made changes -
          Summary EXPLAIN: different plan for SELECT and DELETE/UPDATE EXPLAIN: different plan for SELECT and multi-table DELETE/UPDATE
          igor Igor Babaev (Inactive) made changes -
          Summary EXPLAIN: different plan for SELECT and multi-table DELETE/UPDATE EXPLAIN: different plans for SELECT and multi-table DELETE/UPDATE
          igor Igor Babaev (Inactive) made changes -
          Fix Version/s 10.4 [ 22408 ]
          igor Igor Babaev (Inactive) made changes -
          Status Open [ 1 ] In Progress [ 3 ]
          lstartseva Lena Startseva made changes -
          Description For the following query with SELECT:
          {code:sql}
          select *
           from v1,t3
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      v1.c1 in (select c1 from v2);
          {code}

          EXPLAIN produces:
          {code:sql}
          id select_type table type possible_keys key key_len ref rows Extra
          1 PRIMARY t1 ref t1_c2 t1_c2 5 const 2 Using where
          1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func 1
          1 PRIMARY t3 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
          3 MATERIALIZED t2 ref t2_c2 t2_c2 5 const 2
          2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 8 Using where
          {code}

          For the queries with DELETE and UPDATE based on previous SELECT:
          {code:sql}
          delete
           from v1
           using v1,t3
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      exists (select 'X' from v2 where c1 = v1.c1);
          {code}

          {code:sql}
          update v1,t3
          set v1.c1 = 15, t3.c1=21
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      exists (select 'X' from v2 where c1 = v1.c1);
          {code}

          EXPLAIN produces:
          {code:sql}
          id select_type table type possible_keys key key_len ref rows Extra
          1 PRIMARY t1 ref t1_c2 t1_c2 5 const 2 Using where
          1 PRIMARY t3 ALL NULL NULL NULL NULL 8 Using where
          3 DEPENDENT SUBQUERY t2 ref t2_c2 t2_c2 5 const 2 Using where
          2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 8 Using where
          {code}

          *but it is expected that the plan will be the same as plan for SELECT*

          MTR test case:
          {code:sql}
          --source include/have_innodb.inc

          create table t1 (c1 integer, c2 integer, c3 integer) engine=innodb;
          insert into t1(c1,c2,c3)
          values (1,1,1),(1,2,2),(1,3,3),
          (2,1,4),(2,2,5),(2,3,6),
          (2,4,7),(2,5,8);
          create view v1 as select * from t1 where c2=2;
          create index t1_c2 on t1 (c2);
          analyze table t1 persistent for all;

          create table t2 (c1 integer, c2 integer, c3 integer) engine=innodb;
          insert into t2(c1,c2,c3)
          values (1,1,1),(1,2,2),(1,3,3),
          (2,1,4),(2,2,5),(2,3,6),
          (2,4,7),(2,5,8);
          create view v2 as select * from t2 where c2=2;
          create index t2_c2 on t2 (c2);
          analyze table t2 persistent for all;

          create table t3 (c1 integer, c2 integer, c3 integer) engine=innodb;
          insert into t3(c1,c2,c3)
          values (1,1,1),(1,2,2),(1,3,3),
          (2,1,4),(2,2,5),(2,3,6),
          (2,4,7),(2,5,8);
          analyze table t3 persistent for all;

          explain
          select *
           from v1,t3
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      v1.c1 in (select c1 from v2);

          explain
          delete
           from v1
           using v1,t3
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      exists (select 'X' from v2 where c1 = v1.c1);

          explain
          update v1,t3
          set v1.c1 = 15, t3.c1=21
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      exists (select 'X' from v2 where c1 = v1.c1);

          drop view v1, v2;
          drop table t1, t2, t3;
          {code}
          For the following query with SELECT:
          {code:sql}
          select *
           from v1,t3
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      v1.c1 in (select c1 from v2);
          {code}

          EXPLAIN produces:
          {code:sql}
          id select_type table type possible_keys key key_len ref rows Extra
          1 PRIMARY t1 ref t1_c2 t1_c2 5 const 2 Using where
          1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func 1
          1 PRIMARY t3 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
          3 MATERIALIZED t2 ref t2_c2 t2_c2 5 const 2
          2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 8 Using where
          {code}

          For the queries with DELETE and UPDATE based on previous SELECT:
          {code:sql}
          delete
           from v1
           using v1,t3
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      exists (select 'X' from v2 where c1 = v1.c1);
          {code}

          {code:sql}
          update v1,t3
          set v1.c1 = 15
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      exists (select 'X' from v2 where c1 = v1.c1);
          {code}

          EXPLAIN produces:
          {code:sql}
          id select_type table type possible_keys key key_len ref rows Extra
          1 PRIMARY t1 ref t1_c2 t1_c2 5 const 2 Using where
          1 PRIMARY t3 ALL NULL NULL NULL NULL 8 Using where
          3 DEPENDENT SUBQUERY t2 ref t2_c2 t2_c2 5 const 2 Using where
          2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 8 Using where
          {code}

          *but it is expected that the plan will be the same as plan for SELECT*

          MTR test case:
          {code:sql}
          --source include/have_innodb.inc

          create table t1 (c1 integer, c2 integer, c3 integer) engine=innodb;
          insert into t1(c1,c2,c3)
          values (1,1,1),(1,2,2),(1,3,3),
          (2,1,4),(2,2,5),(2,3,6),
          (2,4,7),(2,5,8);
          create view v1 as select * from t1 where c2=2;
          create index t1_c2 on t1 (c2);
          analyze table t1 persistent for all;

          create table t2 (c1 integer, c2 integer, c3 integer) engine=innodb;
          insert into t2(c1,c2,c3)
          values (1,1,1),(1,2,2),(1,3,3),
          (2,1,4),(2,2,5),(2,3,6),
          (2,4,7),(2,5,8);
          create view v2 as select * from t2 where c2=2;
          create index t2_c2 on t2 (c2);
          analyze table t2 persistent for all;

          create table t3 (c1 integer, c2 integer, c3 integer) engine=innodb;
          insert into t3(c1,c2,c3)
          values (1,1,1),(1,2,2),(1,3,3),
          (2,1,4),(2,2,5),(2,3,6),
          (2,4,7),(2,5,8);
          analyze table t3 persistent for all;

          explain
          select *
           from v1,t3
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      v1.c1 in (select c1 from v2);

          explain
          delete
           from v1
           using v1,t3
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      exists (select 'X' from v2 where c1 = v1.c1);

          explain
          update v1,t3
          set v1.c1 = 15
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      exists (select 'X' from v2 where c1 = v1.c1);

          drop view v1, v2;
          drop table t1, t2, t3;
          {code}

          Here's a simpler test case demonstrating this problem:

          create table t1 (c1 int, c2 int, c3 int, index idx(c2));
          insert into t1 values
          (1,1,1),(3,2,2),(1,3,3),
          (2,1,4),(2,2,5),(4,3,6),
          (2,4,7),(2,5,8);
           
          create table t2 (c1 int, c2 int, c3 int, index idx(c2));
          insert into t2 values
          (1,7,1),(1,8,2),(1,3,3),
          (2,1,4),(2,2,5),(2,3,6),
          (2,4,7),(2,5,8);
           
          create table t3 (c1 int, c2 int, c3 int, index idx(c2));
          insert into t3 values
          (1,1,1),(1,2,2),(1,3,3),
          (2,1,4),(2,2,5),(2,3,6),
          (2,4,7),(2,5,8);
          insert into t3 select c1+1, c2+2, c3 from t3;
          insert into t3 select c1, c2+2, c3  from t3;
           
          analyze table t1,t2,t3 persistent for all;
           
          create table t select * from t1;
           
          explain
          select * from t1,t3 
          where
            t1.c2 = t3.c2 and 
            t1.c1 > 1 and 
            exists (select 'X' from t2 where t2.c1 = t1.c1 and t2.c2 > 4);
           
          explain
          delete from t1 using t1,t3 
          where
            t1.c2 = t3.c2 and 
            t1.c1 > 1 and 
            exists (select 'X' from t2 where t2.c1 = t1.c1 and t2.c2 > 4);
           
          explain
          update t1,t3 set t1.c1 = t1.c1+10
          where
            t1.c2 = t3.c2 and 
            t1.c1 > 1 and 
            exists (select 'X' from t2 where t2.c1 = t1.c1 and t2.c2 > 4);
          

          We have the following output for the above EXPLAIN commands:

           
          MariaDB [test]> explain
              -> select * from t1,t3 
              -> where
              ->   t1.c2 = t3.c2 and 
              ->   t1.c1 > 1 and 
              ->   exists (select 'X' from t2 where t2.c1 = t1.c1 and t2.c2 > 4);
          +------+--------------+-------------+--------+---------------+--------------+---------+------------+------+-------------+
          | id   | select_type  | table       | type   | possible_keys | key          | key_len | ref        | rows | Extra       |
          +------+--------------+-------------+--------+---------------+--------------+---------+------------+------+-------------+
          |    1 | PRIMARY      | t1          | ALL    | idx           | NULL         | NULL    | NULL       | 8    | Using where |
          |    1 | PRIMARY      | <subquery2> | eq_ref | distinct_key  | distinct_key | 4       | func       | 1    |             |
          |    1 | PRIMARY      | t3          | ref    | idx           | idx          | 5       | test.t1.c2 | 3    |             |
          |    2 | MATERIALIZED | t2          | ALL    | idx           | NULL         | NULL    | NULL       | 8    | Using where |
          +------+--------------+-------------+--------+---------------+--------------+---------+------------+------+-------------+
          4 rows in set (0.003 sec)
           
          MariaDB [test]> 
          MariaDB [test]> explain
              -> delete from t1 using t1,t3 
              -> where
              ->   t1.c2 = t3.c2 and 
              ->   t1.c1 > 1 and 
              ->   exists (select 'X' from t2 where t2.c1 = t1.c1 and t2.c2 > 4);
          +------+--------------------+-------+-------+---------------+------+---------+------------+------+-------------+
          | id   | select_type        | table | type  | possible_keys | key  | key_len | ref        | rows | Extra       |
          +------+--------------------+-------+-------+---------------+------+---------+------------+------+-------------+
          |    1 | PRIMARY            | t1    | ALL   | idx           | NULL | NULL    | NULL       | 8    | Using where |
          |    1 | PRIMARY            | t3    | ref   | idx           | idx  | 5       | test.t1.c2 | 3    | Using index |
          |    2 | DEPENDENT SUBQUERY | t2    | range | idx           | idx  | 5       | NULL       | 3    | Using where |
          +------+--------------------+-------+-------+---------------+------+---------+------------+------+-------------+
          3 rows in set (0.001 sec)
           
          MariaDB [test]> 
          MariaDB [test]> explain
              -> update t1,t3 set t1.c1 = t1.c1+10
              -> where
              ->   t1.c2 = t3.c2 and 
              ->   t1.c1 > 1 and 
              ->   exists (select 'X' from t2 where t2.c1 = t1.c1 and t2.c2 > 4);
          +------+--------------------+-------+-------+---------------+------+---------+------------+------+-------------+
          | id   | select_type        | table | type  | possible_keys | key  | key_len | ref        | rows | Extra       |
          +------+--------------------+-------+-------+---------------+------+---------+------------+------+-------------+
          |    1 | PRIMARY            | t1    | ALL   | idx           | NULL | NULL    | NULL       | 8    | Using where |
          |    1 | PRIMARY            | t3    | ref   | idx           | idx  | 5       | test.t1.c2 | 3    | Using index |
          |    2 | DEPENDENT SUBQUERY | t2    | range | idx           | idx  | 5       | NULL       | 3    | Using where |
          +------+--------------------+-------+-------+---------------+------+---------+------------+------+-------------+
          3 rows in set (0.001 sec)
          

          igor Igor Babaev (Inactive) added a comment - Here's a simpler test case demonstrating this problem: create table t1 (c1 int , c2 int , c3 int , index idx(c2)); insert into t1 values (1,1,1),(3,2,2),(1,3,3), (2,1,4),(2,2,5),(4,3,6), (2,4,7),(2,5,8);   create table t2 (c1 int , c2 int , c3 int , index idx(c2)); insert into t2 values (1,7,1),(1,8,2),(1,3,3), (2,1,4),(2,2,5),(2,3,6), (2,4,7),(2,5,8);   create table t3 (c1 int , c2 int , c3 int , index idx(c2)); insert into t3 values (1,1,1),(1,2,2),(1,3,3), (2,1,4),(2,2,5),(2,3,6), (2,4,7),(2,5,8); insert into t3 select c1+1, c2+2, c3 from t3; insert into t3 select c1, c2+2, c3 from t3;   analyze table t1,t2,t3 persistent for all ;   create table t select * from t1;   explain select * from t1,t3 where t1.c2 = t3.c2 and t1.c1 > 1 and exists ( select 'X' from t2 where t2.c1 = t1.c1 and t2.c2 > 4);   explain delete from t1 using t1,t3 where t1.c2 = t3.c2 and t1.c1 > 1 and exists ( select 'X' from t2 where t2.c1 = t1.c1 and t2.c2 > 4);   explain update t1,t3 set t1.c1 = t1.c1+10 where t1.c2 = t3.c2 and t1.c1 > 1 and exists ( select 'X' from t2 where t2.c1 = t1.c1 and t2.c2 > 4); We have the following output for the above EXPLAIN commands:   MariaDB [test]> explain -> select * from t1,t3 -> where -> t1.c2 = t3.c2 and -> t1.c1 > 1 and -> exists (select 'X' from t2 where t2.c1 = t1.c1 and t2.c2 > 4); +------+--------------+-------------+--------+---------------+--------------+---------+------------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +------+--------------+-------------+--------+---------------+--------------+---------+------------+------+-------------+ | 1 | PRIMARY | t1 | ALL | idx | NULL | NULL | NULL | 8 | Using where | | 1 | PRIMARY | <subquery2> | eq_ref | distinct_key | distinct_key | 4 | func | 1 | | | 1 | PRIMARY | t3 | ref | idx | idx | 5 | test.t1.c2 | 3 | | | 2 | MATERIALIZED | t2 | ALL | idx | NULL | NULL | NULL | 8 | Using where | +------+--------------+-------------+--------+---------------+--------------+---------+------------+------+-------------+ 4 rows in set (0.003 sec)   MariaDB [test]> MariaDB [test]> explain -> delete from t1 using t1,t3 -> where -> t1.c2 = t3.c2 and -> t1.c1 > 1 and -> exists (select 'X' from t2 where t2.c1 = t1.c1 and t2.c2 > 4); +------+--------------------+-------+-------+---------------+------+---------+------------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +------+--------------------+-------+-------+---------------+------+---------+------------+------+-------------+ | 1 | PRIMARY | t1 | ALL | idx | NULL | NULL | NULL | 8 | Using where | | 1 | PRIMARY | t3 | ref | idx | idx | 5 | test.t1.c2 | 3 | Using index | | 2 | DEPENDENT SUBQUERY | t2 | range | idx | idx | 5 | NULL | 3 | Using where | +------+--------------------+-------+-------+---------------+------+---------+------------+------+-------------+ 3 rows in set (0.001 sec)   MariaDB [test]> MariaDB [test]> explain -> update t1,t3 set t1.c1 = t1.c1+10 -> where -> t1.c2 = t3.c2 and -> t1.c1 > 1 and -> exists (select 'X' from t2 where t2.c1 = t1.c1 and t2.c2 > 4); +------+--------------------+-------+-------+---------------+------+---------+------------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +------+--------------------+-------+-------+---------------+------+---------+------------+------+-------------+ | 1 | PRIMARY | t1 | ALL | idx | NULL | NULL | NULL | 8 | Using where | | 1 | PRIMARY | t3 | ref | idx | idx | 5 | test.t1.c2 | 3 | Using index | | 2 | DEPENDENT SUBQUERY | t2 | range | idx | idx | 5 | NULL | 3 | Using where | +------+--------------------+-------+-------+---------------+------+---------+------------+------+-------------+ 3 rows in set (0.001 sec)
          igor Igor Babaev (Inactive) made changes -
          Summary EXPLAIN: different plans for SELECT and multi-table DELETE/UPDATE Unexpectedly different plans for SELECT and multi-table DELETE/UPDATE
          igor Igor Babaev (Inactive) made changes -
          Summary Unexpectedly different plans for SELECT and multi-table DELETE/UPDATE Plans for SELECT and multi-table UPDATE/DELETE unexpectedly differ
          igor Igor Babaev (Inactive) made changes -
          Assignee Igor Babaev [ igor ] Oleksandr Byelkin [ sanja ]
          Status In Progress [ 3 ] In Review [ 10002 ]
          igor Igor Babaev (Inactive) made changes -
          Description For the following query with SELECT:
          {code:sql}
          select *
           from v1,t3
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      v1.c1 in (select c1 from v2);
          {code}

          EXPLAIN produces:
          {code:sql}
          id select_type table type possible_keys key key_len ref rows Extra
          1 PRIMARY t1 ref t1_c2 t1_c2 5 const 2 Using where
          1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func 1
          1 PRIMARY t3 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
          3 MATERIALIZED t2 ref t2_c2 t2_c2 5 const 2
          2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 8 Using where
          {code}

          For the queries with DELETE and UPDATE based on previous SELECT:
          {code:sql}
          delete
           from v1
           using v1,t3
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      exists (select 'X' from v2 where c1 = v1.c1);
          {code}

          {code:sql}
          update v1,t3
          set v1.c1 = 15
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      exists (select 'X' from v2 where c1 = v1.c1);
          {code}

          EXPLAIN produces:
          {code:sql}
          id select_type table type possible_keys key key_len ref rows Extra
          1 PRIMARY t1 ref t1_c2 t1_c2 5 const 2 Using where
          1 PRIMARY t3 ALL NULL NULL NULL NULL 8 Using where
          3 DEPENDENT SUBQUERY t2 ref t2_c2 t2_c2 5 const 2 Using where
          2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 8 Using where
          {code}

          *but it is expected that the plan will be the same as plan for SELECT*

          MTR test case:
          {code:sql}
          --source include/have_innodb.inc

          create table t1 (c1 integer, c2 integer, c3 integer) engine=innodb;
          insert into t1(c1,c2,c3)
          values (1,1,1),(1,2,2),(1,3,3),
          (2,1,4),(2,2,5),(2,3,6),
          (2,4,7),(2,5,8);
          create view v1 as select * from t1 where c2=2;
          create index t1_c2 on t1 (c2);
          analyze table t1 persistent for all;

          create table t2 (c1 integer, c2 integer, c3 integer) engine=innodb;
          insert into t2(c1,c2,c3)
          values (1,1,1),(1,2,2),(1,3,3),
          (2,1,4),(2,2,5),(2,3,6),
          (2,4,7),(2,5,8);
          create view v2 as select * from t2 where c2=2;
          create index t2_c2 on t2 (c2);
          analyze table t2 persistent for all;

          create table t3 (c1 integer, c2 integer, c3 integer) engine=innodb;
          insert into t3(c1,c2,c3)
          values (1,1,1),(1,2,2),(1,3,3),
          (2,1,4),(2,2,5),(2,3,6),
          (2,4,7),(2,5,8);
          analyze table t3 persistent for all;

          explain
          select *
           from v1,t3
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      v1.c1 in (select c1 from v2);

          explain
          delete
           from v1
           using v1,t3
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      exists (select 'X' from v2 where c1 = v1.c1);

          explain
          update v1,t3
          set v1.c1 = 15
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      exists (select 'X' from v2 where c1 = v1.c1);

          drop view v1, v2;
          drop table t1, t2, t3;
          {code}
          For the following query with SELECT:
          {code:sql}
          explain
          select *
           from v1,t3
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      exists (select 'X' from v2 where c1 = v1.c1);
          {code}

          EXPLAIN produces:
          {noformat}
          MariaDB [test]> explain
              -> select *
              -> from v1,t3
              -> where
              -> v1.c2 = t3.c2 and
              -> v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
              -> and v1.c1 < 10 and
              -> exists (select 'X' from v2 where c1 = v1.c1);
          +------+--------------------+-------------+--------+---------------+--------------+---------+-------+------+-------------------------------------------------+
          | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
          +------+--------------------+-------------+--------+---------------+--------------+---------+-------+------+-------------------------------------------------+
          | 1 | PRIMARY | t1 | ref | t1_c2 | t1_c2 | 5 | const | 2 | Using where |
          | 1 | PRIMARY | <subquery3> | eq_ref | distinct_key | distinct_key | 4 | func | 1 | |
          | 1 | PRIMARY | t3 | ALL | NULL | NULL | NULL | NULL | 8 | Using where; Using join buffer (flat, BNL join) |
          | 3 | MATERIALIZED | t2 | ref | t2_c2 | t2_c2 | 5 | const | 2 | |
          | 2 | DEPENDENT SUBQUERY | t2 | ALL | NULL | NULL | NULL | NULL | 8 | Using where |
          +------+--------------------+-------------+--------+---------------+--------------+---------+-------+------+-------------------------------------------------+
          {noformat}

          For the queries with DELETE and UPDATE based on previous SELECT:
          {code:sql}
          delete
           from v1
           using v1,t3
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      exists (select 'X' from v2 where c1 = v1.c1);
          {code}

          {code:sql}
          update v1,t3
          set v1.c1 = 15
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      exists (select 'X' from v2 where c1 = v1.c1);
          {code}

          EXPLAIN produces:
          {noformat}
          MariaDB [test]> explain
              -> delete
              -> from v1
              -> using v1,t3
              -> where
              -> v1.c2 = t3.c2 and
              -> v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
              -> and v1.c1 < 10 and
              -> exists (select 'X' from v2 where c1 = v1.c1);
          +------+--------------------+-------------+--------+---------------+--------------+---------+-------+------+-------------+
          | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
          +------+--------------------+-------------+--------+---------------+--------------+---------+-------+------+-------------+
          | 1 | PRIMARY | t1 | ref | t1_c2 | t1_c2 | 5 | const | 2 | Using where |
          | 1 | PRIMARY | <subquery3> | eq_ref | distinct_key | distinct_key | 4 | func | 1 | |
          | 1 | PRIMARY | t3 | ALL | NULL | NULL | NULL | NULL | 8 | Using where |
          | 3 | MATERIALIZED | t2 | ref | t2_c2 | t2_c2 | 5 | const | 2 | |
          | 2 | DEPENDENT SUBQUERY | t2 | ALL | NULL | NULL | NULL | NULL | 8 | Using where |
          +------+--------------------+-------------+--------+---------------+--------------+---------+-------+------+-------------+
          {noformat}

          *but it is expected that the plan will be similar to the plan for SELECT*

          MTR test case:
          {code:sql}

          create table t1 (c1 integer, c2 integer, c3 integer) ;
          insert into t1(c1,c2,c3)
          values (1,1,1),(1,2,2),(1,3,3),
          (2,1,4),(2,2,5),(2,3,6),
          (2,4,7),(2,5,8);
          create view v1 as select * from t1 where c2=2;
          create index t1_c2 on t1 (c2);
          analyze table t1 persistent for all;

          create table t2 (c1 integer, c2 integer, c3 integer) ;
          insert into t2(c1,c2,c3)
          values (1,1,1),(1,2,2),(1,3,3),
          (2,1,4),(2,2,5),(2,3,6),
          (2,4,7),(2,5,8);
          create view v2 as select * from t2 where c2=2;
          create index t2_c2 on t2 (c2);
          analyze table t2 persistent for all;

          create table t3 (c1 integer, c2 integer, c3 integer) ;
          insert into t3(c1,c2,c3)
          values (1,1,1),(1,2,2),(1,3,3),
          (2,1,4),(2,2,5),(2,3,6),
          (2,4,7),(2,5,8);
          analyze table t3 persistent for all;

          explain
          select *
           from v1,t3
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      exists (select 'X' from v2 where c1 = v1.c1);
           
          explain
          delete
           from v1
           using v1,t3
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      exists (select 'X' from v2 where c1 = v1.c1);

          explain
          update v1,t3
          set v1.c1 = 15
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      exists (select 'X' from v2 where c1 = v1.c1);

          drop view v1, v2;
          drop table t1, t2, t3;
          {code}

          OK to push

          sanja Oleksandr Byelkin added a comment - OK to push
          sanja Oleksandr Byelkin made changes -
          Assignee Oleksandr Byelkin [ sanja ] Igor Babaev [ igor ]
          Status In Review [ 10002 ] Stalled [ 10000 ]
          igor Igor Babaev (Inactive) made changes -
          Status Stalled [ 10000 ] In Progress [ 3 ]

          This bug was pushed into 10.4. It has to be merged upstream as it is.

          igor Igor Babaev (Inactive) added a comment - This bug was pushed into 10.4. It has to be merged upstream as it is.
          igor Igor Babaev (Inactive) made changes -
          Fix Version/s 10.4.29 [ 28510 ]
          Fix Version/s 10.5.20 [ 28512 ]
          Fix Version/s 10.6.13 [ 28514 ]
          Fix Version/s 10.7.9 [ 28516 ]
          Fix Version/s 10.8.8 [ 28518 ]
          Fix Version/s 10.9.6 [ 28520 ]
          Fix Version/s 10.4 [ 22408 ]
          Resolution Fixed [ 1 ]
          Status In Progress [ 3 ] Closed [ 6 ]
          igor Igor Babaev (Inactive) made changes -
          Description For the following query with SELECT:
          {code:sql}
          explain
          select *
           from v1,t3
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      exists (select 'X' from v2 where c1 = v1.c1);
          {code}

          EXPLAIN produces:
          {noformat}
          MariaDB [test]> explain
              -> select *
              -> from v1,t3
              -> where
              -> v1.c2 = t3.c2 and
              -> v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
              -> and v1.c1 < 10 and
              -> exists (select 'X' from v2 where c1 = v1.c1);
          +------+--------------------+-------------+--------+---------------+--------------+---------+-------+------+-------------------------------------------------+
          | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
          +------+--------------------+-------------+--------+---------------+--------------+---------+-------+------+-------------------------------------------------+
          | 1 | PRIMARY | t1 | ref | t1_c2 | t1_c2 | 5 | const | 2 | Using where |
          | 1 | PRIMARY | <subquery3> | eq_ref | distinct_key | distinct_key | 4 | func | 1 | |
          | 1 | PRIMARY | t3 | ALL | NULL | NULL | NULL | NULL | 8 | Using where; Using join buffer (flat, BNL join) |
          | 3 | MATERIALIZED | t2 | ref | t2_c2 | t2_c2 | 5 | const | 2 | |
          | 2 | DEPENDENT SUBQUERY | t2 | ALL | NULL | NULL | NULL | NULL | 8 | Using where |
          +------+--------------------+-------------+--------+---------------+--------------+---------+-------+------+-------------------------------------------------+
          {noformat}

          For the queries with DELETE and UPDATE based on previous SELECT:
          {code:sql}
          delete
           from v1
           using v1,t3
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      exists (select 'X' from v2 where c1 = v1.c1);
          {code}

          {code:sql}
          update v1,t3
          set v1.c1 = 15
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      exists (select 'X' from v2 where c1 = v1.c1);
          {code}

          EXPLAIN produces:
          {noformat}
          MariaDB [test]> explain
              -> delete
              -> from v1
              -> using v1,t3
              -> where
              -> v1.c2 = t3.c2 and
              -> v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
              -> and v1.c1 < 10 and
              -> exists (select 'X' from v2 where c1 = v1.c1);
          +------+--------------------+-------------+--------+---------------+--------------+---------+-------+------+-------------+
          | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
          +------+--------------------+-------------+--------+---------------+--------------+---------+-------+------+-------------+
          | 1 | PRIMARY | t1 | ref | t1_c2 | t1_c2 | 5 | const | 2 | Using where |
          | 1 | PRIMARY | <subquery3> | eq_ref | distinct_key | distinct_key | 4 | func | 1 | |
          | 1 | PRIMARY | t3 | ALL | NULL | NULL | NULL | NULL | 8 | Using where |
          | 3 | MATERIALIZED | t2 | ref | t2_c2 | t2_c2 | 5 | const | 2 | |
          | 2 | DEPENDENT SUBQUERY | t2 | ALL | NULL | NULL | NULL | NULL | 8 | Using where |
          +------+--------------------+-------------+--------+---------------+--------------+---------+-------+------+-------------+
          {noformat}

          *but it is expected that the plan will be similar to the plan for SELECT*

          MTR test case:
          {code:sql}

          create table t1 (c1 integer, c2 integer, c3 integer) ;
          insert into t1(c1,c2,c3)
          values (1,1,1),(1,2,2),(1,3,3),
          (2,1,4),(2,2,5),(2,3,6),
          (2,4,7),(2,5,8);
          create view v1 as select * from t1 where c2=2;
          create index t1_c2 on t1 (c2);
          analyze table t1 persistent for all;

          create table t2 (c1 integer, c2 integer, c3 integer) ;
          insert into t2(c1,c2,c3)
          values (1,1,1),(1,2,2),(1,3,3),
          (2,1,4),(2,2,5),(2,3,6),
          (2,4,7),(2,5,8);
          create view v2 as select * from t2 where c2=2;
          create index t2_c2 on t2 (c2);
          analyze table t2 persistent for all;

          create table t3 (c1 integer, c2 integer, c3 integer) ;
          insert into t3(c1,c2,c3)
          values (1,1,1),(1,2,2),(1,3,3),
          (2,1,4),(2,2,5),(2,3,6),
          (2,4,7),(2,5,8);
          analyze table t3 persistent for all;

          explain
          select *
           from v1,t3
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      exists (select 'X' from v2 where c1 = v1.c1);
           
          explain
          delete
           from v1
           using v1,t3
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      exists (select 'X' from v2 where c1 = v1.c1);

          explain
          update v1,t3
          set v1.c1 = 15
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      exists (select 'X' from v2 where c1 = v1.c1);

          drop view v1, v2;
          drop table t1, t2, t3;
          {code}
          For the following query with SELECT:
          {code:sql}
          explain
          select *
           from v1,t3
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      exists (select 'X' from v2 where c1 = v1.c1);
          {code}

          EXPLAIN produces:
          {noformat}
          MariaDB [test]> explain
              -> select *
              -> from v1,t3
              -> where
              -> v1.c2 = t3.c2 and
              -> v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
              -> and v1.c1 < 10 and
              -> exists (select 'X' from v2 where c1 = v1.c1);
          +------+--------------------+-------------+--------+---------------+--------------+---------+-------+------+-------------------------------------------------+
          | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
          +------+--------------------+-------------+--------+---------------+--------------+---------+-------+------+-------------------------------------------------+
          | 1 | PRIMARY | t1 | ref | t1_c2 | t1_c2 | 5 | const | 2 | Using where |
          | 1 | PRIMARY | <subquery3> | eq_ref | distinct_key | distinct_key | 4 | func | 1 | |
          | 1 | PRIMARY | t3 | ALL | NULL | NULL | NULL | NULL | 8 | Using where; Using join buffer (flat, BNL join) |
          | 3 | MATERIALIZED | t2 | ref | t2_c2 | t2_c2 | 5 | const | 2 | |
          | 2 | DEPENDENT SUBQUERY | t2 | ALL | NULL | NULL | NULL | NULL | 8 | Using where |
          +------+--------------------+-------------+--------+---------------+--------------+---------+-------+------+-------------------------------------------------+
          {noformat}

          For the queries with DELETE and UPDATE based on previous SELECT:
          {code:sql}
          delete
           from v1
           using v1,t3
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      exists (select 'X' from v2 where c1 = v1.c1);
          {code}

          {code:sql}
          update v1,t3
          set v1.c1 = 15
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      exists (select 'X' from v2 where c1 = v1.c1);
          {code}

          EXPLAIN produces:
          {noformat}
          MariaDB [test]> explain
              -> delete
              -> from v1
              -> using v1,t3
              -> where
              -> v1.c2 = t3.c2 and
              -> v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
              -> and v1.c1 < 10 and
              -> exists (select 'X' from v2 where c1 = v1.c1);
          +------+--------------------+-------+------+---------------+-------+---------+-------+------+-------------+
          | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
          +------+--------------------+-------+------+---------------+-------+---------+-------+------+-------------+
          | 1 | PRIMARY | t1 | ref | t1_c2 | t1_c2 | 5 | const | 2 | Using where |
          | 1 | PRIMARY | t3 | ALL | NULL | NULL | NULL | NULL | 8 | Using where |
          | 3 | DEPENDENT SUBQUERY | t2 | ref | t2_c2 | t2_c2 | 5 | const | 2 | Using where |
          | 2 | DEPENDENT SUBQUERY | t2 | ALL | NULL | NULL | NULL | NULL | 8 | Using where |
          +------+--------------------+-------+------+---------------+-------+---------+-------+------+-------------+

          MariaDB [test]> explain
              -> update v1,t3
              -> set v1.c1 = 15
              -> where
              -> v1.c2 = t3.c2 and
              -> v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
              -> and v1.c1 < 10 and
              -> exists (select 'X' from v2 where c1 = v1.c1);
          +------+--------------------+-------+------+---------------+-------+---------+-------+------+-------------+
          | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
          +------+--------------------+-------+------+---------------+-------+---------+-------+------+-------------+
          | 1 | PRIMARY | t1 | ref | t1_c2 | t1_c2 | 5 | const | 2 | Using where |
          | 1 | PRIMARY | t3 | ALL | NULL | NULL | NULL | NULL | 8 | Using where |
          | 3 | DEPENDENT SUBQUERY | t2 | ref | t2_c2 | t2_c2 | 5 | const | 2 | Using where |
          | 2 | DEPENDENT SUBQUERY | t2 | ALL | NULL | NULL | NULL | NULL | 8 | Using where |
          +------+--------------------+-------+------+---------------+-------+---------+-------+------+-------------+

          {noformat}

          *but it is expected that the plan will be similar to the plan for SELECT*

          MTR test case:
          {code:sql}

          create table t1 (c1 integer, c2 integer, c3 integer) ;
          insert into t1(c1,c2,c3)
          values (1,1,1),(1,2,2),(1,3,3),
          (2,1,4),(2,2,5),(2,3,6),
          (2,4,7),(2,5,8);
          create view v1 as select * from t1 where c2=2;
          create index t1_c2 on t1 (c2);
          analyze table t1 persistent for all;

          create table t2 (c1 integer, c2 integer, c3 integer) ;
          insert into t2(c1,c2,c3)
          values (1,1,1),(1,2,2),(1,3,3),
          (2,1,4),(2,2,5),(2,3,6),
          (2,4,7),(2,5,8);
          create view v2 as select * from t2 where c2=2;
          create index t2_c2 on t2 (c2);
          analyze table t2 persistent for all;

          create table t3 (c1 integer, c2 integer, c3 integer) ;
          insert into t3(c1,c2,c3)
          values (1,1,1),(1,2,2),(1,3,3),
          (2,1,4),(2,2,5),(2,3,6),
          (2,4,7),(2,5,8);
          analyze table t3 persistent for all;

          explain
          select *
           from v1,t3
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      exists (select 'X' from v2 where c1 = v1.c1);
           
          explain
          delete
           from v1
           using v1,t3
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      exists (select 'X' from v2 where c1 = v1.c1);

          explain
          update v1,t3
          set v1.c1 = 15
          where
            v1.c2 = t3.c2 and
            v1.c2 in (select max(c2) from t2 where c3 = v1.c3)
                      and v1.c1 < 10 and
                      exists (select 'X' from v2 where c1 = v1.c1);

          drop view v1, v2;
          drop table t1, t2, t3;
          {code}
          serg Sergei Golubchik made changes -
          Fix Version/s 10.7.9 [ 28516 ]

          People

            igor Igor Babaev (Inactive)
            lstartseva Lena Startseva
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Git Integration

                Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.