Я могу ожидать увеличение производительности от удаления этого СОЕДИНЕНИЯ?

У меня есть таблица "объектов" с 1 миллионом строк и "пользовательская" таблица с 20 000 строк. Когда я выбираю из таблицы "объектов", я делаю соединение на "пользовательской" таблице (объекты user_id = user.id), так, чтобы я мог захватить "имя пользователя" от пользовательской таблицы.

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

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

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

Запрос в качестве примера с соединением:
ВЫБРАТЬ Item.id, Item.submitter_id, Item.source_image, Item.cached_image, Item.source_title, Item.source_url, Item.width, Item.height, Item.status, Item.popular, Item.made_popular, Item.fave_count, Item.tags, Item.user_art, Item.nudity, Item.created, Item.modified, Item.removed, Item.nofront, Item.test, Item.recs, Item.recs_data, User.id, User.username, User.password, User.email, User.fullname, User.profileurl, User.homepage, User.bio, User.location, User.avatar, User.ff_user, User.ff_key, User.ff_last_faveid, User.twitter_user, User.twitter_pass, User.emailalerts, User.showunsafe, User.view, User.fb_uid, User.fb_session, User.fb_avatar, User.twitter_uid, User.twitter_data, User.twitter_autopost, User.uri, User.created, User.modified ОТ items AS Item ОСТАВЛЕННОЕ СОЕДИНЕНИЕ users AS User НА (Item.submitter_id = User.id) ГДЕ Item.nofront ! = 1 И Item.removed ! = 1 И Item.made_popular не является ПУСТЫМ И нагота! = 1 ORDER BY Item.made_popular ПРЕДЕЛ DESC 1040, 290;

Запрос в качестве примера без соединения:
ВЫБРАТЬ Item.id, Item.submitter_id, Item.source_image, Item.cached_image, Item.source_title, Item.source_url, Item.width, Item.height, Item.status, Item.popular, Item.made_popular, Item.fave_count, Item.tags, Item.user_art, Item.nudity, Item.created, Item.modified, Item.removed, Item.nofront, Item.test, Item.recs, Item.recs_data ОТ items AS Item ГДЕ Item.nofront ! = 1 И Item.removed ! = 1 И Item.made_popular не является ПУСТЫМ И нагота! = 1 ORDER BY Item.made_popular ПРЕДЕЛ DESC 1040, 290;

5
задан makeee 8 April 2010 в 03:58
поделиться

5 ответов

Правильный ответ - измерить его в целевой среде , чтобы увидеть, имеет ли это значение. Затем проведите анализ затрат и выгод, чтобы понять, стоит ли оно того.

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

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

В любом случае дублирование столбца можно довольно легко контролировать в приличной СУБД с помощью триггеров. Под этим я имею в виду размещение триггера вставки / обновления в таблице пользователей, чтобы, если пользователь изменяет свое имя пользователя, оно также изменялось в таблице элементов (и, возможно, наоборот).

Я не могу комментировать, соответствует ли MySQL моему определению достойной СУБД - я сам являюсь специалистом по DB2. Но возврат из третьей нормальной формы - это испытанный и проверенный метод выжать все до последней капли производительности из баз данных и, если вы понимаете последствия, вполне приемлем. Очень немногие люди жалуются на то, что их базы данных занимают слишком много места на диске. Многие жалуются на то, как медленно выполняются их запросы.

Просто имейте в виду, что реверсия - это то, что вы делаете , если и когда у вас есть проблемы с производительностью. Это не то, что следует делать только потому, что вы думаете, что это может снизить нагрузку.Если нагрузка (или затраченное время) на самом деле не является проблемой, часть выгоды вашего анализа затрат / выгод равна нулю, поэтому любой разумный счетчик bean скажет вам, что это означает «без изменений».


Основываясь на ваших добавленных вопросах, у меня есть пара замечаний:

  • Во-первых, столбец нагота . Скажите, пожалуйста, как мне получить доступ к этой базе данных: -)
  • Вы должны только извлечь нужные столбцы. Если имя пользователя - это все, что вам нужно из таблицы User , вы не должны получать все эти лишние данные в первом запросе. Возможно, то же самое и с предметом Item - получите только то, что вам нужно.
  • Убедитесь, что у вас есть индексы для всех столбцов, используемых в предложениях WHERE - это также может повлечь за собой комбинированные индексы (с несколькими столбцами). То, что будет индексироваться, зависит от ваших запросов, но каждый столбец, используемый в предложениях WHERE , является хорошим началом для анализа.
  • Для больших таблиц вы можете рассмотреть возможность «выметания» удаленных элементов периодически в отдельную таблицу (например, RemovedItems ), чтобы минимизировать размер элементов и ускорить запросы. Но имейте в виду, что это полезно только в том случае, если вам редко нужно искать ромовированные элементы, поскольку это усложнит эти запросы (заставляя их искать в двух таблицах вместо одной). Опять же, это вопрос затрат и выгод. Один миллион строк - это не такая уж большая таблица (по крайней мере, в моем мире).
5
ответ дан 14 December 2019 в 13:31
поделиться

Вы увидите значительное увеличение производительности только в том случае, если вам не хватало индекса для items.user_id или user.id , или если вы используете дрянную базу данных. В противном случае производительность существенно не улучшится.

0
ответ дан 14 December 2019 в 13:31
поделиться

JOINS всегда занимают больше ресурсов, чем простые операторы SELECT. Так что да, удаление JOIN должно повысить производительность.

0
ответ дан 14 December 2019 в 13:31
поделиться

У меня есть таблица "items" с 1 миллионом строк и таблица "users" с 20 000 строк.

То есть, независимо от того, JOIN или денормализация, вы все равно передадите по проводам примерно 1M/20k = в 50 раз больше пользовательской информации, чем это строго необходимо. Кодирование, передача и последующее декодирование данных увеличивают нагрузку.

Я рассматриваю возможность добавления столбца имени пользователя в таблицу items и удаления объединения.

Зачем вы тогда в своем оригинальном JOIN передаете всю эту другую (потенциально объемную) информацию (такую как User.profileurl, User.homepage и т.д.), если вам нужно только имя пользователя? Помните, что для столбцов User вы передаете в среднем 50 копий каждого бита информации. Не рассматривали ли вы возможность радикально сократить столбцы, из которых вы ВЫБИРАЕТЕ в JOIN (как из User, так и из Item таблиц?)

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

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

На втором этапе позвольте мне начать с собственного вопроса: действительно ли вам нужен весь миллион строк за один раз? Если нет, например, если вы ориентируетесь на пользовательский интерфейс и разбиваете их на страницы (используя OFFSET ... LIMIT ... ), то вас не обязательно будет заботить 50-кратное User дублирование информации (если только LIMIT не достигает десятков тысяч. В противном случае вы можете захотеть измерить преимущество устранения 50-кратного дублирования, сначала ВЫБРАВвписав только User.id и User. username в память приложения (20k пар, в хэш-таблицу/карту), затем SELECTing only Item rows (1M итераций), каждый раз разрешая на уровне приложения Item.user_id по хэш-таблице/карте.

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

0
ответ дан 14 December 2019 в 13:31
поделиться

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

1
ответ дан 14 December 2019 в 13:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: