2015-06-19 194 views
0

我試圖限制從JOIN語句中檢索到的行數。Mysql加入select語句

考慮這些表:

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,我只是想知道如何高效THI s是還是有更好的方法來達到同樣的結果。知道表消息和對話可能包含大量的行,我只是不想限制客戶端的消息行數。

回答

0
  • @N不能在LIMIT中使用。 (使用常數。)
  • ORDER BY必須先於LIMIT
  • 除非您確實需要,否則請勿使用LEFT。優化器寧願從子查詢開始。
  • message需要INDEX(date);沒有它,它必須做一個緩慢的表掃描。

請解釋你想查詢的內容;我還沒有弄明白。