Как индексировать таблицу для разных предложений с одним столбцом - PullRequest
0 голосов
/ 24 октября 2018

У меня есть следующая таблица:

CREATE TABLE Test (
  device varchar(12),
  pin varchar(4),
  authToken varchar(32),
  Primary Key (device)
);

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

SELECT * FROM Test WHERE device = ?;
SELECT * FROM Test WHERE authToken = ?;
SELECT * FROM Test WHERE pin = ?;

Как я понимаю, в этом сценарии комбинированный индекс (device, authToken, pin) не имеет смысла, поскольку это ускорит только первый запрос, а не второй или третий..

Скорость чтения более важна, чем запись для этой таблицы, поэтому было бы оптимальным решением просто индексировать каждый столбец отдельно?

Ответы [ 4 ]

0 голосов
/ 24 октября 2018

Простой ответ - создать отдельные индексы из одного столбца для каждого запроса:

create index ix1 (device); -- no need to create it since it's the PK.
create index ix2 (pin);
create index ix3 (authToken);

Первый индекс (из PK) использует первичный индекс.Второй и третий могут быть медленнее, поскольку они страдают от медлительности «вторичного индекса»: им всегда нужно сначала получить доступ к вторичному индексу, а затем получить доступ к первичному индексу;это может стать медленным, если вы выбираете большое количество строк.

Теперь, если вы хотите перебраться с точки зрения скорости SELECT за счет медлительности модификаций (INSERT, UPDATEи DELETE), вы можете использовать «покрывающие индексы» с учетом каждого запроса.Они должны выглядеть следующим образом:

create index ix4 (device, pin, authToken); -- [non needed] optimal for WHERE device = ?
create index ix5 (authToken, device, pin); -- optimal for WHERE authToken = ?
create index ix6 (pin, device, authToken); -- optimal for WHERE pin = ?

Примечание : Как указано Риком Джеймсом, ix4 избыточен с индексом первичного ключа, который имеют таблицы InnoDB.Там нет необходимости создавать его.Он приведен здесь только для полноты.

Эти "покрывающие индексы" используют только вторичные индексы, разрешая запрос без необходимости доступа к первичному индексу вообще.Они намного быстрее для большого количества извлеченных строк.

0 голосов
/ 24 октября 2018

Вам не нужно индексировать столбец булавки, так как он уже проиндексирован.Для других двух столбцов (например, device и authToken), да, в соответствии с вашими общими запросами, лучше хранить их оба индексируемыми по отдельности.

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

0 голосов
/ 24 октября 2018

Вот схема, которую я бы предложил:

CREATE TABLE Test (
  id SERIAL PRIMARY KEY,
  device VARCHAR(255),
  pin VARCHAR(255),
  authToken VARCHAR(255),
  UNIQUE KEY index_authToken (authToken),
  UNIQUE KEY index_device (device),
  KEY index_pin (pin)
);

Если у вас есть столбец типа id, который не связан с какими-либо конкретными данными, и у вас есть ограничения UNIQUE для authToken и device.

Не забывайте индексировать любой столбец, используемый в WHERE, и проверяйте свое покрытие с помощью таких вещей, как:

EXPLAIN SELECT ... FROM Test WHERE pin=?

Если вы видите «сканирование таблицы» в плане, то этопроблема с отсутствующими индексами.

Также рекомендуется использовать VARCHAR(255) по умолчанию, если у вас нет веских причин для его ограничения.Внедрите ограничения длины на вашем прикладном уровне, где они могут быть легко ослаблены позже.Например, изменение 6-значного ПИН-кода против 4-го - это простое изменение кода, и его можно развертывать поэтапно, а не изменение схемы.

0 голосов
/ 24 октября 2018

Ответить:

"Как индексировать таблицу для разных предложений из одного столбца?"

CREATE INDEX Test_device_index ON Test(device);
CREATE INDEX Test_authToken_index ON Test(authToken DESC);
CREATE INDEX Test_pin_index ON Test(pin);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...