簡體   English   中英

使用 OR 查詢性能

[英]Query performance with OR

也許這是一個基本問題,但一直無法回答,感謝您的幫助:)

我在 MySQL 中有下表:

create table anotation
    ( 
        chromosome enum
            (
                'Chr1',
                'Chr2',
                'Chr3',
                'Chr4',
                'Chr5',
                'ChrC',
                'ChrM'
            ), 
        version varchar(10),
        type enum
            (
                'CDS',
                'chromosome',
                'exon',
                'five_prime_UTR',
                'gene',
                'mRNA',
                'mRNA_TE_gene',
                'miRNA',
                'ncRNA',
                'protein',
                'pseudogene',
                'pseudogenic_exon',
                'pseudogenic_transcript',
                'rRNA',
                'snRNA',
                'snoRNA',
                'tRNA',
                'three_prime_UTR',
                'transposable_element_gene'
            ), 
        strand enum
            (
                 '+',
                 '-'
            ), 
        phase tinyint, 
        atrributes text
    );`

它有大約 600,000 個值,我正在執行以下查詢:

select distinct
            anot_1.chromosome,
            anot_1.start,
            anot_1.end,
            anot_1.atrributes 
    from 
            anotation anot_1,
            anotation anot_2 
    where
            anot_1.type='CDS'
        and
            anot_2.type='protein'
        and 
            anot_1.chromosome!='ChrM'
        and
            anot_1.chromosome!='ChrC'
        and
            anot_1.chromosome=anot_2.chromosome
        and 
        (
            (
                anot_2.start=anot_1.start
            and
                anot_1.end!=anot_2.end
            and
                anot_2.strand='+'
            ) 
        or 
            (
                anot_2.start!=anot_1.start
            and
                anot_1.end=anot_2.end
            and
                anot_2.strand='-'
            )
        );

並且實際上需要很長時間才能完成,但是當我執行查詢時(相同的查詢,但我從 OR 中刪除了條件之一)它幾乎立即運行:

select distinct
            anot_1.chromosome,
            anot_1.start,
            anot_1.end,
            anot_1.atrributes
    from
            anotation anot_1, 
            anotation anot_2
    where
            anot_1.type='CDS'
        and 
            anot_2.type='protein'
        and 
            anot_1.chromosome!='ChrM'
        and
            anot_1.chromosome!='ChrC'
        and
            anot_1.chromosome=anot_2.chromosome
        and
            anot_2.start=anot_1.start
        and
            anot_1.end!=anot_2.end
        and 
            anot_2.strand='+';`

任何人都知道發生了什么,如果是這樣,我該如何解決? 謝謝!!!

這不是一個解決方案(我同意上面關於索引的評論),但我已經改變了你的 SQL 來使用一對左外連接,而不是你當前的 SQL,它在 JOIN 中有一個 OR。

雖然我不希望這在性能上有很大不同,但它可能會幫助您和其他人了解查詢正在做什么:-

SELECT distinct anot_1.chromosome, anot_1.start, anot_1.end, anot_1.atrributes 
FROM anotation anot_1,
LEFT OUTER JOIN anotation anot_2 ON anot_1.chromosome = anot_2.chromosome AND anot_1.start = anot_2.start AND anot_1.end != anot_2.end AND anot_2.strAND = '+' AND anot_2.type='protein'
LEFT OUTER JOIN anotation anot_3 ON anot_1.chromosome = anot_3.chromosome AND anot_1.end = anot_3.end AND anot_1.start != anot_3.start AND anot_3.strAND = '+' AND anot_3.type='protein'
WHERE anot_1.type = 'CDS'  
AND anot_1.chromosome != 'ChrM' 
AND anot_1.chromosome != 'ChrC' 
AND (anot_2.chromosome IS NOT NULL
OR anot_3.chromosome IS NOT NULL)

我會首先對您的查詢進行總體清理,將它們分開並進行聯合

select
            CDS.chromosome,
            CDS.start,
            CDS.end,
            CDS.atrributes 
    from
            (
            select
                        a.chromosome,
                        a.start,
                        a.end,
                        a.attribures,
                from
                        anotation a,
                where
                        a.type='CDS'
                    and
                        not a.chromosome IN ('ChrM', 'ChrC')
            ) CDS
        join
            (
            select
                        a.strand,
                from
                        anotation a,
                where
                        a.type='protien'
            ) Protien
                on 
                        CDS.chromosome = Protien.chromosome
                   and
                        CDS.start = Protien.start
                   and
                        CDS.end != Protien.end 
where
            Protien.strand = '+'
union
    select
            CDS.chromosome,
            CDS.start,
            CDS.end,
            CDS.atrributes 
    from
            (
            select
                        a.chromosome,
                        a.start,
                        a.end,
                        a.attribures,
                from
                        anotation a,
                where
                        a.type='CDS'
                    and
                        not a.chromosome IN ('ChrM', 'ChrC')
            ) CDS
        join
            (
            select
                        a.strand,
                from
                        anotation a,
                where
                        a.type='protien'
            ) Protien
                on 
                        CDS.chromosome = Protien.chromosome
                   and
                        CDS.start != Protien.start
                   and
                        CDS.end = Protien.end 
where
            Protien.strand = '-'

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM