我刚刚在我的网站上添加了一个标记系统,我正在尝试找出运行可扩展查询的最有效方法。这是一个基本的工作 mysql 查询,用于返回给定用户的标签匹配:
SELECT
scans.scan_index,
scans.scan_id,
scans.archive_folder
FROM
tags
INNER JOIN
interpretationtags USING (tagid)
INNER JOIN
interpretations USING (interpretation_id)
INNER JOIN
scans
ON scans.scan_id = interpretations.scan_id
AND scans.archive_folder = interpretations.archive_folder
INNER JOIN
archives
ON scans.archive_folder = archives.archive_folder
WHERE
archives.user_id = "google-authd...."
AND tags.tag = "tag1"
但是当我想查询多个tags
相同的scan
. 你看,tags
存在于不同的interpretations,
地方,每个都有多种解释scan.
这是两个tags
使用子查询的工作查询:
SELECT
a.scan_index,
a.scan_id,
a.archive_folder
FROM
(
SELECT
scans.scan_index,
scans.scan_id,
scans.archive_folder
FROM
tags
INNER JOIN
interpretationtags USING (tagid)
INNER JOIN
interpretations USING (interpretation_id)
INNER JOIN
scans
ON scans.scan_id = interpretations.scan_id
AND scans.archive_folder = interpretations.archive_folder
INNER JOIN
archives
ON scans.archive_folder = archives.archive_folder
WHERE
archives.user_id = "google-auth2..."
AND tags.tag = "tag1"
)
as a
INNER JOIN
interpretations
ON a.scan_id = interpretations.scan_id
AND a.archive_folder = interpretations.archive_folder
INNER JOIN
interpretationtags USING(interpretation_id)
INNER JOIN
tags USING(tagid)
WHERE
tags.tag = "tag2"
由于它在 LAMP 堆栈上运行,因此我编写了一些 PHP 代码来迭代tags
我想包含在此 AND 样式搜索中的内容,从而构建多嵌套查询。这是一带三
SELECT
b.scan_index,
b.scan_id,
b.archive_folder
FROM
(
SELECT
a.scan_index,
a.scan_id,
a.archive_folder
FROM
(
SELECT
scans.scan_index,
scans.scan_id,
scans.archive_folder
FROM
tags
INNER JOIN
interpretationtags USING (tagid)
INNER JOIN
interpretations USING (interpretation_id)
INNER JOIN
scans
ON scans.scan_id = interpretations.scan_id
AND scans.archive_folder = interpretations.archive_folder
INNER JOIN
archives
ON scans.archive_folder = archives.archive_folder
WHERE
archives.user_id = "google..."
AND tags.tag = "tag1"
)
as a
INNER JOIN
interpretations
ON a.scan_id = interpretations.scan_id
AND a.archive_folder = interpretations.archive_folder
INNER JOIN
interpretationtags USING(interpretation_id)
INNER JOIN
tags USING(tagid)
WHERE
tags.tag = "tag2"
)
as b
INNER JOIN
interpretations
ON b.scan_id = interpretations.scan_id
AND b.archive_folder = interpretations.archive_folder
INNER JOIN
interpretationtags USING(interpretation_id)
INNER JOIN
tags USING(tagid)
WHERE
tags.tag = "tag3"
即使 4 个嵌套子查询也能以最少的数据快速运行,但是当我处理 100k 行数据时,我只是不认为这是一个可扩展的解决方案。我怎样才能在不恢复到这个丑陋的低效代码的情况下实现这一点?
如果没有表结构和示例数据,很难确定,但我认为您的做法是错误的。您应该从扫描开始并找到所有合适的标签,然后过滤这些标签(这应该是一个简单的IN
表达式):
SELECT
scans.scan_index,
scans.scan_id,
scans.archive_folder
FROM
scans
INNER JOIN
archives
ON scans.archive_folder = archives.archive_folder
INNER JOIN
interpretations
ON scans.scan_id = interpretations.scan_id
AND scans.archive_folder = interpretations.archive_folder
INNER JOIN
interpretationtags USING (interpretation_id)
INNER JOIN
tags USING (tagid)
WHERE
archives.user_id = "google-authd...."
AND tags.tag IN("tag1", "tag2")
请注意,根据您的SELECT
字段列表,我不认为你真的需要JOIN
到archives
的。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句