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

ref_to_range rewrite causes poor query plan

    XMLWordPrintable

Details

    Description

      Consider a testcase:

      create table t1 (a int);
      insert into t1 select seq from seq_1_to_100;
       
      create table t2 (
        kp1 int,
        kp2 int,
        filler char(100),
        key(kp1, kp2)
      );
      insert into t2
      select 
        seq, seq,
        'filler-data'
      from seq_1_to_10000;
      

      Suppose table t2 has

      • a ref(non-const) access
      • a range access that uses more keyparts than ref:

      Query Q1:

      explain
      select * 
      from t1, t2 
      where 
       t2.kp1=t1.a and t2.kp1<=100 and t2.kp2<=20
      

      The query plan is:

      +------+-------------+-------+-------+---------------+------+---------+------+------+------------------------------------------------------------------------+
      | id   | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra                                                                  |
      +------+-------------+-------+-------+---------------+------+---------+------+------+------------------------------------------------------------------------+
      |    1 | SIMPLE      | t1    | ALL   | NULL          | NULL | NULL    | NULL | 100  | Using where                                                            |
      |    1 | SIMPLE      | t2    | range | kp1           | kp1  | 10      | NULL | 999  | Using index condition; Using where; Using join buffer (flat, BNL join) |
      +------+-------------+-------+-------+---------------+------+---------+------+------+------------------------------------------------------------------------+
      

      One can get a much better if one prevents the optimizer from constructing range access with two keyparts:
      Query Q2:

      explain
      select *
      from t1, t2
      where
        t2.kp1=t1.a and t2.kp1<=1000 and t2.kp2+1<=20; -- make kp2 unusable for range.
      

      +------+-------------+-------+------+---------------+------+---------+-----------+------+-----------------------+
      | id   | select_type | table | type | possible_keys | key  | key_len | ref       | rows | Extra                 |
      +------+-------------+-------+------+---------------+------+---------+-----------+------+-----------------------+
      |    1 | SIMPLE      | t1    | ALL  | NULL          | NULL | NULL    | NULL      | 100  | Using where           |
      |    1 | SIMPLE      | t2    | ref  | kp1           | kp1  | 5       | test.t1.a | 1    | Using index condition |
      +------+-------------+-------+------+---------------+------+---------+-----------+------+-----------------------+
      

      Examining the optimizer trace for Q1, one can see that the optimizer picks ref access for table t2, but then the rewrite makes it range access:

                    "attached_conditions_computation": [
                      {
                        "ref_to_range": true,
                        "cause": "range uses longer key"
                      }
                    ],
      

      Attachments

        Activity

          People

            psergei Sergei Petrunia
            psergei Sergei Petrunia
            Votes:
            0 Vote for this issue
            Watchers:
            3 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.