2013-04-09 3 views
1

Работая над проектом, в котором схема что-то вроде этого:поиск MySQL FTS против нескольких запросов

id , key, value

В key и value столбцы VARCHAR, и таблица InnoDB.

Пользователь может искать на основе пар значений ключа ... Каков наилучший способ запроса в MySQL? варианты я могу думать:

  • Для каждого key => value формирует запрос и выполнить inner join, чтобы получить id соответствие всех критериев.

  • или в фоновом режиме, заполнить таблицу MyISAMid, info с Full Text index на info и одного запроса с использованием like '%key:value%key2:value2%'. Преимущество этого будет позже, если сайт будет популярен, а таблица имеет сто тысяч строк, я могу легко передать код Lucene, но на данный момент MySQL.

+0

Я не думаю, что последнее будет быстрее, так как мы используем его. – srinath

ответ

2

Узор вы говорите, называется реляционная деление.

Вариант № 1 (самоподключение) является гораздо более быстрым решением, если у вас есть нужные индексы.

Я сравнил производительность для нескольких решений для реляционного деления в моей презентации SQL Query Patterns, Optimized. Решение самосоединения работало в 0,005 секунды даже против таблицы с миллионами строк.

Вариант № 2 с полным текстом не так, как вы его написали, потому что вы не использовали бы LIKE с полнотекстовым поиском. Вы бы использовали MATCH(info) AGAINST('...' IN BOOLEAN MODE). Я не уверен, что вы можете использовать шаблоны в формате key:value в любом случае. MySQL FTS предпочитает сопоставлять слова.

0

@Bill Karwin

Если вы собираетесь сделать это за 1 условие, это будет очень быстро с этой EAV типа схемы, но если вы делаете это для многих (особенно со смешанными Анд и ОШ) он, вероятно, развалится. Лучшее, на что можно надеяться, - это нечто вроде супер быстрого слияния индекса, и это неуловимо. Вы получите временную таблицу в большинстве СУБД, если вы что-нибудь придумаете. Кажется, я помню, что вы не поклонник EAV, и, может быть, я вас не понимаю.

Насколько я помню, СУБД также может выполнять несколько сканирований, а затем обрабатывать ее с помощью одноразового индекса растрового изображения. Но полнотекстовые индексы сохраняют сортировку списков документов и выполняют низкозатратное слияние по всем критериям с помощью планировщика FTS, который начинается стратегически с более редкими ключевыми словами. Это все, что они делают, чтобы выполнить «word1 & word2» весь день. Они оптимизированы для такого рода вещей.

Так что, если у вас есть много простых фактов, индекс FTS - это один достойный способ сделать это, я думаю. Я что-то упускаю? Вам просто нужно изменить факты на что-то индексируемое, например COLORID_3, затем искать «COLORID_3 & SOMETHINGELSEID_5».

Если запросы не связаны с слиянием или сортировкой, я подозреваю, что это будет в значительной степени как стирка. Ничего здесь, кроме нас.

+0

Да, это отличный пример того, почему EAV имеет тенденцию быть неэффективным. Вы должны сделать реляционное деление, чтобы подражать тому, что может сделать обычный дизайн таблицы с помощью 'AND'. –

+0

Я думаю, что искатель должен уточнить. Если делать AND, FTS или кортежи лучше. По этой причине MS-SQL реализует разреженные столбцы. Редкие кортежи намного лучше, чем EAV. Он поддерживает горячие col-добавления, а NULL - 1 бит. И есть еще одна проблема. Реляционное деление не может представлять корреляцию. Кортежи делают это хорошо :) Но использование FTS будет самой быстрой реализацией поиска типа с индексом-слиянием, который вы найдете. Выбирайте списки, сортируйте их, если необходимо, выполните сортированное пересечение. EAV-запрос почти никогда не сделает этого, даже если большой-O-подобный FTS. Так почему реляционное деление? FTS, вероятно, лучше. –

+0

По возможности я стараюсь рекомендовать решения, которые будут работать с текущей базой данных OP, не требуя от них массового рефакторинга или переключения на другую технологию. Люди обычно хотят знать, как они могут решить свою проблему сегодня, а не как они могут занять шесть месяцев, чтобы перейти на другую платформу для ее решения. :-) –

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