通过 id 获取 MySQL 中最旧行的最有效方法

sca*_*ace 3 mysql

我有2张桌子:

conversation

CREATE TABLE `conversation` (
  `conversation_id` int(11) NOT NULL,
  `title` varchar(200) COLLATE utf16_czech_ci NOT NULL,
  `beginning_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `user_id` int(11) DEFAULT NULL
)
Run Code Online (Sandbox Code Playgroud)

message

CREATE TABLE `message` (
  `message_id` int(11) NOT NULL,
  `text` varchar(5000) COLLATE utf16_czech_ci NOT NULL,
  `add_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `is_seen` int(11) NOT NULL,
  `conversation_id` int(11) NOT NULL,
  `user_id` int(11) DEFAULT NULL
)
Run Code Online (Sandbox Code Playgroud)

当我创建一个新对话时,我还需要创建一个新消息(对话的开始消息)。稍后,此对话可能有数千条消息。但是在某些情况下我需要做的是,我需要conversation_id从数据库中与某个人进行对话,并获取此对话的最旧消息(对话的开始消息)。获取此消息的最有效方法是什么?

我做了这样的事情,但是当对话有 maaany 消息时,排序可能会减慢它的速度:

SELECT * FROM message WHERE conversation_id=some_id ORDER BY add_date ASC LIMIT 1

ype*_*eᵀᴹ 6

对于仅从表中获取一行的特定查询:

SELECT *
FROM message
WHERE conversation_id = @some_id
ORDER BY add_date ASC
LIMIT 1 ;
Run Code Online (Sandbox Code Playgroud)

你只需要一个公共(btree)索引(conversation_id, add_date)。查询只需要执行索引查找(将查找 PK 值),然后在表上查找。操作应该都非常快 ( O(logn)),因此表的大小无关紧要。

添加索引(或任何索引)后,您无需再执行任何操作。每当查询运行时,如果优化器决定索引有用(对于该查询,可以是上面的特定查询或任何其他查询),那么它将使用索引。


旁注:请PRIMARY KEY在表格中添加s。