Mysql不存在或不存在替代方案

Mysql不存在或不存在替代方案,mysql,sql,Mysql,Sql,表、数据和查询的示例可以在中找到 我感兴趣的是找到所有没有特定记录类型的不同用户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_

表、数据和查询的示例可以在中找到

我感兴趣的是找到所有没有特定记录类型的不同用户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

有没有更好的方法来满足这一需求?

我会这样做:

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
这样可以避免不存在解决方案中的相关子查询

或者,您应该有另一个只列出用户的表,这样您就不必执行子查询:

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
无论哪种情况,在一对列上添加复合索引都有助于优化联接:

ALTER TABLE records ADD KEY (user_id, record_type)

您可以创建一个记录类型等于3的临时表,如

Select distinct user_id
into #users
from records
where record_type=3 
然后在此表上创建唯一索引(或主键)。然后您将在两个表中搜索索引


我不能说性能会更好,你必须在你的数据上测试它。

我也建议加入,但我的会与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
)
;

请注意,这一项与原始子查询更为相似,但去掉了原始子查询的相关性质。

当我进行测试时,添加索引是唯一重要的事情。否则,查询的所有变体都以相同的速度运行。