关于cast类型转换后无法使用索引的优化

关于cast类型转换后无法使用索引的优化

因为表设计时是各开发人员建立的表,同是建立日期字段add_time,有int,还有varchar(50)几种数据类型,如下:
(字段有删减)

mys

ql> show create table credit_tender;
+--------------------------+------------------------
| Table                    | Create Table                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
+--------------------------+------------------------
| credit_tender | CREATE TABLE `credit_tender` (
  `assign_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL DEFAULT '0' COMMENT '用户名称',
  `credit_user_id` int(11) DEFAULT NULL COMMENT '出让人id',
  `status` int(2) DEFAULT '0' COMMENT '状态',
  `add_time` varchar(50) DEFAULT NULL COMMENT '添加时间',
  `addip` varchar(50) DEFAULT NULL COMMENT 'ip',
  `client` int(11) DEFAULT NULL COMMENT '客户端',
  PRIMARY KEY (`assign_id`),
  KEY `user_id` (`user_id`),
  KEY `idx_add_time` (`add_time`)
) ENGINE=InnoDB AUTO_INCREMENT=20152 DEFAULT CHARSET=utf8 COMMENT='债权投资表' |

可以看到字段
add_time varchar(50) DEFAULT NULL COMMENT ‘添加时间’,
有索引:
KEY idx_add_time (add_time)

但现在的查询,所有都是使用了以下查询

SELECT * FROM borrow_tender t
WHERE   FROM_UNIXTIME(t.addtime,'%Y-%m-%d %H:%i:%s') >= '2018-03-19 00:00:00'
AND FROM_UNIXTIME(t.addtime,'%Y-%m-%d %H:%i:%s') <= '2018-03-19 23:59:59'

查看执行计划如下:
可以看到,有索引,但并没有走索引,还是全表搜索(type:ALL),

mysql> explain SELECT * FROM borrow_tender t
    WHERE   FROM_UNIXTIME(t.addtime,'%Y-%m-%d %H:%i:%s') >= '2018-03-19 00:00:00'
    AND FROM_UNIXTIME(t.addtime,'%Y-%m-%d %H:%i:%s') <= '2018-03-19 23:59:59';
+----+-------------+--------+------+---------------+------+---------+------+--------+-------------+
| id | select_type | table  | type | possible_keys | key  | key_len | ref  | rows   | Extra       |
+----+-------------+--------+------+---------------+------+---------+------+--------+-------------+
|  1 | SIMPLE      | tender | ALL  | NULL          | NULL | NULL    | NULL | 664731 | Using where |
+----+-------------+--------+------+---------------+------+---------+------+--------+-------------+
1 row in set

mysql> 

还看到这个表有以下查询条件的,相对于上面的查询,稍有思考,知道转换成相同数据类型进行对比查询:

mysql> explain 
SELECT  user_id,status,add_time
from credit_tender t 
WHERE  t.add_time  >= cast(unix_timestamp('2018-03-19 00:00:00') as CHAR)
AND  t.add_time <= cast(unix_timestamp('2018-03-19 23:59:59')  as CHAR);
+----+-------------+-------+------+---------------+------+---------+------+-------+-------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows  | Extra       |
+----+-------------+-------+------+---------------+------+---------+------+-------+-------------+
|  1 | SIMPLE      | hct   | ALL  | NULL          | NULL | NULL    | NULL | 14287 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+-------+-------------+
1 row in set

但我们看到,还是没走索引,为什么?
cast(unix_timestamp(‘2018-03-19 00:00:00’) as CHAR) 已转换成字串了呀,为什么。
这里是因为char 是定长,而我们的字段类型为 varchar()
所以,这里只要使用以下函数即可
cast(unix_timestamp(‘2018-03-19 00:00:00’) as NCHAR)

mysql> explain 
SELECT  user_id,status,add_time
from credit_tender hct 
WHERE  hct.add_time  >= cast(unix_timestamp('2018-03-19 00:00:00') as NCHAR)
AND  hct.add_time <= cast(unix_timestamp('2018-03-19 23:59:59')  as NCHAR);
+----+-------------+-------+-------+---------------+--------------+---------+------+------+-----------------------+
| id | select_type | table | type  | possible_keys | key          | key_len | ref  | rows | Extra                 |
+----+-------------+-------+-------+---------------+--------------+---------+------+------+-----------------------+
|  1 | SIMPLE      | hct   | range | idx_add_time  | idx_add_time | 153     | NULL |   45 | Using index condition |
+----+-------------+-------+-------+---------------+--------------+---------+------+------+-----------------------+
1 row in set

或者使用 CONCAT 函数,隐性转换成字串的方法

mysql> explain 
SELECT  user_id,status,add_time
from credit_tender hct 
WHERE  hct.add_time  >= CONCAT(unix_timestamp('2018-03-19 00:00:00'),'')
AND  hct.add_time <= CONCAT(unix_timestamp('2018-03-19 23:59:59')  ,'')
;
+----+-------------+-------+-------+---------------+--------------+---------+------+------+-----------------------+
| id | select_type | table | type  | possible_keys | key          | key_len | ref  | rows | Extra                 |
+----+-------------+-------+-------+---------------+--------------+---------+------+------+-----------------------+
|  1 | SIMPLE      | hct   | range | idx_add_time  | idx_add_time | 153     | NULL |   45 | Using index condition |
+----+-------------+-------+-------+---------------+--------------+---------+------+------+-----------------------+
1 row in set

mysql> 
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值