但是,我经常阅读有关字段可为空时的性能问题,并建议在 NULL 实际上语义正确的情况下使用空字符串。
我将暂时对单词选择挑剔:
- 即使它是一个重要的性能因素,但这并不意味着使用值而不是 NULL在语义上是正确的。在 SQL 中,NULL 具有语义作用,表示缺失或不适用的值。给定 RDBMS 实现中 NULL 的性能特征与此无关。性能可能因品牌或版本而异,但语言中NULL的目的是一致的。
无论如何,我没有听说过任何证据表明 NULL 表现不佳。我会对任何显示可空列性能比不可空列差的性能测量参考感兴趣。
我并不是说我没有错,或者在某些情况下它不可能是真的——只是做空洞的假设没有意义。科学不是由猜想组成的;必须通过可重复的测量来证明证据。
指标还告诉您性能差异有多大,因此您可以判断这是否值得担心。也就是说,影响可能是可测量的且非零,但与更大的性能因素(例如正确索引表或调整数据库缓存大小)相比仍然微不足道。
在 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 存在的原因,作为一个定义在任何数据类型的值域之外的值,因此您可以使用整数或字符串或其他任何值的全部范围,并且仍然有一些东西来表示“没有上述值。 "