如果索引列的值为空,Mysql插入查询性能



我有一个mysql表有~ 5000万行。我想在可能具有NULL值的列上添加二级索引。我想了解如果在这个表中插入一行,这个列的值为NULL仍然是一个昂贵的操作?或者插入一行只会增加Mysql中具有非空值的索引列的开销?

我们来做个实验。我创建了一个测试表:

mysql> create table mytable (id serial primary key, x int, y int);

我用几百万行填充它。然后我测试了一个100万行的null INSERT:

mysql> insert into mytable (x, y) select null, null from mytable limit 1000000;
Query OK, 1000000 rows affected (2.57 sec)

对于非null值也是如此:

mysql> insert into mytable (x, y) select 1234, 1234 from mytable limit 1000000;
Query OK, 1000000 rows affected (2.60 sec)

现在添加一个索引并再次尝试测试:

mysql> alter table mytable add index (x);
mysql> insert into mytable (x, y) select null, null from mytable limit 1000000;
Query OK, 1000000 rows affected (3.12 sec)
mysql> insert into mytable (x, y) select 1234, 1234 from mytable limit 1000000;
Query OK, 1000000 rows affected (3.21 sec)

现在我在最后一列上添加了一个索引,所以有两个索引写入,而不是只有一个,然后再试一次测试:

mysql> alter table mytable add index (y);
mysql> insert into mytable (x, y) select null, null from mytable limit 1000000;
Query OK, 1000000 rows affected (3.64 sec)
mysql> insert into mytable (x, y) select 1234, 1234 from mytable limit 1000000;
Query OK, 1000000 rows affected (3.82 sec)

我知道这个测试有缺陷。我很懒,没有在每次测试之前将表重新初始化为初始大小。因此,表变得越来越大,这可能是每次测试时间增加的原因。

问题的关键不是用这样或那样的方法证明答案。这是为了表明,如果你有这样的问题,你有机会和责任自己测试它。这可能会得到比询问Stack Overflow更好的结果,原因如下:

  • 你不必等别人来回答,如果有人来的话。

  • 你避免了那些实际上不知道的人的虚假答案。

  • 你避免基于有缺陷的方法的答案,就像我上面展示的那样。

你接受的是计算机科学专业的教育是有原因的。你应该接受你作为一个科学家的角色,并思考什么样的实验可以给你答案(用适当的方法)。

NULL看作是另一个值。

可以把INDEX看作一对的列表——键值和指向行的某种指针。(键值可以是NULL。)另外,可以把INDEX想象成一个表——存储在b树中。这是按键排序的,就像数据按b树中的PRIMARY KEY排序一样。

向表中添加一行将向数据的b树和每个辅助INDEX'sb树添加一行。

通过将NULL视为另一个值,您可以合理地猜测各种操作不会将NULL视为不同的。

所以,如果业务逻辑需要NULL,使用它就不用担心了。

NULL有使用问题。WHERE x = NULL可能应该"错误";应该是WHERE x IS NULLNULL不等于任何东西,包括另一个NULL。以及其他NULL不完全"只是另一个值"的问题。

最新更新