Как представления работают в DBM?

Скажем, у меня есть две такие таблицы:

Employers (id, name, .... , deptId).
Depts(id, deptName, ...).

Но эти данные не будут меняться так часто, и я хочу, чтобы такой запрос

SELECT name, deptName FROM Employers, Depts 
    WHERE deptId = Depts.id AND Employers.id = "ID"

будь как можно быстрее.

Мне в голову приходят два возможных решения:

  • Денормализовать таблицу:

    Несмотря на это, с этим решением я потеряю некоторые из больших преимуществ «нормализованных баз данных», но здесь производительность ОБЯЗАТЕЛЬНА.

  • Создайте представление для данных денормализации.

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

Или другой способ задать тот же вопрос: представление «Интерпретируется» каждый раз, когда вы делаете запрос к нему, или как работает материал представлений в администраторах баз данных?

ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
0
1 377
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Как правило, если вы не «материализуете» представление, которое является опцией в некотором программном обеспечении, таком как MS SQL Server, оно просто транслируется в запросы к базовым таблицам и, следовательно, не быстрее и не медленнее, чем исходное (за вычетом незначительного количества время, необходимое для перевода запроса, что ничто по сравнению с фактическим выполнением запроса).

Как узнать, что у вас проблемы с производительностью? Вы профилируете под нагрузкой? Вы проверили, что узким местом производительности являются эти две таблицы? Как правило, пока у вас нет точных данных, не предполагайте, что вы знаете, откуда берутся проблемы с производительностью, и не тратьте время на оптимизацию, пока не узнаете, что оптимизируете правильные вещи - 80% проблем с производительностью возникают из 20 % кода.

Ага. На самом деле я согласен с вами в большинстве случаев. Обычно это не проблема производительности. Но в этом случае это происходит (как вы понимаете, приведенный выше пример не является реальной проблемой). Я ищу способ «материализовать» это представление (как вы говорите), но в Mysql. Любые идеи?

David Santamaria 09.01.2009 17:49

Если Depts.ID является первичным ключом этой таблицы, и вы индексируете поле Employers.DeptID, то этот запрос должен оставаться очень быстрым даже для миллионов записей.

В этом сценарии денормализация для меня не имеет смысла.

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

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

Я не думаю, что вам нужен даже индекс по работодателям.deptId - только по первичным ключам в обеих таблицах. Предложение «where» заставит вас в любом случае использовать сканирование таблицы или первичный индекс на Employers.id; как только это будет сделано, возврат к индексу deptId контрпродуктивен, поэтому он не будет использоваться.

SquareCog 09.01.2009 17:49

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

David Santamaria 09.01.2009 17:53

В комментарии к одному из ответов автор вопроса объясняет, что он ищет способ создать материализованное представление в MySQL.

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

Что вам нужно сделать, так это:

  1. Создайте первоначальную материализацию результата вашего запроса.
  2. Создайте триггер при вставке в таблицу работодателей, который вставляет в материализованную таблицу все строки, соответствующие только что вставленному работодателю.
  3. Создайте триггер на удаление в таблице работодателей, который удаляет соответствующие строки из материализованной таблицы.
  4. Создайте триггер при обновлении в таблице работодателей, который обновляет соответствующие строки в материализованной таблице.
  5. То же самое для таблицы отделов.

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

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

David Santamaria 09.01.2009 18:12

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

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

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

Другие вопросы по теме