2011-04-07 3 views
2

У меня есть таблица пользователей с 17 полями и таблица пользовательских данных с 40 полями, и оба связаны с использованием user_id, который является первичным ключом таблицы пользователя. Они не каскадированы. Обе эти таблицы будут иметь ряды до 400 000 до 500 000 В моем программном обеспечении большую часть времени мне понадобится присоединиться к этим двум таблицам для создания выходов.Какой запрос будет быстрее

Мой вопрос, будет ли мой пробег запрос быстрее, если я удалить таблицу данные пользователя и поставить его поля в таблице пользователей itself.so, что я могу получить результаты с помощью отказа присоединиться запросов

Какой из них лучше 1) все поля в одной таблице ИЛИ 2) два таблиц и с помощью запросов присоединиться к

+1

Какие технологии баз данных вы используете? – Ilan

+0

Каков типовой размер запроса? то есть несколько пользователей или 100 000 пользователей. Вы извлекаете все поля из нескольких? – Euclid

+0

MySQL с MyISAM, пользовательская таблица постоянно растет с каждым днем ​​и может достигать 400 000 - 500 000 в течение одного года. Обычно она состоит из более 900 пользователей. – zamil

ответ

3

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

Доступ к таблице с полями фиксированной длины выполняется быстрее, чем использование строк динамической длины.

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

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

+0

. Не хранятся поля 'TEXT' и' BLOB', только указатель (фиксированный размер), хранящийся в строке таблицы? – Piskvor

+0

@Piskvor Я не знаю такого механизма хранения или 'ROW_FORMAT', который делает это, но мне интересно, если вы нашли некоторые ссылки. – vbence

+1

@Piskvor Это зависит от многого. Ответ может быть сложным. См. Http://www.mysqlperformanceblog.com/2010/02/09/blob-storage-in-innodb/ для InnoDB, MyISAM снова отличается. – Isotopp

0

Лучше всего поместить все данные в одну таблицу. Кроме того, вы работаете против правил нормализации БД. И почему вы разделили данные об одном пользователе в 2 таблицах? Просто ограничьте результаты SELECT, не используя wildcard selectorr как *, но запишите список с запрошенными полями.

+0

Эффективность или реальные требования, возможно?Одна таблица может быть псевдонимными идентификаторами для внутреннего использования систем, тогда как таблица подробностей может быть данными, что а) требуется сравнительно реже (вам не нужен почтовый адрес пользователя или знак № 19746 пользователя, чтобы узнать, разрешен ли ему доступ к ресурсу # 0xdeadbeef, также идентификаторы обычно являются целыми числами, которые гораздо быстрее обрабатываются, чем VARCHAR или TEXT - ширина и состав таблицы имеют реальное влияние на скорость) или b) данные, которые не должны быть доступны для всех процессов (HIPAA приходит на ум) , – Piskvor

+0

Я согласен с этим, но эта ситуация часто не случается. Я все же предпочитаю хранить все в одной таблице, если я действительно не увижу преимущества разделения данных в других таблицах. Он может использовать представления, если хочет ограничить видимые данные для определенных пользователей или разделов приложения. Есть много случаев для пользователей, я говорил о наиболее распространенных случаях, потому что он не упоминал каких-либо специальных требований. –

+1

Что касается нормализации, * это * укусит вас, как только у вашего клиента будет почтовый адрес, адрес фактурирования и адрес доставки (наиболее распространенный пример). Нормализованный подход там определенно не «набивает всех в одну строку в таблице». – Piskvor

6

Я не пытаюсь быть смартфоном, но единственным разумным ответом является «попробуй его и измерить для себя».

Вы видите, слишком много неизвестных переменных в вашем вопросе: двигатель

  • таблиц (s) (MyISAM, InnoDB, ...)
  • дополнительные WHERE условия, если таковые имеются
  • дополнительные JOIN s, если они есть
  • Структура таблицы («40 полей» - это что-то совсем другое, если они все INT или CHAR или TEXT или VARCHAR или какая-то комбинация).
  • существующих индексы
  • соотношений чтения/записи на столе (ы), и связанные с этим шумиху (то есть блокировки модель используется)
  • и Gazillion других вещей

Try для запуска запросов/запросов с EXPLAIN; план запроса даст вам гораздо более конкретные данные, чем мы могли бы предоставить.

+0

+1 для EXPLAIN, она предоставляет много полезной информации - хотя вы, вероятно, захотите прочитайте документы, чтобы понять, что все это значит. – pwaring

+0

Где будет присутствовать 3-4 поля, кроме этого еще одно соединение будет preent, движок - myisam, почти 85% полей - varchar, каждый талбе имеет только один первичный ключ и внешние ключи – zamil

0

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

Можете ли вы генерировать случайные записи пользователей через скрипт?Если это так, вы можете просто создать 500 000 записей, используя обе схемы (все в одной таблице и две таблицы с объединением) и посмотрите, какая из них самая быстрая. Может быть, разница настолько мала, что нет смысла сливать таблицы.

+0

С акцентом на "относительно". Таблица с 57 колонками с записями 0.5M, вероятно, будет чем угодно, но быстро, особенно. если задействованы строки. «Соединять все ко всему» действительно медленно, но «удаление соединений ускоряет работу» - это чрезмерное обобщение. Как вы правильно заметили, он * может * или * не может *. – Piskvor

+0

«Это происходит за счет нормализации». Это происходит за счет количества искусственных идентификаторов. Хранение натурального ключа вместо искусственного идентификационного номера может исключить объединение без какого-либо влияния на нормализацию. Тем не менее, это может ускорить процесс. –

2

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

Твердые результаты можно получить только путем бенчмаркинга.

Я могу внести полезный анекдот. В другом задании у нас была пользовательская база данных, которая содержала все данные для одного пользователя в одной строке. Данные пользователя составляли около 1-2K на пользователя, в общей сложности, и у нас было 25 миллионов записей пользователей.

База данных считывает и записывает данные на страницах по 8K каждый (MySQL InnoDB будет 16K страниц, кстати). Это означает, что у нас около 4-6 записей пользователей на странице базы данных и около 5 миллионов страниц данных.

В записи пользователя содержатся поля, в которых хранится время последнего входа пользователей. Между 7 и 9 утрами мы увидим около 8 миллионов уникальных пользователей, которые будут регистрироваться, поэтому нам будет около 8 миллионов страниц, загрязненных и нуждающихся в обратной записи. По существу, каждый день мы возвращаем всю пользовательскую таблицу на диск дважды или трижды.

Мы ввели искусственную связь 1: 1, которая напоминает страницы пользователя и user_details: у нас был пользователь и таблица user_lastlogin. Записи user_lastlogin были очень узкими, состоящими, по существу, только из идентификатора пользователя и (трех разных) последних дней входа пользователя (в зависимости от используемого сервиса). Поскольку user_lastlogin очень узкий, теперь у нас почти тысяча записей на странице и всего 25 000 страниц в таблице. Имея 8 миллионов уникальных логинов, нам теперь нужно записать намного меньше данных (поскольку контрольные точки и обратные записи в базе данных задерживаются). Нагрузка на дисковый ввод-вывод снижалась на порядок.

Извлеченный урок: может быть очень полезно отделить статические данные от изменчивых данных (мы рассмотрели статические данные пароля, так как у нас было около 15 000 изменений пароля в день, тогда как у нас было 8 миллионов обновлений last_login в день).

+0

+1 для истории войны – Ronnis

+1

спасибо, это полезно – zamil

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