简体   繁体   English

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

[英]How to combine these two queries into one optimized query to avoid a Select N+1

This is for an online photo library. 这是用于在线照片库的。 I have two tables; 我有两个桌子。 "photoSearch" and "photos". “ photoSearch”和“照片”。 The first, "photoSearch", has just a few columns and contains all searchable data for the photos, such as "photoID", "headline", "caption", "people", "dateCaptured" and "keywords". 第一个是“ photoSearch”,只有几列,其中包含照片的所有可搜索数据,例如“ photoID”,“标题”,“标题”,“人物”,“ dateCaptured”和“关键字”。 It has a multi-column full-text index on (headline, caption, people, keywords). 它具有关于(标题,标题,人员,关键字)的多列全文索引。 The second table, "photos", contains all of the photos data; 第二张表“照片”包含所有照片数据。 heights, widths, copyrights, caption, ID's, dates and much more. 高度,宽度,版权,标题,ID,日期等。 Both have 500K+ rows and the headline and caption fields sometimes return 2000+ characters. 两者都有500K +行,并且标题和标题字段有时会返回2000+个字符。

This is approximately how the query looks now: (things to note: I cannot use joins with fulltext searching, hence keywords being stored in one column - in a 'de-normalized' table. Also, this kind of pseudo code as my app code is elsewhere - but it's close ) 这大约是查询现在的样子:(注意事项:我无法将联接与全文搜索一起使用,因此关键字被存储在“非规范化”表的一列中。此外,这种伪代码作为我的应用程序代码在其他地方-但很近)

This particular query is being looped through and inside the loop, another SQL statement is being executed... 这个特定的查询正在循环中并且在循环内部,正在执行另一个SQL语句...

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

This is the SQL Statement being executed for each row in the query above: 这是针对上面查询中的每一行执行的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 & ";"

When tested, having the full-text index on its own table, "photoSearch", instead of the large table, "photos", seemed to improve speed somewhat. 经过测试,在其自己的表“ photoSearch”上有全文索引,而不是在大表“ photos”上,似乎在一定程度上提高了速度。 I didn't add the "photoSearch" table, it was already there - this is not my app. 我没有添加“ photoSearch”表,该表已经存在-这不是我的应用程序。 If I try joining the two tables to lose the second query, I lose my indexing all together, resulting in very long times - so I can't use joins with full-text. 如果我尝试将两个表连接起来以丢失第二个查询,那么我的索引将全部丢失,这将导致很长的时间-因此,我无法使用全文连接。 This just seemed to be the quickest method. 这似乎是最快的方法。 If it wasn't for the full-text and joining problems, I would have combined both of these queries already. 如果不是针对全文和联接问题,我已经将这两个查询合并了。

Is it possible to combine these two queries into one, to make the process run more efficiently, rather than executing query #2 1000 times for each result in query 1? 是否可以将这两个查询合并为一个,以使过程更有效地运行,而不是对查询1中的每个结果执行#2查询1000次?

If a Join didn't work, try a subquery: 如果联接不起作用,请尝试子查询:

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)

or try to find out why the join didn't work, i should have used: 或尝试找出为什么联接不起作用的原因,我应该使用:

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&"';"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM