Mysql select 优化(巨大的数据库)

Mysql select optimization (huge db)

我在 MySQL 有一个 select 请求,需要 25-30 秒,非常长,我想知道你是否可以帮我固定它。

CREATE TEMPORARY TABLE results(
    id VARCHAR(30),
    secondid VARCHAR(5),
    allele VARCHAR(30),
    translation VARCHAR(10),
    level VARCHAR(20),
    subgroup VARCHAR(20),
    subgroup2 VARCHAR(20)
);
INSERT INTO results(id, secondid, allele, level) SELECT DISTINCT t1.id, t1.secondid, t1.texte, t3.texte
FROM database t1
JOIN database t2 ON t1.id=t2.id
JOIN database t3 ON t1.id=t3.id AND t1.secondid=t3.secondid
WHERE (t1.qualifier,t2.qualifier) = ("allele","organism") AND t3.qualifier = "level_length" AND t3.texte NOT REGEXP "X" AND t3.texte IS NOT NULL
AND t2.texte = ? AND t1.texte REGEXP ?
GROUP BY t1.texte;
UPDATE results SET translation = (SELECT t1.qualifier
FROM database t1
JOIN database t2 ON t1.id=t2.id AND t1.secondid=t2.secondid
JOIN database t3 ON t1.id=t3.id AND t1.secondid=t3.secondid
WHERE t1.qualifier IN ("protein","ncRNA","rRNA") AND t2.texte=results.allele AND t3.texte=results.level LIMIT 1);
UPDATE results SET subgroup = (SELECT t2.subgrp
FROM alleledb.alleleSubgroups t1
JOIN alleledb.subgroups t2 ON t1.subgroup=t2.subgroup
WHERE t1.gene=SUBSTRING_INDEX(results.allele, "*", 1) AND t1.species=? LIMIT 1);
ALTER TABLE results DROP id, DROP secondid;
SELECT * FROM results ORDER BY subgroup ASC, level ASC;
DROP TABLE results;

我需要通过很多数据库才能加入(相同的 ID),数据库很大但提取的结果很低(不到所有数据库的 1%)。大多数结果存储在同一个数据库中的不同行中(具有相同的 id 和 secondid)。但是,id 和 secondid 并不是我需要的行唯一的 select,只有两者的组合才是。

谢谢。

我首先要在你的数据库上建立一个合适的复合索引 table

首先在

(qualifier, id, secondid, texte)  

这将有助于您的连接、测试位置,并且不必返回到记录的实际原始数据 table,因为索引中包含您感兴趣的数据。

接下来,我会调整query/joins。由于您是专门从 t1 和 t2 分别寻找“等位基因”和“生物体”,因此将它们制作成这样。

我不知道你用 REGEXP“X”或“?”做什么texte 的值,但你会在之后弄清楚。

这是我修改查询的方式

insert into ...
SELECT DISTINCT 
        t1.id, 
        t1.secondid, 
        t1.texte, 
        t3.texte
    FROM 
        database t1
            JOIN database t2 
                ON t1.id = t2.id
                AND t2.qualifier = 'organism'
            JOIN database t3 ON 
                    t1.id = t3.id 
                AND t1.secondid = t3.secondid
                AND t3.qualifier = 'level_length'
    WHERE 
            t1.qualifier = 'allele'
        AND t1.texte REGEXP ?
        -- I would move these t2 and t3 into the respective JOINs above directly.
        AND t3.texte NOT REGEXP "X" 
        AND t3.texte IS NOT NULL
        AND t2.texte = ? 
    GROUP BY 
        t1.texte;

至于您的 UPDATE 命令,在 (id, secondid) 上有第二个索引将有助于连接到 t2 和 t3,因为连接没有限定符上下文。

至于你的 UPDATE 命令,正如 Rick 提到的,如果没有 ORDER BY 子句的一些上下文,你无法保证 LIMIT 1 返回 WHICH 记录。

首先感谢大家的帮助。 我的第一个 table (插入和第一次更新,数据库命名)看起来像这样:

我想要所有的东西都是红色的。换句话说,我需要一些与id中唯一的“级别”具有相同id和secondid的参数。而其他参数可能会在同一个 ID 中重复(但第二个 ID 不同)。 我使用 REGEXP 和物种的等位基因名称(EC 基因座中的 ECK)进行过滤。例如,来自人类 EC 基因座的所有等位基因。

然后(上次更新),我采用一个参数(等位基因),对其进行子字符串化,然后转到一个给我一个 ID(一行 -> 一个 ID)的数据库。我在注释数据库上使用这个 id,它给我一两行(一个或两个子组 subgroups/rare)。因此,在我的示例中,我只有一组,没有看到 ORDER BY 的缺失。但是,是的,我想订购(首先获取包含等位基因的子组)。我不知道该怎么做。

最后,我可以尝试创建一个索引,但是由于数据库的大小,我想知道这样一个索引的时间和大小。它会显着缩短时间吗?我可以删除它吗?

REGEXP“X”是为了删除所有与此参数无关的匹配项(我不想要它们)。 这 ?是用户输入(对于 species/2 次出现,这个和轨迹)。

第一个数据库的操作需要30s,最后两个数据库的操作持续1-2s。其他(下降,select)<20ms(不是问题)。