我开发了一种图像搜索工具,可以对所有图像的目录建立索引,存储数据,然后根据搜索结果。
这是可行的,但是由于数据量大(用于150,000张图像的约270万行元数据),返回结果花费了很长时间(有时> 5分钟)。我相信这是由于在foreach循环中查询第二组数据。我希望将sql合并为一条语句以更好地进行优化(除非有另一种方法!)。
到目前为止,我将返回所有元数据与搜索词匹配的image_id,然后使用返回的image_id获取每个图像的元数据表中的所有元数据。这是数据库的基本结构:
SELECT image_id
FROM metadata
WHERE (meta_value LIKE '%runner%')
AND meta_key IN ('keyword', 'filename', 'description')
GROUP BY image_id
到目前为止,我的代码从获取搜索词“ runner”匹配的所有图片开始(因此图片1和3)
$search_results = $imagesearch->search_images(); //object array from above sql
foreach ($search_results as $image) {
$id = $image->image_id;
$get_metadata = $imageget->get_metadata($id)
}
然后遍历返回的结果集并获取每个结果的元数据:
SELECT *
FROM metadata
WHERE image_id = $id
Array
(
[1] => array(
[image_id] => 1
[filename] => image_XYZ.jpg
[thumb] => image_XYZ_thumb.jpg
[filetype] => jpg
[keyword] => runner
[height] => 600
),
[2] => array(
[image_id] => 3
[filename] => runner_bean.jpg
[thumb] => runner_bean_thumb.jpg
[filetype] => jpg
[filesize] => 12485
[description] => runnerbean
[keyword] => runner
[keyword] => vegetable
),
)
然后使用元数据提取meta_key等于我想要的数据(例如height)以检索值等的行。
所以我的最终数组看起来像这样:
SELECT *
FROM metadata m
LEFT JOIN image i ON i.image_id = m.image_id
WHERE i.image_id IN (
SELECT image_id
FROM metadata
WHERE $search
AND meta_key IN ('keyword', 'filename', 'description')
GROUP BY image_id
)
GROUP BY m.image_id
到目前为止,我的工作是使用子查询首先获取与搜索字词匹配的图片,然后获取这些图片的元数据:
{{1}}
我的分组依据是按图像ID折叠结果,因此我仅获得每个图像的第一行(上述示例中的文件类型)。是否有一种方法可以获取与搜索词匹配的最终图像数组,并以更优化的方式返回每个图像的元数据?
任何帮助将不胜感激
答案 0 :(得分:0)
我看不到查询中第二个GROUP BY
的含义,我想您需要删除它。然后,查询将为每个图像元数据生成一行,并按图像排序。这并不完全是您期望的结构(这需要旋转结果集),但是您可以遍历它并动态生成数组数组(每次image_id
更改时,就开始提供新的子数组)在您的全局数组中。)
SELECT m.*
FROM metadata m
WHERE m.image_id IN (
SELECT DISTINCT image_id
FROM metadata
WHERE
meta_value LIKE '%runner%'
AND meta_key IN ('keyword', 'filename', 'description')
)
ORDER BY m.image_id
注意:根据数据的外观,内部查询中的SELECT DISTINCT
可能比SELECT
更为有效。
另一个选项(产生相同的结果集)是使用带有WHERE EXISTS
子句的相关子查询,如下所示:
SELECT m.*
FROM metadata m
WHERE EXISTS (
SELECT 1
FROM metadata
WHERE
image_id = m.image_id
AND meta_value LIKE '%runner%'
AND meta_key IN ('keyword', 'filename', 'description')
)
ORDER BY m.image_id