Mysql e、 您没有示例输入、输出和所需输出。“我只解析了一行”是什么意思?并给出一个完整的例子(代码和数据),展示您的问题。在给出您的规范时,还有哪些其他可声明的惟一列集&FKs列集和非空列?PS“reference”和“searched”列是什么意思?在表中添
Mysql e、 您没有示例输入、输出和所需输出。“我只解析了一行”是什么意思?并给出一个完整的例子(代码和数据),展示您的问题。在给出您的规范时,还有哪些其他可声明的惟一列集&FKs列集和非空列?PS“reference”和“searched”列是什么意思?在表中添,mysql,sql,indexing,explain,Mysql,Sql,Indexing,Explain,e、 您没有示例输入、输出和所需输出。“我只解析了一行”是什么意思?并给出一个完整的例子(代码和数据),展示您的问题。在给出您的规范时,还有哪些其他可声明的惟一列集&FKs列集和非空列?PS“reference”和“searched”列是什么意思?在表中添加了几十行之后,请再次尝试EXPLAIN。您可能会发现它不是以u的完整表扫描开始的。但是,中仍然隐含着一个tmp表。此外,还有一个完整的表扫描(确定,只有2行)来构建索引()。@RickJames我用6个用户和50条消息进行了测试,执行计划没有
e、 您没有示例输入、输出和所需输出。“我只解析了一行”是什么意思?并给出一个完整的例子(代码和数据),展示您的问题。在给出您的规范时,还有哪些其他可声明的惟一列集&FKs列集和非空列?PS“reference”和“searched”列是什么意思?在表中添加了几十行之后,请再次尝试
EXPLAIN
。您可能会发现它不是以u
的完整表扫描开始的。但是,
中仍然隐含着一个tmp表。此外,还有一个完整的表扫描(确定,只有2行)来构建索引(
)。@RickJames我用6个用户和50条消息进行了测试,执行计划没有改变。此查询类似于@BillKarwin one,但它只对u执行1次完整表扫描,并且只执行1次嵌套循环(JOIN
),而不是2和2。从MySQL 5.7开始,为派生表构建合并索引应该具有良好的性能。我的意思是,加入一个联盟应该比两个联盟更好。哇!该问题需要test_message
和test_user
中的所有列;此处的查询仅提供来自test\u user
的列。因此,我认为这不是一个有效的答案。问题是“在这种情况下,如何可能获得‘每个记录的范围检查’”,我的答案给出了问题的描述和避免问题的替代解决方案。如果你不喜欢,别担心。。我会活下来..“为每个记录检查的范围”太神秘了,我不知道它是什么意思。我不能检查,但我相信使用“联合所有”将有助于避免临时表(可能会导致重复,但我认为很少向自己发送消息)@skyboyer:MySQL 5.7.3及更高版本可以在使用UNION ALL
时消除临时表。请参阅第页的具体说明。MySQL的早期版本没有这种优化。
SELECT *
FROM message AS m
INNER JOIN user AS u
ON u.id = m.sender_id OR u.id = m.receiver_id
+----+-------------+-------+------+---------------+------+---------+------+-------+-----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+-------+-----------------------------------------------+
| 1 | SIMPLE | u | ALL | PRIMARY | null | null | null | 75000 | Range checked for each record (index map: 0x1)|
+----+-------------+-------+------+---------------+------+---------+------+-------+-----------------------------------------------+
SELECT *
FROM message AS m
INNER JOIN user AS u
ON u.id IN(m.sender_id, m.receiver_id)
SELECT *
FROM message AS m
INNER JOIN user AS u
ON u.id = m.sender_id
CREATE TABLE test_user (
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(30),
PRIMARY KEY (id)
);
CREATE TABLE test_message (
id INT NOT NULL AUTO_INCREMENT,
sender_id INT NOT NULL,
receiver_id INT NOT NULL,
PRIMARY KEY (id),
INDEX idx_sender (sender_id),
INDEX idx_receiver (receiver_id)
);
EXPLAIN SELECT *
FROM test_message AS m
INNER JOIN test_user AS u
ON u.id = m.sender_id OR u.id = m.receiver_id;
mysql> EXPLAIN
SELECT * FROM test_message AS m
INNER JOIN test_user AS u ON u.id = m.sender_id
UNION
SELECT * FROM test_message AS m
INNER JOIN test_user AS u ON u.id = m.receiver_id;
+----+--------------+------------+--------+---------------+---------+---------+--------------------+------+-----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------+------------+--------+---------------+---------+---------+--------------------+------+-----------------+
| 1 | PRIMARY | m | ALL | idx_sender | NULL | NULL | NULL | 1 | NULL |
| 1 | PRIMARY | u | eq_ref | PRIMARY | PRIMARY | 4 | test.m.sender_id | 1 | NULL |
| 2 | UNION | m | ALL | idx_receiver | NULL | NULL | NULL | 1 | NULL |
| 2 | UNION | u | eq_ref | PRIMARY | PRIMARY | 4 | test.m.receiver_id | 1 | NULL |
| NULL | UNION RESULT | <union1,2> | ALL | NULL | NULL | NULL | NULL | NULL | Using temporary |
+----+--------------+------------+--------+---------------+---------+---------+--------------------+------+-----------------+
EXPLAIN
SELECT *
FROM test_user AS u
INNER JOIN (
select id, sender_id as msg_id
from test_message
union all
select id, receiver_id
from test_message
) AS m
ON u.id = m.msg_id;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 PRIMARY u NULL ALL PRIMARY NULL NULL NULL 1 100.00 NULL
1 PRIMARY <derived2> NULL ref <auto_key0> <auto_key0> 4 test.u.id 2 100.00 NULL
2 DERIVED test_message NULL index NULL idx_sender 4 NULL 1 100.00 "Using index"
3 UNION test_message NULL index NULL idx_receiver 4 NULL 1 100.00 "Using index"