Использование MySQL для поиска больших наборов данных? - PullRequest
1 голос
/ 02 августа 2010

Теперь я действительно продвинутый PHP-разработчик и хорошо разбираюсь в небольших наборах MySQL, однако сейчас я создаю большую инфраструктуру для недавно созданного стартапа, и их серверы собирают около 1 миллиона строк данных каждый день, используя их мощную серверную мощность и предыдущую архитектуру.

Мне нужно знать, каков наилучший способ поиска по большим наборам данных (в настоящее время их размер составляет 84,9 миллиона) строк с размером базы данных 394,4 гигабайта. Он размещен на Amazon RDS, поэтому он не имеет времени простоя или медлительности, просто я хочу знать, как лучше всего получить доступ к большим наборам данных внутри.

Например, если я хочу найти в базе данных 84 миллиона строк, мне потребуется 6 минут. Теперь, если я сделаю прямой запрос к определенному идентификатору или названию, он будет обработан немедленно. Итак, как бы я искал через большой набор данных.

Напоминаю, что быстро найти информацию через базу данных, передав одну переменную, но при поиске она выполняется ОЧЕНЬ медленно.

Пример запроса MySQL:

SELECT u.*, COUNT(*) AS user_count, f.* FROM users u LEFT JOIN friends f ON u.user_id=(f.friend_from||f.friend_to) WHERE u.user_name LIKE ('%james%smith%') GROUP BY u.signed_up LIMIT 0, 100

Этот запрос длиной менее 84 миллионов строк значительно медленнее. Конкретно, 47,41 секунды, чтобы выполнить этот запрос автономно, есть идеи, ребята?

Все, что мне нужно, это отсортированный вызов, и я смогу получить дрейф. Кроме того, я знаю, что MySQL не очень хорош для больших наборов данных и чего-то подобного Oracle или MSSQL, однако мне было сказано перестроить его на MySQL, а не на других решениях для баз данных.

Ответы [ 2 ]

2 голосов
/ 02 августа 2010

LIKE ОЧЕНЬ медленный по ряду причин:

  • Если ваше LIKE выражение не начинается с константы, индекс не будет использоваться .

    Например, LIKE ('james%smith%') - это хорошо, LIKE ('%james%smith%') - плохо для индексации.Ваш пример НЕ будет использовать какие-либо индексы в поле "user_name".

  • Сопоставление строк является сложным (алгоритмически) делом по сравнению с обычными операторами.

Чтобы разрешить:

  • Убедитесь, что выражение LIKE начинается с константы, а не с подстановочного знака, если у вас есть индекс в этом поле, который вы могли бы использовать.

  • Подумайте о создании индексной таблицы (в контексте литературы / библиотеки слова «индекс», а не в контексте индекса базы данных), если вы ищете целые слова.Или таблицу поиска подстроки, если вы ищете случайные часто повторяющиеся подстроки.

    Например, если все имена пользователей имеют форму "FN LN" или "LN, FN" - разделите их и сохраните имена и / или фамилии в таблице словаря, присоединяясь к этой таблице (и делаяпрямое равенство) в вашем запросе.

1 голос
/ 02 августа 2010
LIKE ('%james%smith%')

Избегайте таких вещей, как чума. Их невозможно оптимизировать для обычной СУБД.

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

Или, если вы хотите, чтобы все слова в столбце, имели триггер, разбивающий данные на слова, затем располагайте индексную таблицу уровня приложения для поиска соответствующих записей, например:

main_table:
    id integer primary key
    blah blah blah
    text varchar(60)
appl_index:
    id index
    word varchar(20)
    primary key (id,word)
    index (word)

Затем вы можете запросить appl_index, чтобы найти id s, в которых есть james и smith, что гораздо быстрее, чем отвратительный like '%...'. Вы также можете разбить фактические слова на отдельные таблицы и использовать идентификаторы слов, но это дело вкуса - это повлияет на производительность.

У вас вполне могут быть похожие проблемы с f.friend_from||f.friend_to, но я не видел этот синтаксис ранее (если, как кажется, контекст u.user_id может быть одним или другим).

Обычно, если вы хотите, чтобы ваши базы данных масштабировались, не делайте ничего , которое даже выглядит как функция для каждой строки в ваших выборках. Возьмите это от кого-то, кто работает с базами данных мэйнфреймов, где 84 миллиона строк имеют размер наших таблиц конфигурации: -)

И, как и во всех вопросах оптимизации, измерьте, не угадайте!

...