这时就需要牵扯到MySQL的唯一索引机制了: 在MySQL官方文档中MySQL索引文档,描述到: A UNIQUE index creates a constraint such that all values in the index must be distinct. An error occurs if you try to add a new row with a key value that matches an existing row. If you specify a prefix value for a column in a UNIQUE index, the column values must be unique within the prefix length. A UNIQUE index permits multiple NULL values for columns that can contain NULL. 翻译: 唯一索引创建一个约束,使得索引中的所有值都必须是不同的。 如果尝试添加一个键值与现有行匹配的新行,则会发生错误。 如果在唯一索引中为列指定前缀值,则列值在前缀长度内必须是唯一的。 唯一索引允许包含空值的列有多个空值。
先看下explain执行计划:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
mysql> explain select * from user_2 where email='aaa@qq.com' and phone is NULL; +----+-------------+--------+------------+------+----------------+----------------+---------+-------------+------+----------+-----------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+--------+------------+------+----------------+----------------+---------+-------------+------+----------+-----------------------+ | 1 | SIMPLE | user_2 | NULL | ref | uk-email-phone | uk-email-phone | 132 | const,const | 3 | 100.00 | Using index condition | +----+-------------+--------+------------+------+----------------+----------------+---------+-------------+------+----------+-----------------------+ 1 row in set, 1warning (0.01 sec)
Scans a unique non-clustered index ata given index entry to determine whether a uniqueness violation has occurred forthe key valueofthe entry. Set shared locks onpossibleduplicaterecords
If the secondary indexisunique, but one of the fields in the n_unique first fields isNULL, a uniquekey violation cannot occur, since we define NULL != NULLin this case
/* In a unique secondary index we allow equal key values if they contain SQL NULLs 在唯一的二级索引中,如果包含sql NULL值 */ if (!index->is_clustered() && !index->nulls_equal) { for (i = 0; i < n_unique; i++) { if (dfield_is_null(dtuple_get_nth_field(entry, i))) { return (FALSE); } } }