Why Mysql use index for a single table, but not when join

KouAkira Chin :

I wonder why mysql use index for a single table query, while not for a join query, even i force using index.

Just show the tables and querys:

show create table dc_assess_plan_batch;
CREATE TABLE `dc_assess_plan_batch` (
   `id` varchar(255) NOT NULL,
   `app_batch_id` varchar(255) NOT NULL COMMENT '数据来源的id ',
   `project_id` varchar(255) NOT NULL COMMENT '课程计划id',
   `name` varchar(32) DEFAULT NULL COMMENT '批次名',
   `time` datetime DEFAULT NULL COMMENT '批次的时间',
   `batch_id` varchar(255) DEFAULT NULL,
   `status` tinyint(4) DEFAULT NULL COMMENT '1.可用关系.0 不可用',
   `app_from` varchar(10) DEFAULT NULL COMMENT '数据来源',
   PRIMARY KEY (`id`),
   KEY `inx_project_id` (`project_id`) USING BTREE,
   KEY `app_batch_id` (`app_batch_id`) USING BTREE
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `dc_assess_task` (
   `id` varchar(255) NOT NULL,
   `name` varchar(255) DEFAULT NULL COMMENT '任务名称',
   `class_id` varchar(255) DEFAULT NULL COMMENT '班级id',
   `course_id` varchar(255) DEFAULT NULL COMMENT '课程id',
   `app_from` varchar(255) DEFAULT NULL COMMENT '成绩来源',
   `term_id` varchar(255) DEFAULT NULL COMMENT '学期id',
   `publish_time` datetime DEFAULT NULL COMMENT '任务发布时间',
   `completion_degree` double(10,3) DEFAULT NULL COMMENT '完成度',
   `course_name` varchar(255) DEFAULT NULL COMMENT '课程名称',
   `school_id` varchar(255) DEFAULT NULL,
   `app_batch_id` varchar(255) NOT NULL,
   `score_type` varchar(10) DEFAULT NULL COMMENT '''成绩计算规则 COUNT :按数量,  SCORE:按照分数, KCBCOUNT:按课程币数量'',',
   `xxpj_mode` enum('BY_GROUP','BY_PERSON') DEFAULT NULL COMMENT '线下评价评分模式',
   `upload_flag` tinyint(4) NOT NULL DEFAULT '0' COMMENT '标志任务是否线下上传,1是,0否',
   PRIMARY KEY (`id`),
   KEY `FKrx8fxs12oe1mafttciiwir6cm` (`app_from`) USING BTREE,
   KEY `app_batch_id` (`app_batch_id`) USING BTREE
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

There are two tables, and both have index on filed 'app_batch_id'

  • query1:
explain select * from dc_assess_plan_batch where app_batch_id = '2ebb4066038441229e937d2de4a9b5632018-12-07';

# id, select_type, table, type, possible_keys, key, key_len, ref, rows, Extra
1   SIMPLE  dc_assess_plan_batch    ref app_batch_id    app_batch_id    767 const   1   Using index condition
  • query2
explain select * from dc_assess_plan_batch dapb join dc_assess_task dat on dapb.app_batch_id = dat.app_batch_id where dat.course_id = '562aecc2d1c64fabbff4a18496acc757';

# id, select_type, table, type, possible_keys, key, key_len, ref, rows, Extra
1   SIMPLE  dapb    ALL app_batch_id                277947  
1   SIMPLE  dat ref app_batch_id    app_batch_id    767 ifass.dapb.app_batch_id 1   Using where

-query3

explain select * from dc_assess_plan_batch dapb force index (app_batch_id) join dc_assess_task dat on dapb.app_batch_id = dat.app_batch_id where dat.course_id = '562aecc2d1c64fabbff4a18496acc757';

# id, select_type, table, type, possible_keys, key, key_len, ref, rows, Extra
1   SIMPLE  dapb    ALL app_batch_id                277947  
1   SIMPLE  dat ref app_batch_id    app_batch_id    767 ifass.dapb.app_batch_id 1   Using where

Why index on 'app_batch_id' not work when join, even force using index

Rick James :

Which runs faster? Sometimes the "Optimizer knows best". However, the EXPLAINs seem the same?

I would expect these to help significantly with performance:

dat:  (course_id, app_batch_id)  -- the table has nothing like this
dapb:  (app_batch_id)

When seeing a JOIN, the Optimizer usually looks at the WHERE clause to decide which table to start with. But, alas, there is no index for dat.course_id. SO it needs to run the query in a "brute force" way -- Scan all of one table, then reach into the other. A strong clue of this is ALL .. 277947 in the EXPLAIN. That says that it could not benefit from an index on dat.

If it had such an index, the Optimizer would start with dat, reach in for perhaps 1 row, not 277947, then reach into the other table using the index you already have, even without using FORCE INDEX.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=9550&siteId=1