2013-03-28 214 views
0

我有兩個表tabAtabB,並且存在從tabAtabB的一對多關係。我有查詢:在一對多關係中使用LIMIT查詢

SELECT * FROM `tabA` LEFT JOIN `tabB` ON `tabA`.`aID` = `tabB`.`aID` 

和返回的行是一大組來自tabA多個複製爲每個tabB參照tabA

我知道我可以使用GROUP BYtabA行限制,以獨特的元素,除非我用用GROUP_CONCAT功能自定義字段(S),有兩個REPLACE功能相結合轉義(這嚴重影響性能),我鬆所有欄包含在tabB中的一行。示例查詢看起來像:

SELECT `tabA`.*, 
      GROUP_CONCAT(REPLACE(REPLACE(`tabB`.`tabBCol1`, '/', '//'), ',', '/,')) AS `tabBCol`, 
      GROUP_CONCAT(REPLACE(REPLACE(`tabB`.`tabBCol2`, '/', '//'), ',', '/,')) AS `tabBCo2` 
    FROM `tabA` 
LEFT JOIN `tabB` ON `tabA`.`aID` = `tabB`.`aID` 
GROUP BY `tabA`.`aID` 

該查詢將允許我使用LIMIT語法,所以我可以(例如)只顯示5項,5(即LIMIT 5,5)之後開始。當我將它應用於前一個查詢時,我不會得到接下來的5個查詢,而是基於關聯數量的一組隨機數據。

因此,除了第二個查詢,是沒有辦法,我可以取行,與有關聯,但允許使用LIMIT語法,並沒有過多的REPLACE功能的性能命中什麼辦法?

附加

雖然我可以使用多個子查詢的每一行,使用第一個查詢與GROUP BY語法(這將讓我申請協會的任何WHERE條件),我試圖找到一種方法以避免N + 1選擇問題(儘管在這個例子中,我的LIMIT語法是LIMIT 5,5,我將這個應用到更大的LIMIT s(一次最多可達1000行))。

+0

有兩件事情在我身上跳出來。一,你爲什麼要做一個左連接而不是內連接。二,而不是選擇*爲什麼不,選擇不同的只是你需要的領域? – 2013-03-28 01:25:53

回答

1

嘗試兩個查詢:

// get those 5 records 
SELECT * FROM Cars WHERE some_conditon = blabla LIMIT 5; 

// get all associated records from related table 
SELECT * FROM Wheels WHERE car_id IN (1, 3, 5, 123, 16); 

在結果不會有任意N型問題,因爲你永遠有兩個查詢。即使你在第一次查詢中有1000條記錄,使用這種簡單的方法總比使用/ concats/etc加入/分組總是更好。

+0

隨着'IN'條件,當它達到1000的大小時,這會如何影響性能? – topherg 2013-03-28 01:22:26

+0

也可能是您當前的ORM始終允許您以這種方式工作。如果沒有 - 您可以將其擴展到這個方向。 – gaRex 2013-03-28 01:22:57

+0

這是一個自定義的ORM,我把它作爲一個學術練習來構建。我相信真正理解一個系統的唯一方法就是能夠從頭開始構建一個包含所有所需功能的系統 – topherg 2013-03-28 01:24:30