• mysql 优化之 is null ,is not null 索引使用测试


     关于mysql优化部分,有很多网友说尽量避免使用is null, is not null,select * 等,会导致索引失效,性能降低?那是否一定收到影响呢?真的就不会使用索引了吗?

    本文的测试数据库版本为5.7.18,不同版本得出的结果可能会有所不同:

    本文测试的两张表数据如下:

    CREATE TABLE `t_user` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `name` varchar(20) NOT NULL,
      `age` int(11) DEFAULT NULL,
      `sex` varchar(20) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
    
    INSERT INTO `t_user` (`id`, `name`, `age`, `sex`) VALUES ('1', 'jemis', '20', '男');
    INSERT INTO `t_user` (`id`, `name`, `age`, `sex`) VALUES ('2', 'fox', '20', '男');
    INSERT INTO `t_user` (`id`, `name`, `age`, `sex`) VALUES ('3', 'tony', '20', '男');
    
    CREATE  UNIQUE  INDEX indexName ON t_user(name(20));
    

      一、索引字段不能为空的情况下:

       测试select *  结合is null 和 is not null :

     

    可以得出:

          EXPLAIN select * from t_user where `name` is not null; 不使用索引;
          EXPLAIN select * from t_user where `name` is null; 不使用索引;

     查询索引字段的情况下:

     

      有以上可以得出查询索引字段时:

            EXPLAIN select name from t_user where `name` is not null; 使用索引 

            EXPLAIN select name from t_user where `name` is null; 不使用索引

    select 索引字段加 非索引字段时:

      

     可以得出:当select索引字段+其他字段时:

         EXPLAIN select name,age from t_user where `name` is not null; 不使用索引

        EXPLAIN select name,age from t_user where `name` is null; 不使用索引

        

    由此可见,当索引字段不可以为null 时,只有使用is not null 并且返回的结果集中只包含索引字段时,才使用索引

    二、当索引字段可以为null 时测试数据:

    CREATE TABLE `t_user1` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `name` varchar(20) DEFAULT NULL,
      `age` int(11) DEFAULT NULL,
      `sex` varchar(20) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
    
    INSERT INTO `springtest`.`t_user1` (`id`, `name`, `age`, `sex`) VALUES ('1', 'jemis', '20', '男');
    INSERT INTO `springtest`.`t_user1` (`id`, `name`, `age`, `sex`) VALUES ('2', 'fox', '20', '男');
    INSERT INTO `springtest`.`t_user1` (`id`, `name`, `age`, `sex`) VALUES ('3', 'tony', '20', '男');
    
    CREATE  UNIQUE  INDEX indexName ON t_user1(name(20));

     当索引字段可以为null,使用is null ,is not null:

    当select * 时:

    查询语句select *:EXPLAIN select * from t_user1 where `name` is not null;; 不使用索引
                     EXPLAIN select * from t_user1 where `name` is null; 使用索引

    select 索引字段:

     

      select 索引字段的结论为:

               EXPLAIN select name from t_user1 where `name` is not null; 使用索引
                EXPLAIN select name from t_user1 where `name` is null; 使用索引

      select 索引字段 + 非索引字段 为:

        

    当select索引字段+其他字段时: EXPLAIN select name,age from t_user1 where `name` is not null;不使用索引,会导致索引失效
                                                        EXPLAIN select name,age from t_user1 where `name` is null; 使用索引

    总结以上情形可知:1、当索引字段不可以为null 时,只有使用is not null 返回的结果集中只包含索引字段时,才使用索引

                                  2、当索引字段可以为空时,使用 is null 不影响覆盖索引,但是使用 is not null 只有完全返回索引字段时才会使用索引

    最后附上本文的测试完整版sql以及结论:

    CREATE TABLE `t_user` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `name` varchar(20) NOT NULL,
      `age` int(11) DEFAULT NULL,
      `sex` varchar(20) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
    
    INSERT INTO `springtest`.`t_user` (`id`, `name`, `age`, `sex`) VALUES ('1', 'jemis', '20', '');
    INSERT INTO `springtest`.`t_user` (`id`, `name`, `age`, `sex`) VALUES ('2', 'fox', '20', '');
    INSERT INTO `springtest`.`t_user` (`id`, `name`, `age`, `sex`) VALUES ('3', 'tony', '20', '');
    CREATE  UNIQUE  INDEX indexName ON t_user(name(20));
    
    
    CREATE TABLE `t_user1` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `name` varchar(20) DEFAULT NULL,
      `age` int(11) DEFAULT NULL,
      `sex` varchar(20) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
    
    INSERT INTO `springtest`.`t_user1` (`id`, `name`, `age`, `sex`) VALUES ('1', 'jemis', '20', '');
    INSERT INTO `springtest`.`t_user1` (`id`, `name`, `age`, `sex`) VALUES ('2', 'fox', '20', '');
    INSERT INTO `springtest`.`t_user1` (`id`, `name`, `age`, `sex`) VALUES ('3', 'tony', '20', '');
    
    
    CREATE  UNIQUE  INDEX indexName ON t_user1(name(20));
    
    
    
    当字段值可以为null,使用is null ,is not null,
    查询语句:EXPLAIN select * from t_user1  where `name` is not null;;  不使用索引
              EXPLAIN select * from t_user1  where `name` is  null;   使用索引
              
    当不使用select * 时 : EXPLAIN select name from t_user1  where `name` is not null;  使用索引
                           EXPLAIN select name from t_user1  where `name` is  null; 使用索引
                           
                           
    当select索引字段+其他字段时: EXPLAIN select name,age from t_user1  where `name` is not null;不使用索引,会导致索引失效
                                  EXPLAIN select name,age from t_user1  where `name` is  null;   使用索引
                                  
    从以上可以看出,当索引字段可以为空时,使用 is null 不影响覆盖索引,但是使用 is not null 只有完全返回索引字段时才会使用索引
    
    
    
    
    当字段值不能为null 时,EXPLAIN select *  from t_user  where `name` is not  null; 不使用索引;
                           EXPLAIN select * from t_user  where `name` is  null;  不使用索引;
                           
    当select索引字段 时 :  EXPLAIN select name from t_user  where `name` is not null; 使用索引 
                            EXPLAIN select name from t_user  where `name` is  null;  不使用索引
                            
    当select索引字段+其他字段时: EXPLAIN select name,age from t_user  where `name` is  not null; 不使用索引
                                  EXPLAIN select name,age from t_user  where `name` is  null;   不使用索引
                                  
                                  
    由此可见,当索引字段不可以为null 时,只有使用is not null 返回的结果集中只包含索引字段时,才使用索引
                            
        
    View Code
  • 相关阅读:
    Visual Studio2019安装步骤
    写在第一页的话
    数状数组
    hdu 3501 数学题
    静态邻接表
    最长子序列
    hdu 1094 所想到的
    bellman_ford
    郁闷的一晚
    SPFA + 静态邻接表 模板
  • 原文地址:https://www.cnblogs.com/cheng21553516/p/11450765.html
Copyright © 2020-2023  润新知