MySQL中IS NULL与NOT EXISTS查询效率对比及优化方案咨询
MySQL中基于UUID筛选不存在行的查询效率对比与优化方案
你给出的两种写法性能对比
这两种查询在MySQL优化器的处理下,实际执行性能几乎没有差异。MySQL会自动将WHERE (SELECT uuid ...) IS NULL这类子查询转换成和NOT EXISTS逻辑一致的半连接执行计划,核心都是检查submitedTasks中是否存在匹配的UUID。不过NOT EXISTS语义更直观、可读性更强,日常开发更推荐使用这种写法。
更高效的替代实现
除了上述两种,还有一种常用的实现方式:LEFT JOIN + IS NULL,写法如下:
SELECT t.* FROM tasks t LEFT JOIN submitedTasks st ON t.uuid = st.uuid WHERE st.uuid IS NULL;
这种写法和NOT EXISTS在多数场景下性能相当,但数据量极大时可以通过EXPLAIN对比执行计划:比如当submitedTasks数据量远小于tasks时,NOT EXISTS可能更高效;反之LEFT JOIN的表现会更优。
字段类型优化:varchar(36) 转 bigint的价值
如果业务允许将UUID字段改为bigint,强烈建议执行这个变更,会带来显著性能提升:
- 存储空间:bigint仅占8字节,而varchar(36)至少占用37字节(含长度标识),存储空间减少70%以上,索引体积也会大幅缩小,磁盘IO和内存占用都会降低。
- 查询速度:数值类型的比较远快于字符串类型的UUID对比,关联、筛选时的性能提升明显。
- 注意:替换时建议用自增ID、雪花ID这类原生数值型唯一标识;若要基于现有UUID转换,需确保转换逻辑不会破坏唯一性。
关键优化前提
不管采用哪种写法,必须为tasks.uuid和submitedTasks.uuid建立单独的二级索引,或作为联合索引的前缀。没有索引的情况下,所有写法都会触发全表扫描,数据量稍大就会变得极慢。
内容的提问来源于stack exchange,提问作者piggy_oink
相关产品推荐
相关产品推荐

