Нечетный вопрос к фразе, но немного легче объяснить в структуре таблицы. Два стола:
CREATE TABLE 'posts' (
'id' bigint(20) AUTO_INCREMENT,
'text' mediumtext,
PRIMARY KEY ('id')
);
CREATE TABLE 'dictionary' (
'id' bigint(20) AUTO_INCREMENT,
'term' varchar(255),
'definition' varchar(255),
PRIMARY KEY ('id'),
UNIQUE KEY 'ix_term' ('term')
);
Таблица posts
содержит большие проходы произвольного текста. Таблица dictionary
поддерживает отображение терминов (то есть отдельных слов, которые могут встречаться в тексте) и их определения (более широкое значение).
Пример некоторых данных по posts
:
+----+-----------+
| id | text |
+----+-----------+
| 1 | foo |
| 2 | bar |
| 3 | foo bar |
| 4 | foobarbaz |
+----+-----------+
Пример некоторых данных dictionary
:
+----+------+--------------------------+
| id | term | definition |
+----+------+--------------------------+
| 1 | foo | A foo is a foo. |
| 2 | bar | A bar is a bar. |
| 3 | baz | A baz is something else. |
| 4 | quux | Who knows. |
+----+------+--------------------------+
В данных примера есть запись словаря для термина quux
, который не отображается в тексте любых сообщений. Я хотел бы удалить такие неиспользуемые строки из таблицы словаря, но из-за компоновки схемы, похоже, не особенно эффективный способ сделать это.
Лучшее, что я смог собрать, - это:
DELETE 'dictionary' FROM 'dictionary'
LEFT JOIN 'posts' ON 'posts'.'text' LIKE CONCAT('%', 'dictionary'.'term', '%')
WHERE 'posts'.'id' IS NULL;
... и это sloooow. Мне интересно, есть ли более эффективный способ построения условия JOIN
или лучший способ сделать LIKE %...%
или совсем другой подход к поиску posts.text
который будет работать быстрее.
(В стороне, я признаю, что наличие многого числа, которое связывает posts
с соответствующими строками dictionary
было бы гораздо более эффективным способом поддерживать и искать эти данные, но код приложения - это то, что он есть.)
Создать таблицу как select (CTAS) должна работать быстрее, чем удалить с помощью соединения.
CTAS
where exists
: CREATE TABLE dictionary_new
AS выберите * из dictionary
где существует (выберите 1 из posts
где posts
. text
LIKE CONCAT ('%', dictionary
term
, '%'))
;
Удалить исходный стол
drop table dictionary
;
Переименовать таблицу
RENAME TABLE dictionary_new
TO dictionary
;
4.Создать ограничения
ALTER TABLE 'dictionary' ADD PRIMARY KEY(id);
ALTER TABLE 'dictionary' ADD UNIQUE KEY 'ix_term' ('term')