С точки зрения производительности, насколько эффективно использовать временную таблицу MySQL для высоко используемой функции веб-сайта?

Я пытаюсь написать функцию поиска для веб-сайта, и я решил использовать временные таблицы MySQL для обработки ввода данных с помощью запроса ниже:

CREATE TEMPORARY TABLE `patternmatch`
  (`pattern` VARCHAR(".strlen($queryLengthHere)."))

INSERT INTO `patternmatch` VALUES ".$someValues

здесь $someValues - это набор данных с макетом ('some', 'search', 'query') - или в основном то, что пользователь искал. Затем я ищу свою главную таблицу images на основе данных в таблице patternmatch вот так:

SELECT images.* FROM images JOIN patternmatch ON (images.name LIKE patternmatch.pattern)

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

мне интересно, сколько накладных расходов требует создание временной таблицы? Я понимаю, что они существуют только в сеансе и удаляются, как только сеанс заканчивается, но если у меня есть сотни тысяч поисков в секунду, с какими проблемами производительности я могу столкнуться? Есть ли лучший способ реализации функции поиска?

3 ответов


то, что вы указали, совершенно правильно, временная таблица будет видна только текущему пользователю/соединению. Тем не менее, есть некоторые накладные расходы и некоторые другие проблемы, такие как:

  • для каждого из тысяч поисков, которые вы собираетесь создать и заполнить эту таблицу (и удалить ее позже) - не для каждого пользователя, для поиска. Поскольку каждый поиск, скорее всего, будет повторно выполнять скрипт, а "за сеанс" не означает сеанс PHP - это означает сеанс базы данных (open соединение.)
  • вам понадобится CREATE TEMPORARY TABLES привилегии, которые вы может нет.
  • тем не менее, эта таблица действительно должна иметь тип памяти, который крадет вашу ОЗУ больше, чем кажется. Потому что даже имея VARCHAR, таблицы памяти используют хранилище строк фиксированной длины.
  • если ваша эвристика позже должна ссылаться на эту таблицу дважды (например,SELECT xyz FROM patternmatch AS pm1, patternmatch AS pm2 ...) - это невозможно с таблицами памяти.

далее, это было бы проще для вас - а также для базы данных-добавить LIKE '%xyz%' непосредственно на images таблицы WHERE предложения. Он будет делать то же самое без накладных расходов на создание временной таблицы и присоединение к ней.

в любом случае - неважно, в какую сторону вы идете-то, где будет ужасно медленно. Даже если вы добавите индекс на images.name вам скорее всего понадобится LIKE '%xyz%' вместо LIKE 'xyz%', так что индекс не привыкать.

Я спрашиваю, является ли временная таблица конкретной сессии для обработки поисковый ввод пользователем (созданный при поиске, отброшенный в конце сеанса) является подходящим способом обработки функции поиска.

нет. :)

альтернативные варианты

MySQL имеет встроенный Полнотекстовый-Поиск (С 5.6 также для InnoDB), что даже может дать вам этот счет: я настоятельно рекомендую дать ему прочитать и попробовать. Вы можете быть уверены, что база данных знает лучше вас, как сделать этот поиск эффективно.

если вы собираетесь использовать MyISAM вместо InnoDB, имейте в виду часто упускаемое ограничение, что полнотекстовые поиски возвращают только что-либо, если количество результатов меньше 50% от общего числа строк таблицы.

другие вещи, которые вы, возможно, захотите посмотреть, например, Solr (хорошее введение, прочитанное на эту тему, будет началом http://en.wikipedia.org/wiki/Apache_Solr). Мы используем его в нашей компании и он делает отличная работа, но она требует некоторого обучения.

резюме

решение вашей текущей проблемы (поиск) заключается в использовании полнотекстовых возможностей.

если у меня сотни тысяч поисков в секунду, какие проблемы с производительностью могут возникнуть? Есть ли лучший способ реализации функции поиска?

чтобы дать вам номер, 10.000 звонков в секунду не является " тривиальным" уже-с сотнями тысяч поисков в секунду проблемы с производительностью, с которыми вы столкнетесь, повсюду в вашей настройке. Вам понадобится пара серверов, балансировка нагрузки и тонны другого удивительного технологического дерьма. И одним из них будет, например, Solr;)


  1. создание временных таблиц на диске относительно дорого. В вашем сценарии это звучит так, как будто это будет медленнее, чем стоит.
  2. обычно стоит только создавать временные таблицы в памяти. Но вы должны знать, что у вас достаточно памяти, доступной в любое время. Если вы планируете поддерживать так много поисков в секунду, это не является хорошим решением.
  3. MySQL есть полнотекстовый поиск встроенный. Это хорошо для небольших систем. Это, вероятно, выполните гораздо лучше, чем ваш temp таблицы и присоединиться. Но если вы хотите поддержать тысячи запросов в секунду я бы не советовал. Это может потреблять слишком много вашей общей производительности базы данных. Кроме того, вы вынуждены использовать MyISAM для хранения, которое может иметь свои собственные проблемы в вашем сценарии.
  4. для стольких поисков вы захотите выгрузить работу в другую систему. Уже существует множество поисковых систем со скорингом. Взгляните на ElasticSearch, Solr / Lucene, Redis, так далее.

из кода, который вы даете, я действительно не думаю, что нужны таблицы tmp, а также полнотекстовый поиск. Но... о производительности таблицы tmp:

создание / очистка таблицы tmp не записывается в журналы транзакций,поэтому ОС будет относительно быстро выполнять ввод-вывод. Если временные таблицы будут маленькими и недолговечными, и у вас есть много буферов, доступных для ОС, диск реально даже не будет затронут. Если вы думаете, что это будет в любом случае, получите SSD драйв, и получить больше ОЗУ.

но если вы реалистичны, что вы смотрите на сотни тысяч запросов в секунду!--7--> тогда у вас есть большой инженерный проект на руках. Почему бы просто не сделать:

select images.* from images where name in ('some', 'search', 'query')

?