我的MySQL 5.5数据库出现了以下问题 - 我对此很新,所以它可能非常明显,但是我似乎无法得到它:
两张桌子:
表1
CREATE TABLE `sequence_matches` (
`Sample_ID` INT(6) NOT NULL,
`Sequence_Match_ID` INT(8) NOT NULL,
`Start` INT(6) NULL DEFAULT NULL,
`End` INT(6) NULL DEFAULT NULL,
`Coverage` DOUBLE(5,2) NULL DEFAULT NULL,
`Frag_String` VARCHAR(255) NULL DEFAULT NULL,
`rms_mass_error_prod` DOUBLE(10,4) NULL DEFAULT NULL,
`rms_rt_error_prod` DOUBLE(10,4) NULL DEFAULT NULL,
PRIMARY KEY (`Sample_ID`, `Sequence_Match_ID`)
)
和
表2
CREATE TABLE `peptide_identifications` (
`Sample_ID` INT(6) NOT NULL,
`Peptide_identification_ID` INT(8) NOT NULL,
`Mass_error` DOUBLE(10,4) NULL DEFAULT NULL,
`Mass_error_ppm` DOUBLE(10,4) NULL DEFAULT NULL,
`Score` DOUBLE(10,4) NULL DEFAULT NULL,
`Type` VARCHAR(45) NULL DEFAULT NULL,
`global_pept_ID` INT(8) NOT NULL,
PRIMARY KEY (`Sample_ID`, `Peptide_identification_ID`),
INDEX `Index` (`global_pept_ID`)
)
每个包含约1500万行。
现在,我希望Table2
global_pept_id = 27443
中的所有行,然后使用peptide_identification_id
中的Table1
来查询来自peptide_identification_id = sequence_match_id
SELECT * from sequence_matches
JOIN (
SELECT peptide_identification_id
FROM peptide_identifications
WHERE global_pept_id = 27443
) as tmp_pept
ON sequence_match_id = peptide_identification_id;
的所有信息
我尝试了以下声明:
{{1}}
这里是该查询的解释:
现在这个查询非常非常慢(我实际上从未完成它,在大约10分钟之后stopepd)并且我可以想象它是因为没有用于第二个表的索引,尽管两个ID都是主键,因此它们应该是索引对吗?
如果单独执行,内部选择的结果需要~3 sek并返回~3k行。所以我认为问题是制作3000 * 15mio比较因为表2中检查了每一行。
但我该如何解决这个问题?
任何帮助表示赞赏 -voiD
答案 0 :(得分:4)
这可能是因为你加入了子查询。尝试:
SELECT sm.*, pi.peptide_identification_id
FROM sequence_matches sm
INNER JOIN peptide_identifications pi
ON sm.id = pi.peptide_identification_id
WHERE pi.global_pept_id = 27443
答案 1 :(得分:1)
与其他解决方案略有不同。考虑您首先尝试获得的主要标准......给定全局肽值的那些肽元素。确保您在此表上有关于您可能要查询的任何此类条件的索引(您有)。但是,如果您发现将针对同一个表查询多个WHERE条件,请尝试准备/拥有一个有助于同时满足条件的索引。
然后,将JOIN条件放到PK / FK关系的另一个表中以获取这些记录。
SELECT *
from
peptide_identification PI
JOIN sequence_matches SM
ON PI.peptide_identification_id = SM.sequence_match_id
WHERE
PI.global_pept_id = 27443
没有适当的索引可能会严重影响查询的性能。您的Sequence_Matches表应该只有(Sequence_match_ID)索引以帮助其优化。将它放在第二个位置(在sample_id之后),将不会像预期的那样受益。
答案 2 :(得分:0)
tipp将避免子选择。有时它们很棒,但通常会导致性能不佳。更好的方法可能是:
SELECT * from peptide_identification as tmp_pept
JOIN sequence_matches
ON sequence_matches.sequence_match_id = tmp_pept.peptide_identification_id
WHERE tmp_pept.global_pept_id = 27443
这样做可以吗?
编辑:不,真正的问题是sequence_match_id上没有索引。加一个,你可能会没事的。
答案 3 :(得分:0)
我认为问题可能是因为你现在正在创建一个交叉连接 而不是内部联接。你的子查询正在创建一个笛卡儿 产品1500万行* 300万行。
使用内部联接,你将这个数字减少到1500万* 3000 行。
它仍然是一个巨大的数字。在Sql端,您可以通过发出来限制它 前10名或前20名。
在前端,如果它是C#你应该使用分页技术 gridviewpager或数据源上的其他分页技术假设你 将在前端显示结果,该结果将位于顶部 您的SQL加入查询和第20页结果一次。