然而,我经常读到
当字段是时的性能问题
可为 null 并被建议使用
如果 NULL 为空字符串
实际上在语义上是正确的。
我暂时会对用词挑剔一下:
- 即使它是一个重要的性能因素,但这并不意味着它语义上正确使用值而不是 NULL。在 SQL 中,NULL 具有语义作用,表示缺失或不适用的值。给定 RDBMS 实现中 NULL 的性能特征与此无关。性能可能因品牌或版本不同而有所不同,但 NULL 在语言中的用途是一致的。
无论如何,我还没有听说过任何证据表明 NULL 表现不佳。我对任何显示可空列的性能比不可空列差的性能测量的参考感兴趣。
我并不是说我没有错,或者在某些情况下这不可能是真的——只是说做出无聊的假设是没有意义的。科学不是由猜想组成的,而是由猜想组成的。必须通过可重复的测量来提供证据。
指标还告诉您how much性能有所不同,因此您可以判断是否值得担心。也就是说,影响可能是可衡量的且非零,但与更大的性能因素(例如正确索引表或调整数据库缓存大小)相比仍然微不足道。
在 MySQL 中,搜索 NULL 可以从索引中受益:
mysql> CREATE TABLE foo (
i INT NOT NULL,
j INT DEFAULT NULL,
PRIMARY KEY (i),
UNIQUE KEY j_index (j)
);
mysql> INSERT INTO foo (i, j) VALUES
(1, 1), (2, 2), (3, NULL), (4, NULL), (5, 5);
mysql> EXPLAIN SELECT * FROM foo WHERE i = 3;
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
| 1 | SIMPLE | foo | const | PRIMARY | PRIMARY | 4 | const | 1 | |
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
mysql> EXPLAIN SELECT * FROM foo WHERE j IS NULL;
+----+-------------+-------+------+---------------+---------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+---------+---------+-------+------+-------------+
| 1 | SIMPLE | foo | ref | j_index | j_index | 5 | const | 2 | Using where |
+----+-------------+-------+------+---------------+---------+---------+-------+------+-------------+
请注意,这仍然不是性能的衡量标准。我仅表明您可以在搜索 NULL 时使用索引。我要断言(诚然没有进行测量,但这只是 StackOverflow)索引的好处掩盖了搜索 NULL 与空白字符串时任何可能的损失。
选择零或空白或任何其他值来代替 NULL 不是正确的设计决策。您可能需要在列中使用这些重要值。这就是 NULL 存在的原因,根据定义,它作为任何数据类型值域之外的值,因此您可以使用整数或字符串或其他任何值的完整范围,并且仍然有一些东西可以表示“以上值都不是”。 ”