Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql InnoDB未进行索引合并_Mysql_Indexing_Innodb - Fatal编程技术网

Mysql InnoDB未进行索引合并

Mysql InnoDB未进行索引合并,mysql,indexing,innodb,Mysql,Indexing,Innodb,我有一张这样的桌子 CREATE TABLE values ( id int(10) auto_increment NOT NULL, molecule_id int(5) NOT NULL, descriptor_id int(5) NOT NULL, T double DEFAULT NULL, value double NOT NULL, PRIMARY KEY (id), KEY index1 (molecule_id, T),

我有一张这样的桌子

CREATE TABLE values (
    id int(10) auto_increment NOT NULL, 
    molecule_id int(5) NOT NULL,
    descriptor_id int(5) NOT NULL,
    T double DEFAULT NULL,
    value double NOT NULL,
    PRIMARY KEY (id),
    KEY index1 (molecule_id, T),
    KEY index2 (descriptor_id, T)
) ENGINE=InnoDB;    
表中的行是3000个描述符ID、600个分子ID和3500个随机双倍值(约20亿行)的组合

我的印象是,对于这样一个问题

SELECT T, value FROM values WHERE molecule_id = X AND descriptor_id = Y
mysql将使用两个键,然后与结果相交。但是在这个查询上执行
Explain extended
告诉我它只使用index2,在index1和index2之间进行了选择

分子_id=X约占表的1/600。 descriptor_id=Y命中表中非常小的部分(如0.001%)或大约1/700,具体取决于Y

看起来相交要比使用index2扫描250多万行中的其余行快得多。即使3000个描述符ID均匀分布,平均仍会有800000行需要扫描


我缺少什么?

我相信只有在至少一个键上进行范围扫描时才会使用
索引\u合并
操作。您的示例查询只有相等谓词,MySQL没有将其视为范围扫描。

spencer7593正确。索引合并仅在范围情况下发生。如果您的
,则会触发索引合并。然而,既然它是一个
,为什么不在
分子id和
描述符id上建立一个多列索引呢?这将使您更快地获得更好的结果。如果
descriptor\u id
更具排他性(如您所述),请执行以下操作:

ALTER TABLE value添加索引描述符\u molecular(描述符\u id,molecular\u id,T,value)


只要您的查询在where子句中同时具有
条件,它就会使用此索引。在这种情况下,我实际上会删除您的
index2
,因为如果查询在where子句中只有
descriptor\u id
列,它仍然可以使用
descriptor\u
索引作为前缀索引。另外,索引所有4列将为您提到的查询创建一个覆盖索引,从而大大加快查询速度。

覆盖索引可能会提供更好的性能
(描述符id、分子id、T、值)
。(我打算建议一个索引(就像你那样)在你的回答中,我没有说到这里,只是回答了一个问题,为什么我们不希望MySQL执行
索引合并
操作。问题是,描述符id、分子id、T的每一个组合在查询中都是可能的,即使有范围。像
SELECT*这样的查询来自描述符id=X和分子I的值Y和Z之间的d仍然不合并,不能使用类似(分子id、描述符id)的索引。因此,如果我想以最佳性能涵盖所有可能性,我需要6个索引,不是吗?还有,有人能给我解释一下这篇博客文章吗?在我看来,它在第三个列表中的两个单列索引相交,就像我在问题中发布的一样。没关系,我在手册中发现了这个条件,我必须当WHERE子句被转换为不同键上的多个范围条件并与AND组合时,可以使用这种访问算法,每个条件都是以下条件之一:在这种形式中,索引正好有N个部分(也就是说,所有索引部分都被覆盖):key\u part1=const1和key\u part2=const2…和key\u partN=constN“。如果我有两个单独的单列索引,它确实会相交,但因为在我的表中,索引是多列的,所以不能使用它们相交。将
t,value
添加到
descriptor\id,molecular\u id
的索引中会很好。当我写我的响应时,我不在其中,试图弄清楚
t是什么
是(我没有看到
t
)列。不过,我的答案是肯定的。正如您所提到的,如果引入范围查找,它显然将停止在该列使用索引。在某些情况下,您将需要基于查询的多个索引。