2014-02-17 86 views
1

所以我一直在尋找一個解決方案和閱讀書籍,並沒有能夠弄清楚,問題很簡單,我有2個表格。在一張桌子上,我有兩個字段:優化特定查詢mysql

table_1:「染色體」和「位置」都是整數。

table_2:「染色體」「開始」和「結束」,都是整數。

我想要一個查詢,該查詢將table_1中位於table_2開始和結束之間的所有行都返回給我。查詢看起來是這樣的:

SELECT 
    table_1 . * 
FROM 
    table_1, 
    table_2 
WHERE 
    table_1.chromosome = table_2.chromosome 
     AND table_1.position > table_2.start 
     AND table_1.position < table_1.end; 

所以此查詢工作正常,但我的表都是幾百萬行(7092713)和(215909)respectvely的。我索引染色體,pos和染色體,開始,結束。奇怪的部分是,如果我逐個執行查詢(perl DBI,爲table_2的每行執行一條語句),則運行速度會快得多。不知道我在哪裏搞砸了。 任何幫助,將不勝感激。

豪爾赫景山

回答

1

爲了清楚起見,我們使用標準的JOIN語法重鑄查詢開始。該查詢是相當的,但更易於閱讀。

SELECT table_1 . * 
    FROM table_1 
    JOIN table_2 ON ( table_1.chromosome = table_2.chromosome 
        AND table_1.position > table_2.start 
        AND table_1.position < table_1.end) 

其次,搜索龐大的表(或與此有關的任何表),以避免在您SELECT條款*時很聰明。使用*會拒絕向優化器提供有用的數據,說明在結果集中您需要做什麼或不需要做什麼。因此,讓我們說

SELECT table_1.chromosome, table_1.position 

for SELECT。

因此,很明顯,您的結果集和您的連接需要染色體和位置,而不是您的大表中的其他位置。嘗試在該表上創建一個複合BTREE索引,如下所示。

CREATE INDEX ON table_1(chromosome,position) USING BTREE 

同樣,嘗試在table_2上創建一個索引,如下所示。

CREATE INDEX ON table_2(chromosome,start, end) USING BTREE 

這些被稱爲覆蓋索引。它們包含足夠多的列,可以從索引滿足查詢,而無需反彈回原始表。

BTREE索引(默認情況下)固有地排序。 table_1中的適當記錄可以通過從(染色體,開始)開始並以(染色體,結束)開始的索引通過範圍掃描找到。第三,在結果集中可能會出現從table_1開始的大量組合爆炸行爲。對於與ON()子句相匹配的兩個表中的每行行,您將得到一行。如果不瞭解您的數據,很難知道情況是否如此。

你可以嘗試降低使用

SELECT DISTINCT table_1.chromosome, table_1.position 

讓這個嘗試是組合爆炸。如果你還沒有找到任何地方,也許完整的表格定義和EXPLAIN的結果會有所幫助。

+0

嗨,首先,感謝您的回覆!我已經通過位置和染色體以及染色體開始結束(開始總是低於結束,並且這是我的理解,如果我以這種方式編制索引,我可以單獨使用任何最左側的索引),我只用了*對於這個例子,但實際上正如你所說我只需要pos和染色體,所以我已經在使用你的消化:) –

+0

我添加了一些關於'SELECT DISTINCT'的內容。 –

+0

嘿,好的,所以我嘗試了,仍然需要永遠運行,我的數據是唯一的,沒有2個單打相同的位置,並且數據不重疊,另一個奇怪的是,如果我從表中進行1個查詢2,它的速度非常快,我的意思是,我可以保持這種方式,直接用mysql(但是thnx! –

0

有趣的問題。在不瞭解更多關於「職位」中包含的數量的情況下,我仍然通常採用這種方式來處理它:

通常從table_1(具有7.0mm實體)選擇位置,以便生成的表格是較小數量的箱數據的。比方說,「位置」數量是從2-9開始的一組離散整數。從table_1中選擇位置等於2的位置,然後從table_2中選擇其中「start」小於2且「end」大於2.迭代此查詢選擇8次,結果更新新的table_3。

我在這裏假設table_2在染色體上是唯一的,table_1不是。因此,最終的染色體可能在同一範圍內有多個位置(染色體有一個範圍,但可以出現在該範圍內的任何地方)。那麼你也不能分辨出結果表有多大,但它可能相當大,因爲table_1中的每個7mm實體都可能在table_2中的所有範圍內。

迭代將允許您「增長」您的結果,同時在提交到整個循環之前通過實驗確定每個點的質量。

下面是該查詢我心目中的想法(未經測試):

SELECT table_1.chromosome, table_1.position, table_2.start, table_2.end 
FROM 
(SELECT table_1.chromosome, table_1.position 
    from table_1 where table_1.position = 2) 
JOIN 
(SELECT table_2.chromosome, table_2.start, table_2.end 
    from table_2 where table_2.start < 2 AND table_2.end > 2) 
ON 
table_1.chromosome = table_2.chromosome 

祝你好運,我希望你能找到你的答案!