我们有一个存在以下问题的Django项目:
User
对象存储在auth_user
表中
这些对象与Profile
对象具有一对一关系,该对象存储在yuza_profile
表中。它与user
的关系是通过user_id
字段
但是,几年前,数千个Profile
对象被删除而没有删除链接的User
对象。
这些没有个人资料的用户正在我们的系统中引起问题,我们希望将其删除。
我创建了以下SQL查询来执行此任务
DELETE FROM auth_user WHERE id NOT IN (SELECT user_id FROM yuza_profile);
自Profile
对象被删除以来,我无法扫描null
字段上的*_id
值-这是我在这里的第一步。
相反,我正在遍历两个表,两个表都包含60.000行以上,这导致查询速度缓慢且效率低下,超过60亿次操作(和服务器超时)
是否可以加快此查询的速度?我知道我的查询效率很低,但是我不知道有什么方法可以改善它,任何帮助将不胜感激。
编辑:根据要求,我添加了以下架构:
user_profile
id - integer
user_id - integer
gender - varchar(2)
birth_date - date
address - varchar(255)
city - varchar(255)
phone_number - varchar(10)
avatar - varchar(255)
---------------------
user_profile_pkey - (id)
user_profile_user_id_key - (user_id)
user_profile_user_id_fkey - (user_id) -> auth_user(id)
user_profile_pkey - (id) UNIQUE
user_profile_user_id_key - (user_id) UNIQUE
auth_user
id - integer
username - varchar(150)
first_name - varchar(30)
last_name - varchar(30)
email - varchar(75)
password - varchar(128)
is_staff - boolean
is_active - boolean
is_superuser - boolean
last_login - timestamp with time zone
date_joined - timestamp with time zone
---------------
auth_user_pkey - (id)
auth_user_username_key - (username)
auth_user_pkey - (id) UNIQUE
auth_user_username_key - (username) UNIQUE
我应该注意,我开始怀疑我使用的IDE(PycharmPro)是否可能是一个因素-使用SELECT
语句测试查询时,IDE会将查询结果显示为每页500个结果的页面。最初的查询确实花费了不到一秒钟的时间-但是按下“转到最后一页”按钮花费了2分钟以上的时间(仅显示16000个结果)
答案 0 :(得分:1)
我不太确定您的方法,我假设您采取了基于游标的策略,但您不能只是:
DELETE FROM auth_user WHERE id NOT IN (SELECT user_id FROM yuza_profile);
如果索引正确,则该DML指令将不需要那么多操作。
答案 1 :(得分:1)
我强烈建议您使用NOT EXISTS
而不是NOT IN
。它更直观地处理NULL
值。 (如果子查询中的任何值为NOT IN
,{NULL
将过滤出所有行。)
因此,将查询写为:
DELETE au FROM auth_user au
WHERE NOT EXISTS (SELECT 1
FROM yuza_profile vp
WHERE vp.user_id = au.id
);
此查询可以利用yuza_profile(user_id)
上的索引:
CREATE INDEX idx_yuza_profile_user_id ON yuza_profile(user_id);