mysql - 优化两个表的 SQL 查询
问题描述
我对有很多行的表有一个 SQL 查询。所以这个查询运行了很长时间。如何优化此查询?这些表已经在 id 和friend_id 上有索引
SELECT u.id, u.first, u.last,
group_concat(u2.first, " " , u2.last) MyFriends
FROM Users u
INNER JOIN Friends f ON f.user_id = u.id
INNER JOIN Users u2 ON u2.id = f.friend_id
GROUP BY u.id;
这些是表结构:
CREATE TABLE Users (
id int(10) unsigned NOT NULL,
first varchar(50) DEFAULT NULL,
last varchar(50) DEFAULT NULL,
city varchar(20) DEFAULT NULL,
country varchar(20) DEFAULT NULL,
Age tinyint(3) unsigned NOT NULL,
KEY users_idx_id (id))
ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE Friends (
user_id int(10) unsigned NOT NULL,
friend_id int(10) unsigned NOT NULL,
KEY idx_friends (friend_id))
ENGINE=InnoDB DEFAULT CHARSET=latin1;
解决方案
多对多映射表 ( Friends
) 需要改进索引。删除您现在拥有的所有索引并添加
PRIMARY KEY(user_id, friend_id),
INDEX(friend_id, user_id)
更多讨论:http: //mysql.rjweb.org/doc.php/index_cookbook_mysql#many_to_many_mapping_table
Age
是一个移动的目标。想一个更好的方法来存储它。
大约有 6 个国家的名字超过 20 个。“圣文森特和格林纳丁斯”是 32 个。
至于城市,“Poselok Uchebnogo Khozyaystva Srednego Professionalno-Tekhnicheskoye Uchilishche Nomer Odin”是 91 个字符。
ALTER TABLE Friends
DROP INDEX idx_friends,
ADD PRIMARY KEY(user_id, friend_id),
ADD INDEX(friend_id, user_id);
每个表都应该有一个PRIMARY KEY
:
ALTER TABLE Users
DROP INDEX users_idx_id,
ADD PRIMARY KEY(user_id)
阅读有关AUTO_INCREMENT
.
“执行计划”可以通过运行来获得EXPLAIN SELECT ...
。但是在这种情况下它不会提供很多线索。
推荐阅读
- python - Python按日期在excel中查找数据
- excel - 我想创建一个数据透视表,但想忽略包含特定单词的单元格
- raspberry-pi - 通过串行通信将数据从 arduino 传输到树莓派(并存储在变量中)
- vba - 按主题自动将收到的电子邮件移动到共享邮箱中的子文件夹
- excel - 将名字和姓氏组合成全名 (VBA)
- html - 将一个 div 一个接一个地放置
- wpf - 数据触发器不会触发背景变化
- reactjs - 在 reactjs 应用程序中嵌入动态 HTML 页面
- flutter - 在 in_app_purchase 插件中为 Flutter 调用 buyNonConsumable 方法,其中 sandbox = true 并在调用 queryPastPurchases 时获取 sandbox = false
- javascript - elementHandle.$x(expression) 似乎没有相对于给定的 elementHandle 运行