Большие таблицы MySQL - PullRequest
       24

Большие таблицы MySQL

3 голосов
/ 07 декабря 2008

Я работаю над проблемой, которая требует кэширования разбиваемых на страницы результатов поиска: Разбивка очень больших наборов данных

Поиск работает следующим образом: по номеру item_id я нахожу соответствующие item_ids и их ранг.

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

Теперь предположим, что я использую промежуточную таблицу MySQL в качестве своего кэша ... то есть я сохраняю первые 500 результатов для каждого элемента в таблице "совпадений", например, так: "item_id (INTEGER), matched_item_id (INTEGER) , match_rank (REAL) ". Поиск теперь становится чрезвычайно быстрым:

SELECT item.* FROM item, matches 
    WHERE matches.item_id=<item in question>
    AND item.id=matches.matched_item_id 
    ORDER BY match_rank DESC
    LIMIT x,y

У меня не будет проблем с переиндексацией элементов и их совпадений в эту таблицу, поскольку они запрашиваются клиентами, если результаты старше, скажем, 24 часов. Проблема в том, что при хранении 500 результатов для N элементов (где N составляет ~ 100 000-1 000 000) эта таблица становится довольно большой ... 50 000 000 - 500 000 000 строк.

Может ли MySQL справиться с этим? Что я должен высматривать?

Ответы [ 4 ]

4 голосов
/ 07 декабря 2008

MySQL может обрабатывать столько строк, и есть несколько способов масштабирования, когда вы начинаете ударяться о стену. Разделение и репликация являются основными решениями для этого сценария.

Вы также можете проверить дополнительные методы масштабирования для MySQL в вопрос, который я ранее задавал здесь, на stackoverflow.

1 голос
/ 07 декабря 2008

Договорились с выше. Будьте очень осторожны, чтобы избежать преждевременной оптимизации путем денормализации здесь.

Не используйте «SELECT *». Больше полей означает больше операций чтения с диска.

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

Тест, Тестовый Тест.

Если возможно, используйте таблицу только для записи (т.е. без обновлений и без удалений), чтобы mysql не использовал повторно удаленные пробелы и перезаполнял индексы.

Убедитесь, что индексированные поля как можно короче (но не короче).

РЕДАКТИРОВАТЬ: Еще некоторые вещи пришли на ум ...

Стандартные (и самые быстрые) типы таблиц MyISAM не имеют никакого способа поддерживать записи в какой-либо последовательности, кроме порядка вставки (изменяемого путем заполнения удаленных строк), т.е. никаких кластеризованных индексов. Но вы можете подделать его, если периодически копируете / перестраиваете таблицу на основе индекса, который полезен для группировки связанных записей на одной странице. Конечно, новые записи не будут соответствовать, но эффективность таблиц на 98% лучше, чем по умолчанию.

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

Познакомьтесь с информацией в журнале статистики, поскольку она относится к эффективности настроек кеша конфигурации.

Постоянно запускать «медленный журнал запросов». Это низкие накладные расходы, и это первая остановка во всем восстановлении.

Это само собой разумеется, но не запускайте ничего, кроме базы данных на одном сервере. Одна из важных причин - возможность оптимизировать ресурсы только для базы данных.

НЕ денормализовать, пока все не развалится.


Non-переговоров вопросов.

Все, что выше этой строки, является сомнительным советом. Никогда не принимайте никаких советов, не понимая этого и не проверяя его. У каждого дизайнерского решения есть две стороны; и онлайн-совет MySQL хуже, чем в среднем, при обобщениях без квалификации и без учета преимуществ и штрафов. Вопрос все, что я отметил здесь, а также. Понять, что вы делаете, почему вы это делаете и какие преимущества вы ожидаете получить. Измерьте изменения, чтобы увидеть, было ли то, что ожидалось, тем, что произошло.

Никогда, никогда "пробуй что-нибудь посмотреть, что происходит". Это похоже на тюнинг автомобиля с несколькими карбюраторами, только хуже. Если то, что вы ожидали, не произошло, отмените изменение и либо выясните это, либо поработайте над чем-то еще, что вы понимаете. Сон твой друг; большая часть этого придет к вам за одну ночь после трудных сессий тестирования.

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

0 голосов
/ 07 декабря 2008

Как уже говорили другие, MySQL может легко масштабироваться для размещения очень больших наборов данных, и довольно часто он будет обрабатывать большие наборы (несколько миллионов строк) без особого вмешательства разработчика / dba, за исключением небольшого количества разумной индексации и запросов. оптимизация. @ doofledorer правильно, чтобы избежать преждевременной оптимизации. Как говорят парни из 37 Signals, если ваше приложение пользуется успехом на взлетно-посадочной полосе и вы сталкиваетесь с проблемами с базами данных - это отличное место для вас.

Я бы, однако, опроверг этот вопрос одним из моих собственных - вам действительно нужно использовать MySQL в качестве вашей системы кэширования? Есть много мест, где можно хранить список из 500 дюймов, и мой первый выбор будет на стороне сервера в сеансе. Даже если данные сеанса записываются на диск, загрузка этого массива в 500 дюймов не будет такой медленной - и существует множество стратегий использования кэшей в памяти (таких как MemCache), чтобы ускорить это.

Цикл по массиву, сохраненному в сеансе, и выполнение 10, 20 (или любой другой страницы) отдельных запросов по типу «выберите элемент. * Где id = X» может показаться пугающим - конечно, это увеличит физическое число запросов, но это будет быстро, особенно с легким добавлением кэширования запросов MySQL.

Редактировать: Комментарии Сэма высветили то, что я забыл: Если вы используете, скажем, подход, основанный на сеансах, вы сразу получаете выгоду от того факта, что сеанс основан на состоянии. Вам не нужно беспокоиться об удалении данных с истекшим сроком действия - когда сеанс заканчивается, пуф, он уходит. И, если вы придерживаетесь дисковых сессий (я здесь работаю в предположении, что PHP является языком на стороне сервера), то помните, что дисковое пространство невероятно дешево.

В конце концов, это становится компромиссом между простотой использования (с точки зрения разработки / обслуживания), масштабируемостью и производительностью. Я бы просто сказал, что вы должны иметь в виду, что если вы имеете дело с результатами запроса к базе данных, это не означает, что база данных является лучшим способом хранения этих результатов во всех случаях - сохраняйте непредвзятость!

0 голосов
/ 07 декабря 2008

MySQL может справиться с этим. Реальный вопрос: может ли он справиться с этим в разумные сроки? Это зависит от вашего запроса. Как сказал Эран Гальперин в своем ответе, изучите разделение и репликацию для оптимизации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...