我在where子句中查询了哪些列是主键的一部分,并且在所有列上都有外键索引。
EXPLAIN SELECT aggEI.c_id AS companyId, aggEI.ei_uid AS uuid
FROM AGG_EI AS aggEI
WHERE aggEI.c_id in (8) and aggEI.tg_id IN (1,2,3,4,5,6,7)
AND aggEI.dt_id = 20130506
我还在(c_id
,tg_id
,dt_id
上定义了多个columnn索引,但EXPLAIN显示它正在c_id
上使用外键索引
1 SIMPLE aggEI ref PRIMARY,datedm_id_UNIQUE,agg_ei_comdm_fk_idx,agg_ei_datedm_fk_idx,agg_ei_topgrp_fk_idx,comp_uuid agg_ei_comdm_fk_idx 8 const 65986 Using where; Using index
agg_ei_comdm_fk_idx是c_id
上的外键索引,comp_uuid是(c_id
,tg_id
,dt_id
)上的多列索引
有人可以解释为什么会这样发生吗
编辑:创建表格
'CREATE TABLE `AGG_EI` (
`dt_id` int(11) NOT NULL,
`c_id` bigint(20) NOT NULL,
`tg_id` bigint(20) NOT NULL,
`ei_uid` varchar(150) NOT NULL
`ei_name` varchar(150) NOT NULL,
`rating` double NOT NULL,
`cnt` double NOT NULL
PRIMARY KEY (`dt_id`,`c_id`,`tg_id`,`ei_uid`),
UNIQUE KEY `datedm_id_UNIQUE` (`dt_id`,`c_id`,`ei_uid`,`tg_id`),
KEY `agg_ei_comdm_fk_idx` (`c_id`),
KEY `agg_ei_datedm_fk_idx` (`dt_id`),
KEY `agg_ei_topgrp_fk_idx` (`tg_id`),
KEY `comp_uuid` (`c_id`,`tg_id`,`dt_id`),
CONSTRAINT `agg_ei_comdm_fk` FOREIGN KEY (`c_id`) REFERENCES `COMPDM` (`c_id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `agg_ei_datedm_fk` FOREIGN KEY (`dt_id`) REFERENCES `DATEDM` (`dt_id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `agg_ei_topgrp_fk` FOREIGN KEY (`tg_id`) REFERENCES `TOPGRP` (`tg_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8'
答案 0 :(得分:4)
MySQL正在使用它认为会发挥最佳性能的计划来执行查询。更有可能的是,它确定将c_id
限制为单个值会将结果集减少到足够少的行,这会导致处理另一个索引中额外列的麻烦并不值得。 MySQL最好的猜测是,使用c_id
限制行更快,然后只过滤内存中的那些行。仅仅因为你有一个索引并不意味着这是最快的计划。
答案 1 :(得分:-1)
您可以强制mysql使用如下索引:
EXPLAIN
SELECT
aggEI.c_id AS companyId,
aggEI.ei_uid AS uuid
FROM
AGG_EI AS aggEI FORCE INDEX(`comp_uuid`)
WHERE
aggEI.c_id in (8)
AND aggEI.tg_id IN (1,2,3,4,5,6,7)
AND aggEI.dt_id = 20130506