这是我在这里发表的第一篇文章,如果我打破协议,请道歉。
我有一个单独的表,为了参数我将调用t1,表格如下:
id -- primary key
fk_id -- foreign key
date_created
我有一组来自先前查询的fk_id。
这是一个完全返回我想要的查询,但使用UNION,对于我可能需要搜索的数百甚至数千个fk_id来说效率非常低:
SELECT *
FROM t1
WHERE fk_id = ?
ORDER BY date_created DESC
LIMIT m, n
UNION
SELECT *
FROM t1
WHERE fk_id = ?
ORDER BY date_created DESC
LIMIT m, n
UNION -- ... for each fk_id
请注意,每个UNION的偏移量和限制值m和n都相同。
我想要的是一个不使用UNION的查询,而是说
之类的内容WHERE fk_id IN (?, ?, ?, ...)
但保留LIMIT对每个子集的单独应用。
答案 0 :(得分:0)
您需要为每个fk分配一个行号。最好的方法可能是使用变量:
SELECT t.*
FROM (SELECT t1.*,
(@rn := if(@f = fk_id, @rn + 1,
if(@f := fk_id, 1, 1)
)
) rn
FROM t1 CROSS JOIN
(SELECT @f := -1, @rn := 0) vars
ORDER BY fk_id, date_created DESC
) t
WHERE rn >= m and rn < m + n;
编辑:
如果只有MySQL支持以下(几乎)ANSI语法,那么这可能会更有效:
select t1.*
from t1
where t1.id in (select id
from t1 tt1
where tt1.fk_id = t1.fk_id
order by date_created desc
limit m, n
);
我不是百分百肯定,但这应该利用t1(fk_id, date_created)
和t1(id)
上的索引。如果它使用这些索引,那么它应该可以很好地工作。