代码应选择具有最少量未分级图像的下一个标记。
流动的列有索引:
代码应遍历每一行并检查有多少重复的tag_name-column。之后它应该返回具有最少重复行数的标记。代码应忽略pick = TRUE
或reject = TRUE
意味着代码应仅包含pick = FALSE
和reject = FALSE
目前,我的代码就在下面。
SELECT image_tags.tag_name, COUNT(*) as number_of_rows FROM image_tags JOIN images ON image_tags.filename = images.filename WHERE images.pick = FALSE AND images.reject = FALSE GROUP BY image_tags.tag_name ORDER BY number_of_rows
由于数据库的大小,查询需要花费大量时间(有时多达30秒)。有没有办法让查询运行得更快,还是有另一个查询可以减少执行时间?
答案 0 :(得分:1)
这是您的查询:
SELECT it.tag_name, COUNT(*) as number_of_rows
FROM image_tags it JOIN
images i
ON it.filename = i.filename
WHERE i.pick = FALSE AND i.reject = FALSE
GROUP BY it.tag_name
ORDER BY number_of_rows;
首先要尝试的是images(pick, reject, filename)
上的索引。这可能无济于事,因为布尔列通常不会足够减少数据。但值得一试。
要尝试的第二件事是这个查询:
SELECT it.tag_name,
(SELECT COUNT(*)
FROM images i
WHERE it.filename = i.filename AND
i.pick = FALSE AND
i.reject = FALSE
) as number_of_rows
FROM image_tags it
GROUP BY it.tag_name
ORDER BY number_of_rows;
这会将聚合移动到子查询,这有时在MySQL中表现更好。为此,您需要images(filename, pick, reject)
上的索引。另请注意,这会返回所有标记,而不仅仅是具有匹配图像的标记。如果您希望获得与版本相同的结果,可以使用HAVING number_of_rows > 0
进行过滤。
编辑:
哦,我明白了。你可以试试这个版本:
SELECT t.tag_name,
(SELECT COUNT(*)
FROM image_tags it JOIN
images i
ON it.filename = i.filename
WHERE it.tag_name = t.tag_name AND
i.pick = FALSE AND
i.reject = FALSE
) as number_of_rows
FROM (SELECT DISTINCT tag_name FROM image_tags) t
ORDER BY number_of_rows;
为此,您需要image_tags(tag_name, filename)
和images(filename, pick, reject)
上的索引。但是,我不确定这会有很大改善。
答案 1 :(得分:0)
确保为JOIN ON
条件中使用的列创建了适当的索引; WHERE
条件; ORDER BY
。在您的情况下,您应该在
image_tags.filename
和images.filename
images.pick
; images.reject
还可以考虑为查询运行EXPLAIN
,看看您获得的查询计划会更好。
EXPLAIN SELECT image_tags.tag_name, COUNT(*) as number_of_rows FROM image_tags ....
答案 2 :(得分:0)
由于images表具有int主键,因此将image_id作为image_tags表中的外键以及该列上的索引更有意义。 您将获得速度和存储空间。