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

cost_for_index_read() doesn't add TIME_FOR_COMPARE/rows.

    XMLWordPrintable

Details

    Description

      Discovered this in TODO-4919.

      Check TODO-4919 for table DDL and imitation-stats.diff .

      Consider a query (constants replaced)

      explain 
      SELECT 
        task0.sys_id  
      FROM 
        task task0  ignore index(number)   
      WHERE    
        task0.sys_class_name = 'const' AND    
        task0.assignment_group = 'uuid-const' AND    
        task0.state IN (1,2,3)  
      ORDER BY    
        task0.number DESC limit 0,20
      

      and two indexes:

      -- assignment_group = 'uuid-const' matches 1% of the table
      INDEX assignment_group(assignment_group) 
       
      -- sys_class_name = 'const' matches 50% of the table
      INDEX sys_class_name_2(sys_class_name, number) 
      

      Range optimizer produces range costs.

      The costs originate from handler::multi_range_read_info_const() and
      do include TIME_FOR_COMPARE:

            cost->cpu_cost+= (rows2double(total_rows) / TIME_FOR_COMPARE +
                              MULTI_RANGE_READ_SETUP_COST);
      

      Then, he code in best_access_path() calls

                        tmp= adjust_quick_cost(table->opt_range[key].cost,
                                               table->opt_range[key].rows);
      

      to remove TIME_FOR_COMPARE from quick select's cost before comparing
      it with other costs. Makes sense.

      Then, in get_range_limit_read_cost(), we take the quick select cost:

            double best_cost= (double) table->opt_range[keynr].cost;
      

      and compare it with the cost we got from cost_for_index_read:

            if (ref_rows > 0)
            {
              double tmp= cost_for_index_read(tab->join->thd, table, keynr,
                                              ref_rows, 
                                              (ha_rows) tab->worst_seeks); 
              if (tmp < best_cost)
      

      Looking inside cost_for_index_read(), I see the cost is computed as follows:

            cost= ((file->keyread_time(key, 0, records) +
                    file->read_time(key, 1, MY_MIN(records, worst_seeks))));
      

      That is, it doesn't include TIME_FOR_COMPARE.
      Should this be fixed?

      Attachments

        Activity

          People

            psergei Sergei Petrunia
            psergei Sergei Petrunia
            Votes:
            1 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:

              Git Integration

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