一个表格示例,数据和查询一起可以在http://sqlfiddle.com/#!9/2e65dd/3
中找到我有兴趣查找所有没有特定record_type的不同user_id。
在我的实际情况下,该表很大,其中有几百万条记录,并且在user_id列上有一个索引。尽管我计划通过一次将输出限制为1000来分批检索它。
select distinct user_id from
records o where
not exists (
select *
from records i
where i.user_id=o.user_id and i.record_type=3)
limit 0, 1000
是否有更好的方法来满足这一需求?
答案 0 :(得分:1)
我会这样:
SELECT u.user_id
FROM (SELECT DISTINCT user_id FROM records) AS u
LEFT OUTER JOIN records as r
ON u.user_id = r.user_id AND r.record_type = 3
WHERE r.user_id IS NULL
这可以避免您的NOT EXISTS解决方案中的相关子查询。
或者,您应该有另一个只列出用户的表,因此您不必执行子查询:
SELECT u.user_id
FROM users AS u
LEFT OUTER JOIN records as r
ON u.user_id = r.user_id AND r.record_type = 3
WHERE r.user_id IS NULL
无论哪种情况,都将有助于优化JOIN,以在该对列上添加复合索引:
ALTER TABLE records ADD KEY (user_id, record_type)
答案 1 :(得分:1)
我也建议加入,但是我的和Bill K会有所不同:
SELECT DISTINCT r.user_id
FROM records AS r
LEFT JOIN (SELECT DISTINCT user_id FROM records WHERE record_type = 3) AS rt3users
ON r.user_id = rt3users.user_id
WHERE rt3users.user_id IS NULL
;
但是,我不希望有一种替代方法,但是值得检查,因为性能会根据数据的大小和内容而有所不同...
SELECT DISTINCT r.user_id
FROM records AS r
WHERE r.user_id NOT IN (
SELECT DISTINCT user_id
FROM records
WHERE record_type = 3
)
;
请注意,这与您的原始查询更相似,但消除了原始子查询的相关性。
答案 2 :(得分:0)
您可以创建一个记录类型等于3的临时表,例如
Select distinct user_id
into #users
from records
where record_type=3
然后在此表上创建唯一索引(或主键)。然后,您将查询两个表中的索引。
我不能说您必须在数据上测试性能会更好。