你能帮我解决这个问题吗?为什么这个MySQL查询不使用完整索引?
SELECT p.patid, MAX(c1.eventdate) as eventdate
from patient as p
left join op_adv_effects._clinical as c1 on p.patid = c1.patid
where c1.eventdate < p.case_index
group by p.patid
这里是SHOW的输出CREATE TABLE为2个表:
patient CREATE TABLE `patient` (
`patid` int(10) unsigned NOT NULL,
`case_index` date NOT NULL,
PRIMARY KEY (`patid`,`case_index`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_general_cs
_clinical CREATE TABLE `_clinical` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`patid` int(10) unsigned NOT NULL,
`eventdate` date NOT NULL,
`medcode` mediumint(8) unsigned DEFAULT NULL,
`adid` mediumint(8) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_clin_eventdate_medcode` (`patid`,`eventdate`,`medcode`),
KEY `idx_clin_eventdate_adid` (`patid`,`eventdate`,`adid`)
) ENGINE=InnoDB AUTO_INCREMENT=62407536 DEFAULT CHARSET=latin1 COLLATE=latin1_general_cs
“解释” 返回以下内容:为什么不使用第2场
*************************** 1. row ********************
id: 1
select_type: SIMPLE
table: p
type: index
possible_keys: PRIMARY
key: PRIMARY
key_len: 7
ref: NULL
rows: 182939
Extra: Using index
*************************** 2. row ********************
id: 1
select_type: SIMPLE
table: c1
type: ref
possible_keys: idx_clin_eventdate_medcode,idx_clin_eventdate_adid
key: idx_clin_eventdate_medcode
key_len: 4
ref: gprd_opadveff_extra_elisa.p.patid
rows: 171
Extra: Using where; Using index
idx_clin_eventdate_medcode,即(patid,eventdate),但只有patid(请参阅ref列)?
如果我改变where条件的平等,它工作正常:
SELECT p.patid, MAX(c1.eventdate) as eventdate
from patient as p
left join op_adv_effects._clinical as c1 on p.patid = c1.patid
where c1.eventdate = p.case_index
group by p.patid
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: p
type: index
possible_keys: PRIMARY
key: PRIMARY
key_len: 7
ref: NULL
rows: 182939
Extra: Using index
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: c1
type: ref
possible_keys: idx_clin_eventdate_medcode,idx_clin_eventdate_adid
key: idx_clin_eventdate_medcode
key_len: 7
ref: gprd_opadveff_extra_elisa.p.patid,gprd_opadveff_extra_elisa.p.cas
e_index
rows: 1
Extra: Using index
一些相同结果提示变化:
explain SELECT patid,
(SELECT eventdate
FROM op_adv_effects._clinical
WHERE patid = p.patid
AND eventdate < p.case_index
ORDER BY eventdate DESC
LIMIT 1) AS eventdate
FROM patient AS p;
*************************** 1. row ***************************
id: 1
select_type: PRIMARY
table: p
type: index
possible_keys: NULL
key: PRIMARY
key_len: 7
ref: NULL
rows: 182939
Extra: Using index
*************************** 2. row ***************************
id: 2
select_type: DEPENDENT SUBQUERY
table: _clinical
type: ref
possible_keys: idx_clin_eventdate_medcode,idx_clin_eventdate_adid
key: idx_clin_eventdate_medcode
key_len: 4
ref: gprd_opadveff_extra_elisa.p.patid
rows: 171
Extra: Using where; Using index; Using filesort
explain SELECT patid,
(SELECT MAX(eventdate)
FROM op_adv_effects._clinical
WHERE patid = p.patid
AND eventdate < p.case_index) AS eventdate
FROM patient AS p;
*************************** 1. row ***************************
id: 1
select_type: PRIMARY
table: p
type: index
possible_keys: NULL
key: PRIMARY
key_len: 7
ref: NULL
rows: 182939
Extra: Using index
*************************** 2. row ***************************
id: 2
select_type: DEPENDENT SUBQUERY
table: _clinical
type: ref
possible_keys: idx_clin_eventdate_medcode,idx_clin_eventdate_adid
key: idx_clin_eventdate_medcode
key_len: 4
ref: gprd_opadveff_extra_elisa.p.patid
rows: 171
Extra: Using where; Using index
查询是一个比较复杂的一个组成部分,报道如下。但是,这只是几个复杂查询的一个示例,应该都使用eventdate上缺少的部分索引。出于这个原因,这非常重要。
CREATE TABLE bmi_lp
(PRIMARY KEY (patid))
ENGINE=INNODB DEFAULT CHARSET=latin1 COLLATE=latin1_general_cs
SELECT tmp.patid, a2.data3 as bmi_lp, tmp.eventdate as bmi_lp_date
from (
SELECT p.patid, MAX(c.eventdate) as eventdate
from patient as p
left join op_adv_effects._clinical as c1 on p.patid = c1.patid
left join op_adv_effects._additional as a1 on c1.patid = a1.patid
where c1.adid <> 0 and c1.adid = a1.adid
and a1.enttype = 13
and a1.data3 is not null
and c1.eventdate < p.case_index
group by p.patid
order by p.patid) as tmp
left join op_adv_effects._clinical as c2 on tmp.patid = c2.patid
left join op_adv_effects._additional as a2 on c2.patid = a2.patid
where tmp.eventdate = c2.eventdate and c2.adid = a2.adid
请注意,此查询呈现为INNER JOIN – Strawberry