explain SELECT u.id FROM user AS u, user_friend AS uf WHERE
(uf.user_id = 1 AND uf.friend_id = u.id) OR
(uf.friend_id = 1 AND uf.user_id = u.id) ;改成select xx union select xx就快很多
(uf.user_id = 1 AND uf.friend_id = u.id) OR
(uf.friend_id = 1 AND uf.user_id = u.id) ;改成select xx union select xx就快很多
解决方案 »
- 求助mysql安装问题
- Toad For Mysql 创建存储过程
- centos 编译mysql,我不知道下载哪个mysql
- 用存储过程怎么从表中删除主键在别一结果表中的数据?
- mysql数据库字符问题
- 难题求解:往100万条数据中插入1万条,有什么好的办法提高效率?
- SQLServer2000中如何通过opendatasource连接到mysql数据库
- [mysqld-5.0.1-alpha-nt]string data,right truncated报错是什么原因引起来的?
- MySQL分页查询调用存储结构的问题
- 大神们在线等答案
- mysql查询性能的问题,比较奇怪
- MySQL还原问题…… (新手问题)
(uf.user_id = 1 AND uf.friend_id = u.id) OR
(uf.friend_id = 1 AND uf.user_id = u.id) ;
其中user_id和friend_id都是外键关联到u表的id上,u表的id是主键把or换成union,先select再union,似乎结果集的笛卡尔积变小了疑问是为什么,第一种方法select u表的类型是all
(uf.user_id = 1 AND uf.friend_id = u.id)
不带or的看看走得什么explain
| 1 | SIMPLE | uf | ref | PRIMARY,user_friend_friend_ref | PRIMARY | 4 | const | 9 | Using where |
| 1 | SIMPLE | u | eq_ref | PRIMARY | PRIMARY | 4 | uf.friend_id | 1 | |带or的
| 1 | SIMPLE | uf | index_merge | PRIMARY,user_friend_friend_ref | PRIMARY,user_friend_friend_ref | 4,4 | NULL | 12 | Using union(PRIMARY,user_friend_friend_ref); Using where |
| 1 | SIMPLE | u | ALL | PRIMARY | NULL | NULL | NULL | 309 | Range checked for each record (index map: 0x1) |
user_friend.user_id是主键??!!SELECT u.id
FROM user u
INNER JOIN user_friend uf
ON u.id = uf.user_id
WHERE uf.user_id = 1
OR uf.friend_id = 1;
如果没有其他条件同样用or,貌似这个快点。下面是测试用例:
DROP TABLE IF EXISTS user;
CREATE TABLE user (
id INT NOT NULL auto_increment,
name VARCHAR(36) NOT NULL,
primary key(id)
) ENGINE=InnoDB;INSERT INTO user (name) VALUES (uuid());
INSERT INTO user (name) SELECT uuid() FROM user;
INSERT INTO user (name) SELECT uuid() FROM user;
INSERT INTO user (name) SELECT uuid() FROM user;
INSERT INTO user (name) SELECT uuid() FROM user;
INSERT INTO user (name) SELECT uuid() FROM user;
INSERT INTO user (name) SELECT uuid() FROM user;
INSERT INTO user (name) SELECT uuid() FROM user;
INSERT INTO user (name) SELECT uuid() FROM user;
INSERT INTO user (name) SELECT uuid() FROM user;
INSERT INTO user (name) SELECT uuid() FROM user;
INSERT INTO user (name) SELECT uuid() FROM user;
INSERT INTO user (name) SELECT uuid() FROM user;
INSERT INTO user (name) SELECT uuid() FROM user;DROP TABLE IF EXISTS user_friend;
CREATE TABLE user_friend (
id INT NOT NULL auto_increment,
user_id INT NOT NULL,
friend_id INT NOT NULL,
primary key(id),
index idx_user(user_id),
index idx_friend(friend_id)
) ENGINE=InnoDB;INSERT INTO user_friend (user_id, friend_id) SELECT id, id + 1 FROM user;
INSERT INTO user_friend (user_id, friend_id) SELECT id, id + 2 FROM user;
INSERT INTO user_friend (user_id, friend_id) SELECT id, id + 3 FROM user;
INSERT INTO user_friend (user_id, friend_id) SELECT id, id + 4 FROM user;
INSERT INTO user_friend (user_id, friend_id) SELECT id, id + 5 FROM user;
INSERT INTO user_friend (user_id, friend_id) SELECT id, id + 11 FROM user;
INSERT INTO user_friend (user_id, friend_id) SELECT id, id + 12 FROM user;
INSERT INTO user_friend (user_id, friend_id) SELECT id, id + 13 FROM user;
INSERT INTO user_friend (user_id, friend_id) SELECT id, id + 14 FROM user;
INSERT INTO user_friend (user_id, friend_id) SELECT id, id + 15 FROM user;
INSERT INTO user_friend (user_id, friend_id) SELECT id, id + 21 FROM user;
INSERT INTO user_friend (user_id, friend_id) SELECT id, id + 22 FROM user;
INSERT INTO user_friend (user_id, friend_id) SELECT id, id + 23 FROM user;
INSERT INTO user_friend (user_id, friend_id) SELECT id, id + 24 FROM user;
INSERT INTO user_friend (user_id, friend_id) SELECT id, id + 25 FROM user;EXPLAIN
SELECT u.id
FROM user u
INNER JOIN user_friend uf
ON u.id = uf.user_id
WHERE uf.user_id = 1
OR uf.friend_id = 1;+----+-------------+-------+-------------+---------------------+---------------------+---------+-----------------+------+-----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------------+---------------------+---------------------+---------+-----------------+------+-----------------------------------------------+
| 1 | SIMPLE | uf | index_merge | idx_user,idx_friend | idx_user,idx_friend | 4,4 | NULL | 16 | Using union(idx_user,idx_friend); Using where |
| 1 | SIMPLE | u | eq_ref | PRIMARY | PRIMARY | 4 | test.uf.user_id | 1 | Using index |
+----+-------------+-------+-------------+---------------------+---------------------+---------+-----------------+------+-----------------------------------------------+
uf里的主键是 (uf.user_id,uf.friend)