我们有一个“用户”表,其中包含有关我们用户的信息。此表中的一个字段称为“查询”。我试图选择具有相同查询的所有用户的用户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.有什么办法可以加快查询速度吗?是我的'&lt;&gt;'加入不良做法比较?此外,id字段是主键
答案 0 :(得分:1)
查询的主要驱动因素是query
字段上的相等性 - 如果它已编入索引。 &lt;&gt; id
的{{1}}可能不是非常具体,它显示的选择类型是'ref'
以下仅适用于'query'未编入索引....
如果id
是主键,您可以这样做:
CREATE INDEX index_1 ON users (query);
添加此类索引的结果将是查询的覆盖索引,并将导致查询执行速度最快。
答案 1 :(得分:1)
我最关心的是key_len
,它表明MySQL必须比较多达768个字节才能查找每个索引条目。
对于此查询,query
上的哈希索引可能更具性能(因为它将涉及大大缩短的比较,代价是计算哈希并且无法使用该索引对记录进行排序):
ALTER TABLE users ADD INDEX (query) USING HASH
您也可以考虑在(query, id)
上将其设为复合,以便MySQL无需扫描到记录本身来测试<>
标准。
答案 2 :(得分:0)
您有多少查询?您可以添加表UsersInQueries:
id queryId userId
0 5 453
1 23 732
2 15 761
然后从此表中选择并按queryId
分组答案 3 :(得分:0)
如果每个查询最多只有两个用户,则可以改为:
select query, min(id) as FirstID, max(id) as SecondId
from users
group by query
having count(*) > 1
如果您有两个以上具有相同查询的用户,您能否解释为什么您需要所有这类用户?