Я не SQL pro, но я считаю, что решил свою проблему, хотя и довольно неэффективным способом. Я надеюсь, что кто-то может указать на лучший метод, чем я придумал. Я пытаюсь найти дублированный или похожий контент в индексе терминов, созданный RelevanSSI (плагин полного текстового поиска для Wordpress) - однако это происходит за пределами установки Wordpress, и это фактическая база данных, поэтому Wordpress, это API и любые другие таблицы обычно связанные с ним, выходят за рамки этого.Получить неагрегатные данные в сводном запросе
RelevanSSI Index таблица выглядит следующим образом:
CREATE TABLE `wp_relevanssi` (
`doc` bigint(20) NOT NULL DEFAULT '0',
`term` varchar(50) NOT NULL DEFAULT '0',
`content` mediumint(9) NOT NULL DEFAULT '0',
`title` mediumint(9) NOT NULL DEFAULT '0',
`comment` mediumint(9) NOT NULL DEFAULT '0',
`tag` mediumint(9) NOT NULL DEFAULT '0',
`link` mediumint(9) NOT NULL DEFAULT '0',
`author` mediumint(9) NOT NULL DEFAULT '0',
`category` mediumint(9) NOT NULL DEFAULT '0',
`excerpt` mediumint(9) NOT NULL DEFAULT '0',
`taxonomy` mediumint(9) NOT NULL DEFAULT '0',
`customfield` mediumint(9) NOT NULL DEFAULT '0',
`mysqlcolumn` mediumint(9) NOT NULL DEFAULT '0',
`taxonomy_detail` longtext NOT NULL,
`customfield_detail` longtext NOT NULL,
`mysqlcolumn_detail` longtext NOT NULL,
`type` varchar(210) NOT NULL DEFAULT 'post',
`item` bigint(20) NOT NULL DEFAULT '0',
`term_reverse` varchar(50) NOT NULL DEFAULT '0',
UNIQUE KEY `doctermitem` (`doc`,`term`,`item`),
KEY `terms` (`term`(20)),
KEY `docs` (`doc`),
KEY `typeitem` (`type`,`item`),
KEY `relevanssi_term_reverse_idx` (`term_reverse`(10))
) ENGINE=InnoDB DEFAULT CHARSET=utf8
И я успешно получаю (я думаю) информацию я хочу с помощью следующего запроса:
SELECT r1.doc, r2.doc,
50 * COUNT(r1.term) * (
(c1.total + c2.total)/
(c1.total * c2.total)
) AS ScorePct
FROM `wp_relevanssi` r1
LEFT JOIN `wp_relevanssi` r2
ON r1.term = r2.term
AND r1.doc > r2.doc
AND r1.type = r2.type
AND (r1.content > 0 or r1.title > 0 or r1.taxonomy > 0 or r1.tag > 0)
AND (r2.content > 0 or r2.title > 0 or r2.taxonomy > 0 or r2.tag > 0)
LEFT JOIN (
SELECT doc, COUNT(term) AS total
FROM `wp_relevanssi`
GROUP BY doc
) c1
ON r1.doc = c1.doc
LEFT JOIN (
SELECT doc, COUNT(term) AS total
FROM `wp_relevanssi`
GROUP BY doc
) c2
ON r2.doc = c2.doc
GROUP BY r1.doc, r2.doc
HAVING ScorePct >50
ORDER BY ScorePct DESC
Мой вопрос таков большой ола 'хитроумные подзапросы упали в соединения. Мне кажется, мне нужен хотя бы один подзапрос, чтобы сделать это (по сути, получить общее количество терминов для конкретного документа), потому что после этого первого LEFT JOIN
у нас есть только информация о совпадении терминов в основном запросе, отбросив несоответствующие , (Пожалуйста, продолжайте и скажите мне, что я здесь не прав, я бы хотел узнать, что подзапрос не нужен).
Помимо этого, есть ли способ для меня сделать это с помощью одного подзапроса или иным образом улучшить производительность этого запроса? Я полностью ожидаю, что это будет очень тяжелый запрос, у меня нет никаких опасений относительно этого, но я бы хотел, чтобы он работал как можно лучше.
EDIT: Так что я просто должен был решить эту проблему с другим подходом - глядя на один документ, в то время (как документ изменен), я могу упростить запрос к:
SELECT r1.doc, r2.doc, count(*) AS matches
FROM `wp_relevanssi` r1
INNER JOIN `wp_relevanssi` r2
ON r1.term = r2.term
AND r1.doc <> r2.doc
AND r1.type = r2.type
AND (r1.content > 0 or r1.title > 0 or r1.taxonomy > 0 or r1.tag > 0)
AND (r2.content > 0 or r2.title > 0 or r2.taxonomy > 0 or r2.tag > 0)
WHERE r1.doc = %d
GROUP BY r1.doc, r2.doc
ORDER BY matches DESC
LIMIT 0,10
Который работает в разумные сроки, даже с 650000 строк, а последующие с:
SELECT doc, COUNT(term) AS total
FROM `wp_relevanssi`
WHERE doc IN (%d,%d,%d...)
GROUP BY doc
затем сделать остальную часть партитуры матча за пределами БД.
попробовать композитный индекс на '(срок , type, doc) '. 'doc' должен быть последним, потому что он используется в неравенстве в вашем соединении. этот индекс может ускорить ваше присоединение – FuzzyTree
Привет @FuzzyTree, спасибо за предложение, в этом случае, к сожалению, структура таблицы не в моих силах - сама таблица исходит от стороннего плагина, я просто пытаюсь сделать некоторый анализ на нем , Из интереса и моего собственного назидания, вы имеете в виду, что это ускорит первое соединение (с самим собой) или последующие объединения с подзапросами? –
Если схема находится вне вашего контроля, но вы хотите поэкспериментировать, скопируйте таблицу. –