SELECT DISTINCT sender_id, recipient_id
FROM messages
WHERE $current_user_id IN (sender_id, receiver_id)
AND sender_id <= receiver_id;
最后一个条件是必要的折(2,1)和(1,2)转换成单排。
如果,违背了你的榜样,也可以在你的数据(2,1)
没有(1,2)
也是在那里,它变得更加复杂。一个UNION
查询应该是完美的:
WITH cte AS (
SELECT sender_id, recipient_id
FROM messages
WHERE $current_user_id IN (sender_id, receiver_id)
)
SELECT sender_id, recipient_id FROM cte
WHERE sender_id <= receiver_id
UNION
SELECT recipient_id, sender_id FROM cte
WHERE sender_id > receiver_id;
的CTE应该更快通过保持它归结为一个单一的索引扫描,而不是两个。
UNION
从结果中删除重复项,使得DISTINCT
步不必要。
对于排序后的输出,您可能希望在末尾添加ORDER BY
子句。
您需要两列的索引才能获得最佳性能。虽然个别指标可以用良好的表现bitmax索引扫描相结合,在(sender_id, receiver_id)
一个multicolumn index仍然会更快:
CREATE INDEX foo_idx ON messages (sender_id, recipient_id);
与往常一样,权衡成本和效益的指标。如果查询是瓶颈,那么索引可能是个好主意。
哇...只是 –
完美。 http://sqlfiddle.com/#!15/5a39c/5/0 –
@Erwin我如何订购这些结果以获得最新的第一个?该表还有一个id列和一个created_at列,两者都可以用于排序...但是如何? –