mysql - 如何加速我的 "friends list"MySQL 查询?

标签 mysql

我正在尝试从我的数据库中获取好友列表,我的查询正在运行,但需要花费大量时间来加载结果(有时大约需要 10 秒)。

在这里:

SELECT F.status, U.username, U.email, UI.country, UI.birthday, P.thumb_url
FROM user U, relation F, user_info UI, photo P 
WHERE
CASE
WHEN F.leader = 'USER_ID'
THEN F.subscriber = U.id
WHEN F.subscriber= 'USER_ID'
THEN F.leader= U.id
END
AND
U.id = UI.user_id
AND
UI.main_photo = P.id
AND
F.status='1';

我的“关系”表如下:

CREATE TABLE IF NOT EXISTS `relation` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `leader` int(11) NOT NULL,
  `subscriber` int(11) NOT NULL,
  `time` timestamp NOT NULL DEFAULT,
  `status` int(11) NOT NULL DEFAULT '0',
  `seen` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;

所以我的问题是:您有什么好的建议可以改进我的查询吗?

谢谢!

最佳答案

根据经验,如果您在 SQL 中使用 CASE(或任何其他 if/then 逻辑),您可能做错了。 SQL 是一种声明性语言,这意味着您可以向它提问。如果你告诉它如何回答问题,它可能会以糟糕(或缓慢)的方式结束。关键是将约束用户 ID 放在 WHERE 子句中并将其保留在连接之外。这改变了它从告诉数据库如何完成它的工作,到询问数据库。数据库会处理剩下的事情。

使用 JOIN 语法可以更清楚什么是连接,什么是约束。 SQL joins当您想要将多个表中的行拼接在一起时,可以使用它。数据库知道如何优化它们。

第二位是use EXPLAIN告诉你 MySQL 是如何执行查询的,哪里比较慢。这通常表明您在哪里需要索引或需要重写查询的哪一部分。

我将假设 Relationship.leaderRelationship.subscriber 都是 User.id 上的外键并描述谁是关注该用户以及他们关注的人,并且您想显示与给定 USER_ID 相关的每个用户。应该不需要 CASE,您可以只检查其中一个是否匹配(检查我那个)。

SELECT F.status, U.username, U.email, UI.country, UI.birthday, P.thumb_url
FROM user U
JOIN user_info UI
  ON U.id = UI.user_id
JOIN photo P
  ON UI.main_photo = P.id
JOIN relation F
  ON F.leader = U.id OR F.subscriber = U.id
WHERE F.status='1'
  AND U.id = ?

更新:现在了解它应该是用户的 friend 列表,更改 U.id = ? 以检查该用户是否在关系中。

SELECT F.status, U.username, U.email, UI.country, UI.birthday, P.thumb_url
FROM user U
JOIN user_info UI
  ON U.id = UI.user_id
JOIN photo P
  ON UI.main_photo = P.id
JOIN relation F
  ON F.leader = U.id OR F.subscriber = U.id
WHERE F.status='1'
  AND F.leader = ? OR F.subscriber = ?

我们想要一个关系列表,但我们使用用户作为主表。这有点尴尬。 @fraxool's query which is FROM relation更有意义,但它可以使用一些关于什么约束去哪里的清理。 JOIN ON 关于网格化表。 WHERE 用于限制整体返回的内容。将这些原则应用于@fraxool 的新查询,我们得到...

SELECT username, email, ui.gender, ui.country, ui.birthday, p.thumb_url
FROM relation R
JOIN user U
  ON U.id = R.leader OR U.id = R.subscriber
JOIN user_info UI
  ON U.id = UI.user_id
JOIN photo P
  ON UI.main_photo = P.id
WHERE R.status = 1
  AND (R.leader = ? OR R.subscriber = ?)

U.id != ? 的附加约束是不必要的,除非你可以成为自己的 friend 。这应该在 relation.leader 和 relation.subscriber 的列约束中处理。

关于mysql - 如何加速我的 "friends list"MySQL 查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28531834/

相关文章:

PHP 类实例写入 MySQL 数据库

java dao :Getting data from database (mysql) by specific id

java - 使用 JavaMail 在超过截止日期时自动向用户发送电子邮件

mysql - 具有相同类型实体但不同数据库的多个数据源

mysql - 用户数据和更改日志的哪种布局最有效且存储消耗更少?

java - 使用 JOptionPane 更新 mysql

Mysql使用存储过程从当前数据库中选择所有现有表

python - 如何从 postgres/mysql 游标对象获取数据库名称

c# - 当 DB 消失时,MySqlConnection Connect() 方法抛出异常的速度非常慢 C#

mysql - 在带有 LEFT JOIN 的查询中使用 MySQL LIMIT