2012-07-13 46 views
0

我在一個mysql table1中保存一組節點,在另一個mysql1中保存一組邊(table2)。節點配備了主鍵和邊緣使用「外鍵」mysql加入性能如果有多個OR條件

**table1** 
id label 
1 node1 
2 node2 
3 node3 

**table2** 
FK_first FK_sec rel 
1  3  guardian 
2  1  guardian 
1  3  times 

我知道數據庫的設計並不完美,但它的簡單... 現在我想「版本」的數量爲每個節點和做一個查詢如:

SELECT 
    label, 
    COUNT(rel) as freq 
FROM 
    `table1` 
    LEFT JOIN table2 ON (id=FK_first OR id=FK_second) 
GROUP BY label 
ORDER BY freq DESC 

我有大約1000個節點和2000邊緣。帶有ON的查詢(id = FK_first 或id = FK_second ),則查詢速度更快(< 1秒)。另一個查詢需要大約6秒,這是慢的。 我將不勝感激一些評論加快這一點:-)

  1. LEFT JOIN表2 ON(ID = FK_first或ID = FK_second)〜6秒
  2. LEFT JOIN表2 ON(ID = FK_first)〜 0.16秒
  3. LEFT JOIN表2 ON(ID = FK_second)〜0.16秒

  4. LEFT JOIN表2的ID IN(FK_first,FK_second)〜6秒

 

EXPLAIN 1: 
     id select_type table type possible_keys     key key_len ref rows Extra 
     1 SIMPLE   table1 ALL NULL       NULL NULL NULL 2571 Using temporary; Using filesort 
     1 SIMPLE   table2 ALL FK_first,FK_second,FK_first_2 NULL NULL NULL 3858  

EXPLAIN 2: 
id select_type table type possible_keys  key key_len ref  rows Extra 
1 SIMPLE  table1 index NULL    PRIMARY 2 NULL  2571 Using index; Using temporary; Using filesort 
1 SIMPLE  table2 ref FK_first,FK_first_2 FK_first_2 4 table1.id 1 
+0

您是否有'FK_second'上的索引? – 2012-07-13 14:16:11

+0

@Michael:考慮到最後一段很不明確,我們應該詢問他是否有沒有or的查詢中使用的密鑰索引。 – Razvan 2012-07-13 14:18:27

+0

我和你在一起,直到真正的問題...你可以顯示2個查詢?描述你的索引? – Randy 2012-07-13 14:20:39

回答

3

儘量做兩件連接和移動「或」入COUNT()函數:在FK2上FK1一次

的每一行,該聯接表2,然後再(如果它尚未加入到通過FK1行。然後在COUNT中,我們指定只有連接的rel列爲非null的行。

SELECT 
    label, 
    COUNT(table2A.rel || table2B.rel) as freq 
FROM 
    `table1` 
    LEFT JOIN 
    table2 as table2A 
    ON id=table2A.FK_first 
    LEFT JOIN 
    table2 as table2B 
    ON id=table2B.FK_second 
    AND table2A.FKFirst != table2B.FKFirst 
GROUP BY label 
ORDER BY freq DESC 
+0

這加速了~2秒,但它非常複雜,而不是在我看來足夠快... – user1523756 2012-07-13 15:11:05

+0

看看這個解決方案的解釋。我認爲這是正確的做法。其餘的緩慢可能是由於GROUP/ORDER所需的文件夾。所以(1)嘗試索引'標籤',因爲你正在對它進行分組。 (2)嘗試增加@@ max_heap_table_size和@@ tmp_table_size,特別是在執行期間看到線程狀態爲「將HEAP轉換爲MyISAM」或「將數據複製到磁盤上的tmp表」時。 (不過,我認爲你的結果集可能足以觸發這個問題。) – 2012-07-13 16:24:53

+0

是的,你是對的!在我使用id並且沒有標籤來分組之後,它非常快速。謝謝大家幫忙找到解決方案! – user1523756 2012-07-13 16:38:45