Как создать индекс на CONCAT ("строка", столбец) в MySQL? - PullRequest
0 голосов
/ 12 января 2019

У меня есть таблица, где id является первичным ключом.

CREATE TABLE t1 (
  id INT NOT NULL AUTO_INCREMENT,
  col1 VARCHAR(45) NULL,
  PRIMARY KEY (id));

У меня есть другая таблица t2, которая присоединяется к таблице t1 как

t2 LEFT JOIN t1 ON CONCAT("USER_", t1.id) = t2.user_id

Я хочу создать индекс, в котором значения CONCAT ("USER_", t1.id) проиндексированы в любом порядке.

Я пытался

ALTER TABLE t1 ADD INDEX ((CONCAT('user_',id) DESC);

но это дает ошибку. Я следовал официальной документации mysql.

Примечание. Я не хочу создавать новый столбец CONCAT ("user_", id).

https://dev.mysql.com/doc/refman/8.0/en/create-index.html#create-index-column-prefixes

1 Ответ

0 голосов
/ 12 января 2019

InnoDB поддерживает вторичные индексы для виртуальных сгенерированных столбцов. https://dev.mysql.com/doc/refman/5.7/en/create-table-secondary-indexes.html

В 5.7 (далее) вы можете использовать сгенерированный столбец, а затем индексировать этот столбец. например,

Вот пример извлечения целого числа из строки для создания эффективного соединения:

CREATE TABLE myusers (
    id mediumint(8) unsigned NOT NULL auto_increment
  , name varchar(255) default NULL,
  PRIMARY KEY (`id`)
) AUTO_INCREMENT=1
;
INSERT INTO myusers (`name`) VALUES ('Imelda'),('Hamish'),('Brandon'),('Amity'),('Jillian'),('Lionel'),('Faith'),('Dai'),('Reed'),('Molly');
CREATE TABLE mytable (
    id mediumint(8) unsigned NOT NULL auto_increment
  , user_id VARCHAR(20)
  , ex_user_id integer GENERATED ALWAYS AS (0+substring(user_id,6,20))
  , password varchar(255)
  , PRIMARY KEY (`id`)
  , INDEX idx_ex_user_id (ex_user_id)
) AUTO_INCREMENT=1
;
INSERT INTO mytable (`user_id`,`password`) VALUES 
 ('user_1','PYX68BIC9RD')
,('user_2','LPY07EIN0UA')
,('user_3','UGC24TKI3JL')
,('user_4','YQU18ALB8YA')
,('user_5','DEL56AGR6AD')
,('user_6','YQN87UOB0PO')
,('user_7','CPC15JFU6MC')
,('user_8','MWC40ZWD2EE')
,('user_9','HEB34QQH0UM')
,('user_10','GVP36PLP5PW')
;
select
*
from myusers
inner join mytable on myusers.id = mytable.ex_user_id
;
id | name    | id | user_id | ex_user_id | password   
-: | :------ | -: | :------ | ---------: | :----------
 1 | Imelda  |  1 | user_1  |          1 | PYX68BIC9RD
 2 | Hamish  |  2 | user_2  |          2 | LPY07EIN0UA
 3 | Brandon |  3 | user_3  |          3 | UGC24TKI3JL
 4 | Amity   |  4 | user_4  |          4 | YQU18ALB8YA
 5 | Jillian |  5 | user_5  |          5 | DEL56AGR6AD
 6 | Lionel  |  6 | user_6  |          6 | YQN87UOB0PO
 7 | Faith   |  7 | user_7  |          7 | CPC15JFU6MC
 8 | Dai     |  8 | user_8  |          8 | MWC40ZWD2EE
 9 | Reed    |  9 | user_9  |          9 | HEB34QQH0UM
10 | Molly   | 10 | user_10 |         10 | GVP36PLP5PW
explain select
*
from myusers
inner join mytable on myusers.id = mytable.ex_user_id
;
id | select_type | table   | partitions | type | possible_keys  | key            | key_len | ref                                    | rows | filtered | Extra      
-: | :---------- | :------ | :--------- | :--- | :------------- | :------------- | :------ | :------------------------------------- | ---: | -------: | :----------
 1 | SIMPLE      | myusers | <em>null</em>       | ALL  | PRIMARY        | <em>null</em>           | <em>null</em>    | <em>null</em>                                   |   10 |   100.00 | <em>null</em>       
 1 | SIMPLE      | mytable | <em>null</em>       | ref  | idx_ex_user_id | idx_ex_user_id | 5       | fiddle_HNTHMETRTFAHHKBIGWZM.myusers.id |    1 |   100.00 | Using where

дБ <> скрипка здесь

note преобразование user_id из строки в целое число является "неявным":

Чтобы привести строку к числу, вам обычно ничего не нужно делать, кроме как использовать строковое значение в числовом контексте: https://dev.mysql.com/doc/refman/5.7/en/create-table-secondary-indexes.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...