我试图限制从JOIN语句中检索的行数。
考虑这些表:
CREATE TABLE `user` (
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255),
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
CREATE TABLE `conversation` (
`id` INT NOT NULL AUTO_INCREMENT,
`date` DATETIME NOT NULL,
`creator_id` INT,
PRIMARY KEY (`id`),
FOREIGN KEY (`creator_id`) REFERENCES `user` (`id`)
) ENGINE=InnoDB;
CREATE TABLE `message` (
`id` INT NOT NULL AUTO_INCREMENT,
`body` VARCHAR(4096) NOT NULL,
`date` DATETIME NOT NULL,
`sender_id` INT,
`receiver_id` INT,
`conversation_id` INT,
PRIMARY KEY (`id`),
FOREIGN KEY (`sender_id`) REFERENCES `user` (`id`),
FOREIGN KEY (`receiver_id`) REFERENCES `user` (`id`),
FOREIGN KEY (`conversation_id`) REFERENCES `conversation` (`id`)
) ENGINE=InnoDB;
我想从涉及特定用户的20个最后一次对话中获取N个最后消息(假设ID为42的那个)
所以我的第一个想法就是这样做:
SELECT * FROM `conversation` `c`
LEFT JOIN `user` `u` ON `u`.`id` = `c`.`creator_id`
LEFT JOIN (
SELECT * FROM `message`
LIMIT @N
ORDER BY `date` DESC
) `m` ON `m`.`conversation_id` = `c`.`id`
WHERE `c`.`creator_id` = 42
LIMIT 20;
由于MySQL可能会为每个会话创建一个临时表m
,我只是想知道这是多么有效,或者是否有更好的方法来实现相同的结果。知道表消息和对话可能包含大量行,我只是不想限制客户端消息行的数量。
答案 0 :(得分:0)
@N
无法在LIMIT
中使用。 (使用常数。)ORDER BY
必须在LIMIT
之前。LEFT
。优化器更喜欢从子查询开始。message
需要INDEX(date)
;没有它,它必须进行慢速扫描。请解释您希望查询执行的操作;我还没弄清楚。