2013-02-27 2 views
0

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

Просто в качестве примера один из больших таблиц имеет поля, как это:

Userid 
Industryid 
Teamid 
Zoneid 

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

Эта таблица имеет 60 полей, но 16 из них проиндексированы + 1 первичное поле.

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

Что лучший способ использовать индексы в таком большом проекте?

+0

Все четыре поля выглядят так, будто они могут быть иностранными ключами. И четыре комбинированных * могут быть естественным первичным ключом. Я не могу сказать о других 12 индексах, но таблица с 60 полями и 12 индексами выглядит немного подозрительно, по модели данных. – wildplasser

+0

фактически 12 из них являются иностранными ключами и 4 доступны для поиска. поэтому для eaxample у меня есть userid, а также имя пользователя, хотя у меня есть имя пользователя - вторая таблица, называемая use. и я не уверен, что я сделал правильный вызов здесь, но это приведет к 1 внутреннему соединению на такой большой таблице. плюс он сохраняет имя пользователя в истории, даже если имя пользователя было изменено по какой-либо причине. – Jaylen

+0

Наличие одной таблицы с 16 FK является либо нарушением 3NF/BCNF, либо произведением искусства. Денормализация, чтобы избежать (внутреннего) объединения звучит как плохая привычка из прошлого, IMnsHO. – wildplasser

ответ

1

Эта таблица имеет 60 полей, но 16 из них индексируются + 1 первичное поле.

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

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

Если это хорошая идея иметь такую ​​большую таблицу со всеми этими индексами?

Наличие индексов на FK практически всегда является хорошей идеей, поэтому СУБД может поддерживать FK с хорошей производительностью. В частности, всякий раз, когда родительская строка удаляется или обновляется ссылочный ключ, СУБД должен искать дочерние строки. Теоретически, если вы никогда не удаляете/не обновляете родителя, вам также не понадобятся индексы на FK, хотя некоторые СУБД заставляют вас иметь их в любом случае.

Эти индексы могут быть (и обычно) полезны для JOINins, но это действительно зависит от того, как вы JOIN и как способный является планировщик запросов от вас СУБД.

Каков наилучший способ использования индексов в таком большом проекте?

Для каждого исполнения чувствительного запроса, внимательно изучить план выполнения запроса и измерения фактического времени на представительных объемах данных. Просто потому, что запрос выполняется одним способом на маленькой таблице, doesn't mean будет выполняться таким же образом, когда таблица будет расти.

И последнее, но не в последнюю очередь, я горячо рекомендую прочитать Use The Index, Luke!


Каждый раз, когда строка вставляется в таблицу, СУБД должен вставить соответствующий ключ в индексе B-дерева. Когда строка удаляется, ключ удаляется из индекса. Когда индексированное поле обновляется, старый ключ нужно удалить, а новый - вставлен. Чем больше индексов у вас на столе, тем больше времени DBMS придется потратить на это «обслуживание индекса» всякий раз, когда вы INSERT/UPDATE/DELETE строку в этой таблице.

Есть много способов объединения могут быть выполнены: вложенные циклы в различных заказов, слияние объединений, хэш-соединения ... Различные стратегии могут потребоваться различные индексы или даже различные виды индексов (например, B-дерево не будет очень полезно для хэш-соединений). Не все СУБД могут использовать все эти стратегии или использовать существующие индексы во всех случаях, когда они теоретически могут быть использованы. Таким образом, стратегия индексирования, которая хорошо работает для одной СУБД, может не обязательно работать и для другой. И иногда вы можете хранить индексы, но вам нужно «подталкивать» СУБД в правильном направлении, используя «подсказки запросов» или используя синтаксис, «дружественный» к оптимизатору запросов конкретной СУБД, даже хотя эквивалентный, но более понятный для человека синтаксис может существовать. Например, более старые версии MySQL всегда будут выполнять подзапрос IN как внутренний один из вложенных циклов, даже в случаях, когда обратный порядок циклов или объединение слияния будет быстрее. Вот почему люди часто рекомендуют rewriting IN as JOIN под MySQL (хотя я слышал, что они исправили это в MySQL 5.6). OTOH, переписывание IN как JOIN в Oracle не очень полезно, так как Oracle намного лучше выполняет эквивалентные запросы, даже если есть синтаксические различия.

+0

Спасибо вам за хорошую обратную связь. Когда вы говорите, что индексы не являются бесплатными и требуют обслуживания, что именно вы имели в виду? какой тип требует? что вы имеете в виду: «Насколько способна планировщик запросов из вашей СУБД». Спасибо за советы :) – Jaylen

+0

@Mike Я отредактировал ответ - см. Сноски. –

+0

Бранко, большое спасибо за вашу помощь, это сделало меня для меня более понятным :) – Jaylen

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