我有两个查询,每个查询返回一个节点ID列表
SELECT node.nid
FROM dpf_node AS node
WHERE node.type = 'image' AND node.nid;
SELECT node.nid
FROM dpf_node AS node, dpf_image_galleries_images AS image
WHERE image.image_nid = node.nid
AND node.type = 'image'
AND image.gallery_nid = 138;
这两个都正常工作
最终虽然我想得到第一个结果列表而不是第二个结果列表中的节点ID列表,但我一直在使用这个查询:
SELECT node.nid
FROM dpf_node AS node
WHERE node.type = 'image'
AND node.nid NOT IN (SELECT node.nid
FROM dpf_node AS node, dpf_image_galleries_images AS image
WHERE image.image_nid = node.nid
AND node.type = 'image'
AND image.gallery_nid = 138);
有一段时间这个工作正常,但就在今晚,它正在沙滩上投球,并导致阿帕奇陷入停顿。我怀疑(/希望)清除数据并重新开始将解决它但是真的想要解决真正的问题,以防它在系统运行后重新抬头。
答案 0 :(得分:1)
将其更改为NOT EXISTS
查询以帮助提高效果:
SELECT node.nid
FROM dpf_node AS node
WHERE node.type = 'image'
AND NOT EXISTS (
SELECT 1
FROM dpf_node AS i_node
JOIN dpf_image_galleries_images AS image ON i_node.nid = image.image_nod
WHERE node.type = 'image'
AND image.gallery_nid = 138
AND i_node.nid = node.nid
)
您还应验证您是否有足够的索引。
答案 1 :(得分:1)
MySQL可能在使用相关子查询时做了相当愚蠢的事情(查看查询计划)。 如果您只想要第一个查询中不在第二个查询中的内容,则可以通过两个LEFT OUTER JOIN获得明显更好的性能,并使用筛选条件筛选出具有第二组结果的空值的行。 / p>
答案 2 :(得分:0)
你应该能够用一个选择来做到这一点。您可以排除它们,而不是选择您不想要的所有节点,而是首先选择您想要的节点。如果图像库和节点之间可能存在许多关系,并且您只需要唯一的node.nids,则将其设置为select distinct。
SELECT node.nid
FROM dpf_node AS node
JOIN dpf_image_galleries_images AS image
ON node.nid = image.image_nod
WHERE node.type = 'image'
AND image.gallery_nid != 138
根据数据的布局方式和数据量,这应该比where子句子查询好得多。而且它更容易理解。