упорядоченное расположение ключей в составном индексе MySQL (полиморфные ассоциации WRT Rails и STI) - PullRequest
7 голосов
/ 09 февраля 2011

Ранее я задавал этот вопрос о составных индексах для полиморфных внешних ключей в ActiveRecord . Основой моего вопроса было моё понимание того, что индексы должны основываться на мощности вашего столбца, и, как правило, количество элементов в Rails для STI-типов и полиморфных _-типов довольно низкое.

Признание того, что ответ на мой вопрос правильный - это то, что имеет смысл индексировать столбцы как с высокой кардинальностью _id, так и с типом колонки с низкой кардинальностью, потому что вместе они имеют большую кардинальность - мой следующий вопрос: как вам следует заказать ваши составные индексы?

Индекс [owner_id, owner_type] размещает поле с более высоким количеством элементов первым, а [owner_type, owner_id] размещает поле с более высоким количеством элементов вторым. Является ли запрос, использующий первый ключ, более производительным, чем запрос, использующий второй ключ, или они одинаково производительны?

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

Ответы [ 2 ]

5 голосов
/ 13 февраля 2011

Из моего собственного исследования (но я не эксперт DBA) я узнал, что есть две вещи, которые следует учитывать при определении порядка составного индекса ключа.

Во-первых, относительно количества столбцов,Индекс вообще лучше при поиске столбцов с высокой кардинальностью.Поэтому я был бы склонен поместить столбец с наибольшим количеством элементов первым в индексе.Для справки есть статья под названием MySQL Query Optimization , в которой говорится:

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

В вашем случае столбцы _id явно бы лучше соответствовали этому определению, поэтому они являются лучшим кандидатом на префиксkey.

Еще одна вещь, которую следует учитывать, - это возможность многократного использования этих индексов.Большинство (если не все) систем баз данных допускают повторное использование префикса составного ключа.Например, составной ключ на (owner_id, owner_type) может также использоваться запросами на owner_id, но не на owner_type.

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

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

Обновление : Там также есть еще один довольно популярный вопрос SO об индексе составного ключа:

Когда я должен использовать составной индекс?

2 голосов
/ 18 октября 2016

TL; DR Сначала укажите тип, затем идентификатор.

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

С другой стороны, [type, id], даст индекс верхнего уровня, который можно использовать повторно при поиске только по типу.Второе решение всегда будет соответствовать одной строке, так как идентификатор уникален по типу, поэтому вы все равно уверены, что сканирование строк после разрешения индекса не выполняется.

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

...