我需要优化此 MYSQL 查询
I need to optimize this MYSQL query
SELECT COUNT(student_id) AS count
FROM student_details
WHERE STATUS='REGISTER'
AND student_id NOT IN (
SELECT student_id FROM student_details WHERE STATUS='CANCEL'
)
AND registered_on< '2020-10-15 00:00:00'
我试过 NOT EXIST 但没有得到预期的结果
SELECT COUNT(DISTINCT S.student_id) AS ren
FROM student_details S
WHERE
S.status = 'REGISTER'
AND S.registered_on < '2020-10-15 00:00:00'
AND NOT EXISTS (
SELECT 1
FROM student_details S1
WHERE S.student_id = S1.student_id AND S1.status = 'CANCEL'
)
无法索引,因为 student_id 的重复条目,状态是有效条目,需要减少执行时间,因为 table 有大量数据。
如果您想要与使用 not exists
的第一个查询等效的内容,逻辑是:
SELECT COUNT(*) AS ren
FROM student_details sd
WHERE
sd.status = 'REGISTER'
AND sd.registered_on < '2020-10-15 00:00:00'
AND NOT EXISTS (SELECT 1 FROM subscription s WHERE s.student_id = sd.student_id AND s.status = 'CANCEL')
即:
子查询应该处理 table subscription
,而不是 student_details
.
你不想要 count(distinct ...)
- 如果 student_id
是 student_details
中的唯一键,结果可能是一样的,但你没有告诉。我使用了 count(*)
,它假设 student_id
不是 null
able。
此查询将利用 subscription(student_id, status)
上的索引。
您可以尝试使用 JOIN 条件查询:
SELECT COUNT(student_details.student_id) AS count
FROM student_details
LEFT JOIN subscription
ON subscription.student_id = student_details.student_id AND subscription.status = 'CANCEL'
WHERE
student_details.status='REGISTER'
AND subscription.status IS NULL
AND registered_on< '2020-10-15 00:00:00';
这里是fiddleSQLize.online
确定您的表在 student_id 字段上有索引。由于你是按状态字段过滤的,所以在这个字段上建立索引可以提高查询性能
SELECT COUNT(student_id) AS count
FROM student_details
WHERE STATUS='REGISTER'
AND student_id NOT IN (
SELECT student_id FROM student_details WHERE STATUS='CANCEL'
)
AND registered_on< '2020-10-15 00:00:00'
我试过 NOT EXIST 但没有得到预期的结果
SELECT COUNT(DISTINCT S.student_id) AS ren
FROM student_details S
WHERE
S.status = 'REGISTER'
AND S.registered_on < '2020-10-15 00:00:00'
AND NOT EXISTS (
SELECT 1
FROM student_details S1
WHERE S.student_id = S1.student_id AND S1.status = 'CANCEL'
)
无法索引,因为 student_id 的重复条目,状态是有效条目,需要减少执行时间,因为 table 有大量数据。
如果您想要与使用 not exists
的第一个查询等效的内容,逻辑是:
SELECT COUNT(*) AS ren
FROM student_details sd
WHERE
sd.status = 'REGISTER'
AND sd.registered_on < '2020-10-15 00:00:00'
AND NOT EXISTS (SELECT 1 FROM subscription s WHERE s.student_id = sd.student_id AND s.status = 'CANCEL')
即:
子查询应该处理 table
subscription
,而不是student_details
.你不想要
count(distinct ...)
- 如果student_id
是student_details
中的唯一键,结果可能是一样的,但你没有告诉。我使用了count(*)
,它假设student_id
不是null
able。
此查询将利用 subscription(student_id, status)
上的索引。
您可以尝试使用 JOIN 条件查询:
SELECT COUNT(student_details.student_id) AS count
FROM student_details
LEFT JOIN subscription
ON subscription.student_id = student_details.student_id AND subscription.status = 'CANCEL'
WHERE
student_details.status='REGISTER'
AND subscription.status IS NULL
AND registered_on< '2020-10-15 00:00:00';
这里是fiddleSQLize.online
确定您的表在 student_id 字段上有索引。由于你是按状态字段过滤的,所以在这个字段上建立索引可以提高查询性能