Php 我不想永远这样

Php 我不想永远这样,php,mysql,sql,subquery,Php,Mysql,Sql,Subquery,此查询通常需要4到5秒才能运行。以下是我的表格统计: 学生表:4200行 idtrack表15000行 我的问题是: SELECT students.student_id FROM students WHERE students.grade_level ='12' AND students.student_id NOT IN ( SELECT idtrack.student_id FROM idtrack WHERE idtrack.event_id ='33' )

此查询通常需要4到5秒才能运行。以下是我的表格统计:

学生表:4200行

idtrack表15000行

我的问题是:

SELECT students.student_id
FROM students
WHERE students.grade_level ='12' 
AND students.student_id 
NOT IN (
    SELECT idtrack.student_id
    FROM idtrack
    WHERE idtrack.event_id ='33'
)

现在完成此查询需要30秒。有人能帮我优化/重构吗?提前感谢。

也许您忘记了为表创建主Kay?

也许您忘记了为表创建主Kay?

存在
通常要快得多,因为在您的情况下,当MySQL在
idtrack
中发现与
不存在
子句相矛盾的记录时,它允许MySQL短路

SELECT students.student_id
FROM students
WHERE students.grade_level ='12' 
AND NOT EXISTS (
SELECT idtrack.student_id
FROM idtrack
WHERE idtrack.event_id ='33'
AND idtrack.student_id = students.student_id
)

EXISTS
通常要快得多,因为在您的例子中,当MySQL在
idtrack
中发现与
notexists
子句相矛盾的记录时,它允许MySQL短路

SELECT students.student_id
FROM students
WHERE students.grade_level ='12' 
AND NOT EXISTS (
SELECT idtrack.student_id
FROM idtrack
WHERE idtrack.event_id ='33'
AND idtrack.student_id = students.student_id
)

加入idtrack上的学生,过滤“where students.grade\u level=12和idtrack.event\u id 33”怎么样?联接应该比子查询快。简单的平等/不平等比“不在”快得多。

如何加入idtrack上的学生,并过滤“where student.grade\u level=12和idtrack.event\u id 33”?联接应该比子查询快。简单的相等/不相等比“不在”快得多。

你也可以试试

SELECT students.student_id
FROM students
LEFT JOIN idtrack ON idtrack.event_id='33' AND idtrack.student_id = students.student_id
WHERE students.grade_level ='12' 
AND idtrack.student_id IS NULL
你也可以试试

SELECT students.student_id
FROM students
LEFT JOIN idtrack ON idtrack.event_id='33' AND idtrack.student_id = students.student_id
WHERE students.grade_level ='12' 
AND idtrack.student_id IS NULL

如果没有看到CREATETABLE命令和explain输出,它相当困难。但你可以试试:

SELECT students.student_id
FROM students LEFT JOIN idtrack
    ON students.id=idtrack.student_id
    AND idtrack.event_id ='33'
WHERE students.grade_level ='12' 
AND idtrack.student_id IS NULL

顺便说一句,如果idtrack.event\u id和students.grade\u level被声明为数字,那么它们就不应该被引用。

在没有看到创建表命令和解释输出的情况下,这相当困难。但你可以试试:

SELECT students.student_id
FROM students LEFT JOIN idtrack
    ON students.id=idtrack.student_id
    AND idtrack.event_id ='33'
WHERE students.grade_level ='12' 
AND idtrack.student_id IS NULL

顺便说一句,如果idtrack.event\u id和students.grade\u level被声明为数字,那么它们就不应该被引用。

子查询总是需要时间的,请确保您有索引并查看查询的执行计划。如果您发布表架构,效果更好。子查询总是需要时间,确保有索引并查看query的执行计划如果发布表模式,更好。我有所有表的主键。最好在绑定字段
学生上创建索引。学生id
idtrack。事件id
我有所有表的主键。最好在绑定字段
学生上创建索引。学生id
idtrack。事件id在唯一索引字段上的比例为4:1?我会非常惊讶。@symcbean:我没有注意到每个表的记录数。在唯一的索引字段上有4:1的比率?我会非常惊讶。@symcbean:我没有注意到每个表的记录数。我尝试了这个,但仍然收到缓慢的结果。我最终用PHP和数组intesect完成了它!谢谢我尝试了这个,但仍然收到缓慢的结果。我最终用PHP和数组intesect完成了它!谢谢