[英]How can I speed up this query that joins a table on itself?
我们有一个“用户”表,用于保存有关我们用户的信息。 此表中的字段之一称为“查询”。 我正在尝试选择具有相同查询的所有用户的用户 ID。 所以我的输出应该是这样的:
user1_id user2_id common_query
43 2 "foo"
117 433 "bar"
1 119 "baz"
1 52 "qux"
不幸的是,我无法在一小时内完成此查询(用户表非常大)。 这是我当前的查询:
SELECT u1.id,
u2.id,
u1.query
FROM users u1
INNER JOIN users u2
ON u1.query = u2.query
AND u1.id <> u2.id
我的解释:
+----+-------------+-------+-------+----------------------+----------------------+---------+---------------------------------+----------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+----------------------+----------------------+---------+---------------------------------+----------+--------------------------+
| 1 | SIMPLE | u1 | index | index_users_on_query | index_users_on_query | 768 | NULL | 10905267 | Using index |
| 1 | SIMPLE | u2 | ref | index_users_on_query | index_users_on_query | 768 | u1.query | 11 | Using where; Using index |
+----+-------------+-------+-------+----------------------+----------------------+---------+---------------------------------+----------+--------------------------+
正如您从解释中看到的,users 表在查询时建立了索引,并且该索引似乎正在我的 SELECT 中使用。 我想知道为什么表 u2 上的 'rows' 列的值为 11,而不是 1。有什么我可以做的来加速这个查询吗? 我的“<>”比较是否在 join 不好的做法中? 此外,id 字段是主键
查询的主要驱动因素是query
字段的相等性——如果它被索引。 id
的 <> 可能不是很具体,它通过用于它的选择类型显示为 'ref'
以下仅适用于“查询”未编入索引的情况....
如果id
是主键,你可以这样做:
CREATE INDEX index_1 ON users (query);
添加此类索引的结果将是查询的覆盖索引,并将导致查询的最快执行。
我最关心的是key_len
,它表明 MySQL 必须比较最多 768 个字节才能查找每个索引条目。
对于此查询,对哈希索引query
可能会更加高性能的(因为它会涉及短得多的比较,在计算哈希值,并使用该指数是无法排序记录的费用):
ALTER TABLE users ADD INDEX (query) USING HASH
您还可以考虑将其作为(query, id)
的组合(query, id)
以便 MySQL 无需扫描到记录本身来测试<>
标准。
你有多少查询? 您可以添加表 UsersInQueries:
id queryId userId
0 5 453
1 23 732
2 15 761
然后从此表中选择并按 queryId 分组
如果每个查询最多只有两个用户,则可以改为执行以下操作:
select query, min(id) as FirstID, max(id) as SecondId
from users
group by query
having count(*) > 1
如果你有两个以上的用户使用相同的查询,你能解释为什么你想要所有这样的用户对吗?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.