如何将这两个查询组合成一个优化查询以避免选择N + 1

时间:2012-07-07 05:30:12

标签: mysql sql

这是一个在线图片库。我有两张桌子; “photoSearch”和“照片”。第一个“photoSearch”只有几列,包含照片的所有可搜索数据,例如“photoID”,“标题”,“标题”,“人物”,“dateCaptured”和“关键字”。它有一个多列全文索引(标题,标题,人物,关键字)。第二张表“照片”包含所有照片数据;高度,宽度,版权,标题,ID,日期等等。两者都有500K +行,标题和标题字段有时会返回2000多个字符。

这大约是查询现在的样子:(需要注意的事项:我不能使用全文搜索的连接,因此关键字存储在一列中 - 在'去规范化'表中。此外,这种伪代码为我的应用程序代码在其他地方 - 但它很接近)

这个特定的查询正在循环中循环,另一个SQL语句正在执行......

 SELECT photoID FROM photoSearch
 WHERE MATCH (headline, caption, people, keywords)
 AGAINST ('"&booleanSearchStr&"' IN BOOLEAN MODE)
 AND dateCaptured BETWEEN '"&fromDate&"' AND '"&toDate&"';"

这是为上面查询中的每一行执行的SQL语句:

 SELECT photoID, setID, eventID, locationID, headline, caption, instructions, dateCaptured, dateUploaded, status, uploaderID, thumbH, thumbW, previewH, previewW, + more 
 FROM photos 
 LEFT JOIN events AS e USING (eventID) 
 LEFT JOIN location AS l USING (locationID) 
 WHERE photoID = " & photoID & ";"

经过测试,在自己的桌子上有全文索引,“photoSearch”,而不是大桌子,“照片”,似乎有点提高了速度。我没有添加“photoSearch”表,它已经存在 - 这不是我的应用程序。如果我尝试加入这两个表以丢失第二个查询,我会丢失所有索引,导致很长时间 - 所以我不能使用全文连接。这似乎是最快捷的方法。如果不是全文和加入问题,我会将这两个问题结合起来。

是否可以将这两个查询合并为一个,以使流程更有效地运行,而不是对查询1中的每个结果执行1000次查询#1?

1 个答案:

答案 0 :(得分:0)

如果Join不起作用,请尝试子查询:

SELECT photoID, setID, eventID, locationID, headline, caption, instructions, dateCaptured, dateUploaded, status, uploaderID, thumbH, thumbW, previewH, previewW, + more 
FROM (
    SELECT photoID 
    FROM photoSearch
    WHERE
        MATCH (headline, caption, people, keywords)
            AGAINST ('"&booleanSearchStr&"' IN BOOLEAN MODE)
        AND dateCaptured BETWEEN '"&fromDate&"' AND '"&toDate&"';"
) as SelectedPhotos
LEFT JOIN photos USING (photoID)
LEFT JOIN events AS e USING (eventID) 
LEFT JOIN location AS l USING (locationID)

或尝试找出为什么连接不起作用,我应该使用:

SELECT photoID, setID, eventID, locationID, headline, caption, instructions, dateCaptured, dateUploaded, status, uploaderID, thumbH, thumbW, previewH, previewW, + more 
FROM photoSearch
LEFT JOIN photos USING (photoID)
LEFT JOIN events AS e USING (eventID) 
LEFT JOIN location AS l USING (locationID)
WHERE
    MATCH (headline, caption, people, keywords)
        AGAINST ('"&booleanSearchStr&"' IN BOOLEAN MODE)
    AND dateCaptured BETWEEN '"&fromDate&"' AND '"&toDate&"';"