Скажем, у меня есть две такие таблицы:
Employers (id, name, .... , deptId). Depts(id, deptName, ...).
Но эти данные не будут меняться так часто, и я хочу, чтобы такой запрос
SELECT name, deptName FROM Employers, Depts
WHERE deptId = Depts.id AND Employers.id = "ID"
будь как можно быстрее.
Мне в голову приходят два возможных решения:
Денормализовать таблицу:
Несмотря на это, с этим решением я потеряю некоторые из больших преимуществ «нормализованных баз данных», но здесь производительность ОБЯЗАТЕЛЬНА.
Создайте представление для данных денормализации.
Я сохраню нормализованные данные и (вот мой вопрос), производительность запроса в этом представлении будет выше, чем без этого представления.
Или другой способ задать тот же вопрос: представление «Интерпретируется» каждый раз, когда вы делаете запрос к нему, или как работает материал представлений в администраторах баз данных?


Как правило, если вы не «материализуете» представление, которое является опцией в некотором программном обеспечении, таком как MS SQL Server, оно просто транслируется в запросы к базовым таблицам и, следовательно, не быстрее и не медленнее, чем исходное (за вычетом незначительного количества время, необходимое для перевода запроса, что ничто по сравнению с фактическим выполнением запроса).
Как узнать, что у вас проблемы с производительностью? Вы профилируете под нагрузкой? Вы проверили, что узким местом производительности являются эти две таблицы? Как правило, пока у вас нет точных данных, не предполагайте, что вы знаете, откуда берутся проблемы с производительностью, и не тратьте время на оптимизацию, пока не узнаете, что оптимизируете правильные вещи - 80% проблем с производительностью возникают из 20 % кода.
Если Depts.ID является первичным ключом этой таблицы, и вы индексируете поле Employers.DeptID, то этот запрос должен оставаться очень быстрым даже для миллионов записей.
В этом сценарии денормализация для меня не имеет смысла.
Вообще говоря, производительность представления будет почти такой же, как и при выполнении самого запроса. Преимущество представления состоит в простом абстрагировании этого запроса, поэтому вам не нужно об этом думать.
Вы можете использовать материализованное представление (или «снимок», как некоторые говорят), но тогда ваши данные будут такими же свежими, как и ваше последнее обновление.
Я не думаю, что вам нужен даже индекс по работодателям.deptId - только по первичным ключам в обеих таблицах. Предложение «where» заставит вас в любом случае использовать сканирование таблицы или первичный индекс на Employers.id; как только это будет сделано, возврат к индексу deptId контрпродуктивен, поэтому он не будет использоваться.
@kogus этот сценарий - всего лишь часть большой проблемы, суть в том, что эти данные будут статическими, поэтому преимущества, которые дает вам нормализация, в этом сценарии на самом деле не нужны. Я хочу, чтобы запрос выполнялся без таблиц соединения (как если бы данные отделов были у работодателей)
В комментарии к одному из ответов автор вопроса объясняет, что он ищет способ создать материализованное представление в MySQL.
MySQL не оборачивает концепцию материализованного представления в приятный для вас пакет, как другие СУБД, но в нем есть все инструменты, необходимые для его создания.
Что вам нужно сделать, так это:
Это может сработать, если ваши базовые таблицы не обновляются часто; но вы должны знать о дополнительных затратах на операции создания / обновления / удаления, как только вы это сделаете. Также вы захотите убедиться, что какой-нибудь администратор баз данных, который не знает о ваших уловках, не перенесет базу данных без миграции триггеров, когда придет время. Так что задокументируйте это хорошо.
Да, это будет хорошее приближение к решению, спасибо за объяснение. Я поддержал ваш ответ (как и другие), и я буду рад отметить его как правильный, но, честно говоря, мой первоначальный вопрос ответ Иэна Варли кажется подходящим (очень сожалею об этом). Большое спасибо.
Похоже на преждевременную оптимизацию, если вы не знаете, что это явная и актуальная проблема.
MySQL не материализует представления, они не быстрее запросов к базовым таблицам. Более того, в некоторых случаях они работают медленнее, поскольку их оптимизируют хуже.
Но представления также «скрывают» вещи от разработчиков, поддерживающих код в будущем, чтобы они вообразили, что запрос менее сложен, чем он есть на самом деле.
Ага. На самом деле я согласен с вами в большинстве случаев. Обычно это не проблема производительности. Но в этом случае это происходит (как вы понимаете, приведенный выше пример не является реальной проблемой). Я ищу способ «материализовать» это представление (как вы говорите), но в Mysql. Любые идеи?