2010-04-30 2 views
1

У меня есть две таблицы, каждая из которых имеет более 20 миллионов записей; table1 - это список терминов, а таблица2 - список ключевых слов, которые могут появляться или не отображаться в этих терминах. Мне нужно определить термины, содержащие ключевое слово.
Поле «термин» - это VARCHAR (320), а поле «keyword» - VARCHAR (64).mysql - фильтрация списка против ключевых слов, списка и ключевых слов> 20 миллионов записей (медленных)

Моя текущая стратегия:

SELECT table1.term, table2.keyword FROM table1 INNER JOIN table2 ON table1.term 
LIKE CONCAT('%', table2.keyword, '%'); 

Это не работает, он принимает е о р е v е р.
Это не сервер, афайк (см. Примечания).

Как я могу переписать это так, чтобы он работал в течение дня?

Я развлекал таблицы в памяти или менялся на innodb и делал буферный пул достаточно большим, чтобы удерживать обе таблицы. К сожалению, каждый поток mysql связан с одним процессором, но у меня есть 4 ядра (ну, «8» с гиперпотоком); если бы я мог распределить рабочую нагрузку, это было бы фантастически.

Примечания:

  1. Что касается оптимизации сервера: обе таблицы MyISAM и имеют уникальные индексы по совпадающему полей; буфер ключа myisam больше, чем сумма обоих размеров файлов индекса, и он даже не облагается полностью (key_blocks_unused ... большой); сервер представляет собой 2x двухъядерный xeon 2U beast с быстрыми дисками sas и 8G RAM, настроенный для рабочей нагрузки mysql.

  2. Я только что вспомнил, что я только индексирую первые 80 символов поля «термин» (чтобы сохранить дисковое пространство); не уверен, что это больно или помогает.

  3. MySQL 5.0.32, Debian Lenny x86_64

+1

Индекс по сроку не будет использоваться в запросе LIKE, таком как ваш, так что это не имеет значения. Поскольку вы по существу просматриваете каждое ключевое слово, индекс на этом тоже не имеет значения. –

+0

Будет ли регулярное выражение быть быстрее, чем LIKE? – mikewaters

+0

конечно - нет. – zerkms

ответ

1

Вы хотите создать полнотекстовый индекс, а затем выполнить поиск по этому вопросу. Прямо сейчас, ваш уникальный индекс, вероятно, не помогает поиску вообще (из-за ведущего «%» в поиске).

Это означает, что почти наверняка выполняется полное сканирование таблицы1 для каждого элемента таблицы2. Призыв к тому, что это крайне неэффективно, прекрасно это делает. Построение полнотекстового индекса несколько медленное (хотя, вероятно, быстрее, чем то, что вы делаете прямо сейчас), но как только это будет сделано, поиск должен пойти на лот быстрее.

Что касается использования полнотекстового индексирования: в то время как у MySQL есть встроенная функция полнотекстового индексирования, я сомневаюсь, что это вам очень поможет - с 20 миллионами строк, его производительность довольно бедным (по крайней мере, по моему опыту). Sphinx - это немного больше работы по настройке, но с гораздо большей вероятностью даст вам адекватную производительность.

+0

почему полный текст для регулярного отношения M: M? – zerkms

1

для первых вы должны нормализовать схему: вы должны сделать 3-ю таблицу, чтобы сохранить соотношение между terms и keywords в виде term_id <-> keyword_id, не так, как вы делаете это теперь - в поле char, разделенное пробелами

+0

Проблема заключается в первоначальном анализе отношений терминов/ключевых слов, а не их хранении. Я фактически сохраняю результаты в третьей таблице. – mikewaters

+0

, если вы последуете моему совету - вы можете быстро выбрать нужные данные. – zerkms

+0

Спасибо за советы, zerkms; Я это сделал. К сожалению, начальный запрос работает * еще (3 дня), поэтому мне все еще нужна помощь. Я рассматриваю возможность написания сценария для выполнения анализа вместо этого, поэтому у меня больше контроля над распараллеливанием и т. Д. – mikewaters

Смежные вопросы