2011-04-27 43 views
4

DataMapper的似乎是嚴重生成用於使用連接表關聯的次優的查詢。我能做些什麼來改善這些查詢的性能?請注意,它有一個隱含的連接表生成相同的查詢,以及(:through => Resource如何使用DataMapper更好地優化多對多關聯查詢?

這裏是我的設置:

class Left 
    include DataMapper::Resource 

    property :id, Serial 

    has n, :joins 
    has n, :rights, :through => :joins 
end 

class Join 
    include DataMapper::Resource 

    belongs_to :left, :key => true 
    belongs_to :right, :key => true 
end 

class Right 
    include DataMapper::Resource 

    property :id, Serial 

    property :one, String 
    property :two, Integer 
end 

現在,說我已經填充了一些數據,我想抓住有關的所有權利用左對象:

Left.first.rights 

DataMapper的執行以下查詢:

SELECT rights.id, rights.one, rights.two FROM rights INNER JOIN joins ON rights.id = joins.right_idINNER JOIN lefts ON joins.left_id = lefts.idWHERE joins.left_id = 1GROUP BY rights.id, rights.one, rights.twoORDER BY rights.id

  • DataMapper的正在生成完全不必要JOIN(第一粗體部分)。我不相信我的RDBMS(MySQL)會忽略這一點。它在解釋計劃中出現,至少是「Using index; Using temporary; Using filesort」。

  • 這是怎麼回事與GROUP BY?這裏看起來完全沒有必要 - 由於連接表上的組合鍵,我不能有重複。另外,不會GROUP BY rights.id有同樣的效果?甚至更好,SELECT DISTINCT

這些查詢都是極其緩慢(與兩側多個屬性表),我不知道如何正確索引表來支持它。

這是遠遠快從加盟模式查詢:Join.all(:left => Left.first).rights,儘管它正在執行兩種說法:

SELECT right_id FROM joins WHERE left_id = 1 
SELECT id, one, two FROM rights WHERE id = 1 ORDER BY id 

有趣的是,Left.first.joins.rights去同樣的路線,並執行上述兩個查詢。

+0

你的問題真的是「爲什麼?」,或者「我該如何避免這個」? – Phrogz 2011-04-27 19:36:34

+0

好點。 Fix't! – Nevir 2011-04-27 20:15:25

回答

3

如何去除加入類的定義,並規定如左圖:

class Left 
    include DataMapper::Resource 

    property :id, Serial 

    has n, :rights, :through => Resource 
end 

相信DM,爲你創造了良好的映射。