Я только что добавил систему тегов на свой сайт и пытаюсь найти наиболее эффективный способ выполнения масштабируемых запросов. Вот основной рабочий запрос 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,
, и для каждого * 1008 существует несколько интерпретаций. Вот рабочий запрос для двух 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 строк данных. Как я могу сделать это, не возвращаясь к этому уродливому неэффективному коду?