MySQL_列值为null对索引的影响_实践

一.首先看一个我在某公众号看到的一个关于数据库优化的举措

二.如果where子句中查询的列执行了 “is null” 或者 “is not null” 或者 “<=> null” 会不会使用索引呢?

先列出结论:where子句中使用上述对null的判断,如果判断的列设置了索引,那就可以使用到索引

官方依据在:https://dev.mysql.com/doc/refman/5.6/en/is-null-optimization.html

三.测试:

1.建表

1 CREATE TABLE `test_null_index` (
2   `id` int(11) DEFAULT NULL,
3   `mark` varchar(20) DEFAULT NULL,
4   `name` varchar(11) DEFAULT NULL
5 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2.插数据

create procedure test_null_index(in num int)
BEGIN
DECLARE i int;
set i=1;
while (i<num)
DO
  if mod(i,10)!=0 then
     insert into test_null_index values (i,concat(‘aaa‘,i),null);
   else
     insert into test_null_index values (null,concat(‘aaa‘,i),‘bbb‘);
   end if;
set i=i+1;
END while;
END;

call test_null_index(10000);

3.没加索引时,type为All,全表扫描

mysql> explain SELECT * from test_null_index WHERE id is null;
+----+-------------+-----------------+------+---------------+------+---------+------+-------+-------------+
| id | select_type | table           | type | possible_keys | key  | key_len | ref  | rows  | Extra       |
+----+-------------+-----------------+------+---------------+------+---------+------+-------+-------------+
|  1 | SIMPLE      | test_null_index | ALL  | NULL          | NULL | NULL    | NULL | 10589 | Using where |
+----+-------------+-----------------+------+---------------+------+---------+------+-------+-------------+
1 row in set (0.00 sec)

4.加上索引,可以看到,索引起作用了

mysql> create index idx_test_null on test_null_index(id);
Query OK, 0 rows affected (0.12 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> explain SELECT * from test_null_index WHERE id is null;
+----+-------------+-----------------+------+---------------+---------------+---------+-------+------+-------------+
| id | select_type | table           | type | possible_keys | key           | key_len | ref   | rows | Extra       |
+----+-------------+-----------------+------+---------------+---------------+---------+-------+------+-------------+
|  1 | SIMPLE      | test_null_index | ref  | idx_test_null | idx_test_null | 5       | const |  998 | Using where |
+----+-------------+-----------------+------+---------------+---------------+---------+-------+------+-------------+
1 row in set (0.00 sec)

四.注意,只能使用针对一个字段的关于null的判断,如果同时在两个字段对null进行判断,还是会走全表扫描

1.测试,可以看到,在name字段加上索引,并查询name为空的语句,同样会走索引

mysql> create index idx_test_null2 on test_null_index(name);
Query OK, 0 rows affected (0.13 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> explain SELECT * from test_null_index WHERE name is null;
+----+-------------+-----------------+------+----------------+----------------+---------+-------+------+-------------+
| id | select_type | table           | type | possible_keys  | key            | key_len | ref   | rows | Extra       |
+----+-------------+-----------------+------+----------------+----------------+---------+-------+------+-------------+
|  1 | SIMPLE      | test_null_index | ref  | idx_test_null2 | idx_test_null2 | 36      | const | 8994 | Using where |
+----+-------------+-----------------+------+----------------+----------------+---------+-------+------+-------------+
1 row in set (0.00 sec)

2.同时针对id和name查询为空的语句,走的是全表扫描

mysql> explain SELECT * from test_null_index WHERE id is null or name is null;
+----+-------------+-----------------+------+------------------------------+------+---------+------+-------+-------------+
| id | select_type | table           | type | possible_keys                | key  | key_len | ref  | rows  | Extra       |
+----+-------------+-----------------+------+------------------------------+------+---------+------+-------+-------------+
|  1 | SIMPLE      | test_null_index | ALL  | idx_test_null,idx_test_null2 | NULL | NULL    | NULL | 10589 | Using where |
+----+-------------+-----------------+------+------------------------------+------+---------+------+-------+-------------+
1 row in set (0.01 sec)

原文地址:https://www.cnblogs.com/rocker-pg/p/9908506.html

时间: 2024-10-10 17:07:33

MySQL_列值为null对索引的影响_实践的相关文章

SQL判断如果一列值为null则取另一列值代替 isnull()

SELECT TOP 1000 [chClientCode] ,[nvcClientName] ,[chRegionCode] ,isnull(chUltimateHeadClientCode,[chClientCode]) as chUltimateHeadClientCode FROM [PwCMDM_V1].[Core].[tblClient] Define: isnull(expression,replacement_value)

使用自增长键列值的统计信息

原文:使用自增长键列值的统计信息 今天的文章里我想谈下SQL Server里非常普遍的问题:如何处理用自增长键列的统计信息.我们都知道,在SQL Server里每个统计信息对象都有关联的直方图.直方图用多个步长描述指定列数据分布情况.在一个直方图里,SQL Server最大支持200的步长,但当你查询的数据范围在直方图最后步长后,这是个问题.我们来看下面的代码,重现这个情形: 1 -- Create a simple orders table 2 CREATE TABLE Orders 3 (

mysql数据5.6.0和5.1.7的null字段索引测试

如果保函null字段是数字 is null 和is not null都不走索引 如果保函null字段是字符 is null不走索引 和is not null会走索引 字符类型可以默认'' 数字类型可以默认0 1.数据库为5.6.0版本测试 mysql> select @@version; +------------+ | @@version  | +------------+ | 5.6.10-log | +------------+ 1 row in set (0.00 sec) mysql>

从DB灌值到DataTable时,字段值为NULL时报错相关信息;

报错信息: 1.  2.  3.  4.  5.  6.  解决方法: 1. Data Layer SQL 语句取数据时,把其列值有为null的字段用0.00替换,(ISNULL的用法): 2. 1 #region 查询工资信息 2 /// <summary> 3 /// 查询工资信息 4 /// </summary> 5 /// <param name="model"></param> 6 /// <param name=&quo

NULL值比较,两个列的合并,列值按条件替换。

show create table 表名 -- 显示创建表的sql语句. 为已有的表增加新列.alter table 表名 add 列名 int NULL -- 此行加了一个int 类型 默认可以null的列. NULL表示:一个未定义的值.如何将列的值与NULL比较?可以用IS NULL,IS NOT NULL 或<=> 可以用<=>比较两个NULL值 ,NULL<=>NULL结果为true而不是未定义. CREATE TABLE `t1` ( `col1` char

mysql 清空或删除表数据后,控制表自增列值的方法

http://blog.sina.com.cn/s/blog_68431a3b0100y04v.html 方法1: truncate table 你的表名 //这样不但将数据全部删除,而且重新定位自增的字段 方法2: delete from 你的表名 dbcc checkident(你的表名,reseed,0) //重新定位自增的字段,让它从1开始 方法3: 如果你要保存你的数据,介绍你第三种方法,by QINYI 用phpmyadmin导出数据库,你在里面会有发现哦 编辑sql文件,将其中的自

通过案例学调优之--Oracle中null使用索引

通过案例学调优之--Oracle中null使用索引  默认情况下,Oracle数据库,null在Index上是不被存储的,当在索引列以"is null"的方式访问时,无法使用索引:本案例,主要向大家演示如何在存在null的索引列上,使用"is null"访问索引. 案例分析: 1.建立表和普通索引 13:52:23 [email protected] prod >create table t2 (x int,y int); Table created. 14:

mysql中生成列与JSON类型的索引

MySQL中支持生成列,生成列的值是根据列定义中包含的表达式计算的. 一个简单的例子来认识生成列! CREATE TABLE triangle( sidea DOUBLE, sideb DOUBLE, sidec DOUBLE AS (SQRT(sidea * sidea + sideb * sideb)) ); INSERT INTO triangle(sidea, sideb) VALUES(3,4),(6,8),(5,12); mysql> select * from triangle;

Hbase 098.4中使用新API通过Get列表获取多行的列值

在Hbase0.98.4中通过Get列表的方式获取Hbase中多行的列值,本来想使用KeyValue类来处理的,结果发现该类的getRow()和getValue()的两个方法已经废弃了,最终使用新API中的Cell接口来实现,如下: Hbase中测试表中数据如下: hbase(main):005:0> scan 'testtable' ROW                      COLUMN+CELL