用于 concat select 的 MySQL 索引

far*_*ess 5 mysql index optimization index-tuning explain

对于以下查询

SELECT MAX(CONCAT(date, ' ', last_entry)) AS LAST_LOG
    FROM entry_log
    WHERE TRIM(LEADING 0 FROM card_no)='2948'
Run Code Online (Sandbox Code Playgroud)

我已经索引了

date
card_no
date,last_entry
date,last_entry,card_no
Run Code Online (Sandbox Code Playgroud)

我的解释显示

id  select_type     table       type    possible_keys   key             key_len     ref     rows    Extra   
1   SIMPLE          entry_log   index   NULL            date_last_card  158         NULL    103766  Using where; Using index
Run Code Online (Sandbox Code Playgroud)

我的解释扩展节目

id  select_type     table           type    possible_keys   key             key_len     ref     rows    filtered    Extra   
1     SIMPLE        entry_log       index   NULL            date_last_card  158         NULL    103766  100.00      Using where; Using index
Run Code Online (Sandbox Code Playgroud)

我想知道我可以删除/使用哪个索引,我的路径是否正确,我应该如何提高上述查询的执行时间?

CREATE TABLE `entry_log` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `card_no` varchar(50) NOT NULL,
 `date` date NOT NULL,
 `first_entry` time NOT NULL,
 `last_entry` time NOT NULL,
 `all_entry` text NOT NULL,
 `entry_time` datetime NOT NULL,
 `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
 PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=9308 DEFAULT CHARSET=latin1
Run Code Online (Sandbox Code Playgroud)

ype*_*eᵀᴹ 3

假设card_noandlog_entry具有VARCHARCHAR类型,我首先会在 上添加一个索引(card_no, date, last_entry)

ALTER TABLE entry_log
  ADD INDEX card_no__date__last_entry__ix
    (card_no, date, last_entry) ;
Run Code Online (Sandbox Code Playgroud)

然后使用这个查询:

SELECT CONCAT(date, ' ', last_entry) AS LAST_LOG 
FROM entry_log 
WHERE card_no = LPAD('2948', 32, '0')
ORDER BY date DESC, last_entry DESC
LIMIT 1 ;
Run Code Online (Sandbox Code Playgroud)

列表中的值IN应包括类型允许的最大长度的所有长度。上面的例子是针对VARCHAR(8).

更新:由于澄清了该card_no列始终为 32 个字符并用零填充,因此查询条件简化为:
WHERE card_no IN ('2948', '02948', '002948', ..., '000...0002948')to
WHERE card_no = RIGHT(CONCAT('000..00', '2948'), 32)或简单地为
WHERE card_no = LPAD('2948', 32, '0')