2013-03-28 212 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