В SQL у вас может быть только один PRIMARY KEY
на таблицу.
KEY(foo)
- поддельный синтаксис в стандартном SQL.В MySQL KEY foo
является плохо названным синонимом для INDEX foo
и не накладывает УНИКАЛЬНОЕ ограничение.(Он плохо назван, потому что на самом деле он не относится к функционированию ключа.)
Может быть несколько UNIQUE INDICES
, которые могут играть роль «ключей-кандидатов».(Уникальное ограничение может быть указано без ассоциированного индекса, но точка «ключа», как правило, представляет собой быстрый просмотр .) Точка PRIMARY KEY
заключается в уникальной идентификацииотдельная запись и почти исключительно поддерживается индексами и может даже иметь прямое отношение к кластеризации данных.
Только минимальный объем [уникальных] ИНДИКСОВ, необходимый для , обеспечивает достоверность данных и соответствуют требованиям к производительности * Следует использовать 1020 * - они налагают штрафы на производительность для механизма запросов, а также требуют дополнительных затрат на обновление и обслуживание.
Неуникально INDEX's(INDEX foo
, или в случае MySQL, KEY foo
) исключительно для того, чтобы база данных могла оптимизировать запросы.Они на самом деле не отображаются на "ключи" и могут называться "индексами покрытия";если они выбраны планировщиком запросов, эти индексы могут повысить производительность, даже если они ничего не добавляют к самой логической модели.(По соображениям производительности ядро базы данных может потребовать, чтобы FOREIGN KEYS были покрыты индексами.)
В этом случае создание INDEX ( не думайте «KEY»! ) для user_id
обычно (значительно) ускоряет запросы с такими предложениями, как:
... WHERE user_id = {somenumber}
Без индекса вышеупомянутый запрос потребует полного сканирования таблицы (например, чтение всех записей).
ПокаЯ не знаю, почему transaction_id
не является индексом, это может не потребоваться (или даже вредно для данных шаблонов доступа ) - рассмотрим случай, когда каждый запрашивает, чтодолжен быть быстрым:
- Не использует
transaction_id
или; - Также имеет
user_id = ...
или другое ограничение, которое может использовать INDEX.Таким образом, в случае, подобном WHERE user_id = ... AND transaction_id = ...
, планировщик запросов , вероятно, сначала найдет записи для соответствующего пользователя , а затем ищет соответствующий transaction_id
- он все еще долженсделать сканирование, но только на гораздо меньший набор данных , чем исходная таблица.Только простой WHERE transaction_id = ...
обязательно потребует ПОЛНОГО СКАНИРОВАНИЯ.
В случае сомнений используйте EXPLAIN - или другой анализатор запросов - ипосмотрите, что MySQL думает , что он должен делать.И последнее замечание: иногда оценочные планы выполнения запросов могут отличаться от фактических планов выполнения, и устаревшая статистика может заставить планировщика запросов выбирать неидеальный план.
Счастливое кодирование.