【发布时间】:2010-11-08 17:38:02
【问题描述】:
考虑以下数据库表:
- 包含 13,000,000 行(每条消息一行)的“消息”表。
- 包含 3,000,000 行(每个用户一行)的“用户”表。
以下查询用于获取一堆消息和对应的用户:
SELECT messages.id, messages.message, users.id, users.username
FROM messages
INNER JOIN users ON messages.user_id=users.id
WHERE messages.id in (?, ?, ?, ? ... a total of 100 "?":s);
在每个查询中获取 100 条消息。
“消息”在 id(主键,BIGINT 不是自动生成)和 user_id 上编入索引。
"users" 以 id 为索引(主键,INT 自动生成)。
数据库是使用 MyISAM 的 MySQL。
目前,查询的执行时间远远超过 3000 毫秒,这让我感到困惑,因为“消息”是在“id”上索引的,因此检索正确的行应该非常快。
我的问题是:考虑到描述场景和设置,3000 毫秒的查询时间是“正常的”还是我遗漏了什么?如果需要更多详细信息,请告诉我。
更新 #1: 以下是表定义:
CREATE TABLE messages (
id bigint(20) NOT NULL DEFAULT '0',
user_id int(11) NOT NULL DEFAULT '0',
message varchar(160) NOT NULL DEFAULT '',
PRIMARY KEY (id),
KEY user_id (user_id),
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE users (
id int(11) NOT NULL DEFAULT '0',
username varchar(32) NOT NULL DEFAULT '',
PRIMARY KEY (id),
UNIQUE KEY username (username),
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
我在定义中观察到的唯一“非标准”内容是“messages.id”是 BIGINT 而不是 INT。这可能是一个提示吗?
【问题讨论】:
-
你能发布 EXPLAIN SELECT 的输出吗...
-
您是否尝试过将 100 个 MessageIds 放入临时表中,然后加入该表或 Exists?
-
3000ms 看起来很糟糕。在索引中查找 100 条消息中的每条消息应该非常快,然后只需检索这 100 条记录,在索引中查找他们的用户,然后检索这 100 条记录。
-
你能解释一下查询吗?
-
当你减少 IN() 中的 id 数量时,所花费的时间是否会按比例减少?
标签: optimization mysql indexing query-optimization