iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >varchar int 查询 到底什么情况下走索引?
  • 862
分享到

varchar int 查询 到底什么情况下走索引?

varcharint查询到底什么情况下走索引? 2015-12-17 14:12:51 862人浏览 绘本
摘要

  一个字符类型的、一个int类型的,查询的时候到底会不会走索引,其实很多工作了几年的开发人员有时也会晕,下面就用具体事例来测试一下。 1.  准备工作 先准备2张表,以备后续测试使用。 表1:创建表test1,总共3列,其中id

varchar  int 查询 到底什么情况下走索引?

 

一个字符类型的、一个int类型的,查询的时候到底会不会走索引,其实很多工作了几年的开发人员有时也会晕,下面就用具体事例来测试一下。

1.  准备工作

先准备2张表,以备后续测试使用。

表1:创建表test1,总共3列,其中id 是主键(int),c_no 为int型,且有索引,c_2为普通字段


create table  test1(id int primary key,c_no  int ,c_2 varchar(1),key c_no(c_no));


insert  into test1 values(1,1,"0"),(2,2,"1"),(3,4,"1"),(4,6,"0"),(5,7,""1),(6,11,"2"),(7,5,"3"),(8,100,"0"),(9,30,"1"),(10,50,"0");

表2: 创建表test1,总共3列,其中id 是主键(int),c_no 为字符型,且有索引,c_2为普通字段


create table  test2(id int primary key  auto_increment,c_no  varchar(11) ,c2 varchar(2),key c_no(c_no));


 insert  into test2 values(1,"5","1"),(4,"100","0"),(3,"30","1"),(10,"500","0"),(11,"20","0"),(12,"20a","0"),(15,"020b","1");

两张表的差异是c_no的字段类型不同。

 

2.    等值查询测试

2.1  测试test1

test1.c_no字段为int类型,下面分别用整型和字符串进行比较,查看是否走索引。对应的执行计划如下:

Mysql> explain  select *  from test1 where c_no="100";
+----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref   | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | test1 | NULL       | ref  | c_no          | c_no | 5       | const |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

mysql> explain  select *  from test1 where c_no=100;
+----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref   | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | test1 | NULL       | ref  | c_no          | c_no | 5       | const |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

可见,两种方式均走索引了,且走的是c_no的索引,类型为ref为const(常量的等值查询),扫行数为1

也就是说当表中的字段类型为整型时,无论查询用字符串类型的数字还是int类型的数字均能走索引。其中用int类型的值查询能走索引可以容易理解,那么,字符型的为什么能走? 其实这里的字符类型做了隐式转化,上例中就相当于

mysql> explain  select *  from test1 where c_no=CAST("100" as UNSIGNED);
+----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref   | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | test1 | NULL       | ref  | c_no          | c_no | 5       | const |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

 

2.2  测试 test2 表

以同样的方式测试一下test2的查询情况

先测试正常情况下字符型与字符型比较,结果可想而知,可以走索引,如下:

mysql> explain  select *  from test2 where c_no="100";
+----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref   | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | test2 | NULL       | ref  | c_no          | c_no | 47      | const |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

而,如果是整型再查呢?结果如下(很遗憾,不能走索引了)

mysql> explain  select *  from test2 where c_no=100;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | test2 | NULL       | ALL  | c_no          | NULL | NULL    | NULL |    7 |    14.29 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 3 warnings (0.00 sec)

也就是说,表中字段为字符类型的时候,查询的值为整型时,无法走索引了

那这句相当于如下情况:

mysql> explain  select *  from test2 where cast(c_no  as  unsigned)=100;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | test2 | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    7 |   100.00 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

也就是c_no做了隐式转化。因为如果是100做了影视转化,那么结果应该是可以走索引,例如:

mysql> explain  select *  from test2 where c_no=cast(100 as char);
+----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref   | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | test2 | NULL       | ref  | c_no          | c_no | 47      | const |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

由此,我们也应证了如果字段做了函数计算后,该列上即使有索引也无法使用(MySQL8.0之前的版本)。

2.3  进一步测试

其实针对test2表 还可以测试一点,进一步证明是c_no字段做了隐式转化,例如:

mysql> select  * from test2 where c_no=20;
+----+------+------+
| id | c_no | c2   |
+----+------+------+
| 11 | 20   | 0    |
| 12 | 20a  | 0    |
| 15 | 020b | 1    |
+----+------+------+
3 rows in set, 2 warnings (0.00 sec)

另外,看到了2个警告,内容如下:

mysql> show warnings;
+---------+------+------------------------------------------+
| Level   | Code | Message                                  |
+---------+------+------------------------------------------+
| Warning | 1292 | Truncated incorrect DOUBLE value: "20a"  |
| Warning | 1292 | Truncated incorrect DOUBLE value: "020b" |
+---------+------+------------------------------------------+
2 rows in set (0.00 sec)

更加证明了转化为数字型(预转为double)

 

3.  小结

通过上面的简单测试,即可发现如下结论:

  • 当表中的字段类型为整型时,无论查询用字符串类型的数字还是int类型的数字均能走索引;
  • 表中字段为字符类型的时候,查询的值为整型时,无法走索引;
  • 如果字段做了函数计算后,该列上即使有索引也无法使用(MySQL8.0之前的版本)

因此开发同学在写SQL的时候要注意SQL的写法,缺少一个单引号可能导致很大的性能差异。

 

您可能感兴趣的文档:

--结束END--

本文标题: varchar int 查询 到底什么情况下走索引?

本文链接: https://www.lsjlt.com/news/5299.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • mysql哪些查询情况不走索引
    这篇文章主要介绍“mysql哪些查询情况不走索引”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“mysql哪些查询情况不走索引”文章能帮助大家解决问题。mysql哪些查询情况不走索引索引列参与计算,不...
    99+
    2023-06-30
  • MySQL中使用IN()查询到底走不走索引?
    MySQL中使用IN()查询到底走不走索引? 看数据量 EXPLAINSELECT * from users WHERE is_doctor in (0,1); 很明显没走索...
    99+
    2023-10-27
    原型模式 java spring 开发语言 后端
  • 你知道mysql哪些查询情况不走索引吗
    目录前言mysql哪些查询情况不走索引不走索引的情况:总结前言 在MySQL中,并不是你建立了索引,并且你在SQL中使用到了该列,MySQL就肯定会使用到那些索引的,有一些情况很可能...
    99+
    2024-04-02
  • mysql索引什么情况下会失效
    mysql索引在不使用索引列进行查询、数据类型不匹配、前缀索引的使用不当、使用函数或表达式进行查询、索引列的顺序不正确、数据更新频繁和索引过多或过少情况下会失效。1、不使用索引列进行查询,为了避免这种情况,应该在查询中使用适当的索引列;2、...
    99+
    2023-08-09
  • MongoDB中什么情况下索引会选择策略
    这篇“MongoDB中什么情况下索引会选择策略”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“MongoDB中什么情况下索引会...
    99+
    2023-06-29
  • MySQL数据库中什么情况下需要使用索引
    这篇文章主要介绍MySQL数据库中什么情况下需要使用索引,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!什么情况下需要使用索引(1)列经常被用于where条件中(2)列中有大...
    99+
    2024-04-02
  • MySQL索引失效原因及SQL查询语句不走索引原因是什么
    这篇“MySQL索引失效原因及SQL查询语句不走索引原因是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我...
    99+
    2023-03-07
    mysql sql
  • MySQL调优之索引在什么情况下会失效详解
    目录前言【1】全值匹配我最爱【2】最佳左前缀法则【3】主键插入顺序【4】计算、函数、类型转换(自动或手动)导致索引失效【5】范围条件右边的列索引失效【6】不等于(!=或者 <>) 索引失效【7】is null...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作