У меня есть таблица USERSEARCH, которую следует использовать для быстрого поиска подстроки для пользователей. Эта функция предназначена для автозаполнения поиска, который происходит, когда кто-то вводит имя пользователя или имя. Однако интересующий меня запрос будет показывать только совпадения от тех пользователей, за которыми следует поисковик. Это можно найти в таблице ПОЛЬЗОВАТЕЛЬСКИЕ СВЯЗИ.
USERSEARCH
-----------------------------------------------
user_id(FK) username_ngram name_ngram
1 "AleBoy leBoy eBoy..." "Ale le e"
2 "craze123 raze123 ..." "Craze raze aze ze e"
3 "john1990 ohn1990 ..." "John ohn hn n"
4 "JJ_1 J_1 _1 1" "JJ"
USERRELATIONSHIP
-----------------------------------------------
user_id(FK) follows_id(FK)
2 1
2 3
Запрос, подобный этому, будет сделан, когда кто-то только что набрал «Al» (не учитывая отношения пользователей):
SELECT * FROM myapp.usersearch where username_ngram like 'Al%'
UNION DISTINCT
SELECT * FROM myapp.usersearch where name_ngram like 'Al%'
UNION DISTINCT
SELECT * FROM myapp.usersearch
WHERE MATCH (username_ngram, name_ngram) AGAINST ('Al')
LIMIT 10
Это невероятно быстро из-за существующих индексов в username_ngram, name_ngram и FULLTEXT (username_ngram, name_ngram). Однако в контексте моего приложения мне нужно ограничить поиск пользователями, за которыми следует поисковик. Я хотел бы заменить таблицу «myapp.usersearch» подмножеством таблицы «myapp.usersearch», включая только пользователей, за которыми следит поисковик. Вот что я попытался:
WITH
--Part 1, restrict the USERSEARCH table to just the users that are followed by searcher
tempUserSearch AS (SELECT T1.id, T2.username_ngram, T2.name_ngram FROM
(SELECT follows_id FROM myapp.userrelationship WHERE user_id = {user_idOfSearcher} ) AS T1
LEFT JOIN myapp.usersearch AS T2 ON T2.user_id = T1.follows_id)
SELECT * FROM tempUserSearch where username_ngram like 'Al%'
UNION DISTINCT
SELECT * FROM tempUserSearch where name_ngram like 'Al%'
UNION DISTINCT
SELECT * FROM tempUserSearch
WHERE MATCH (username_ngram, name_ngram) AGAINST ('Al')
LIMIT 10
К сожалению, MySQL 5.7 не поддерживает предложение CTE WITH.
Есть ли способ ссылаться на часть 1 запроса во всех последующих подзапросах без повторного запроса user_ids пользователей, за которыми следует человек? (в MySQL 5.7)
Обновление:
Действительно ли нет возможности ссылаться на запрос несколько раз в MySQL 5.7? Что-то кажется неправильным, поскольку это кажется мне фундаментальной задачей для любого db.
Почему бы не сделать: «x соединяется с y на a или b или c»? Скорость моего запроса подстроки зависит от следующих индексов:
index(username_ngram)
index(name_ngram)
FULLTEXT(username_ngram, name_ngram)
И использование OR не помогает никаким индексам.