You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL中IS NULL条件下函数索引未生效,求优雅解决方案

解决MySQL中sent_at IS NULL查询慢的优雅方案

方案1:调整查询语句匹配函数索引

你之前创建的ISNULL(sent_at)函数索引本身有效,只是当前查询条件sent_at IS NULL未触发优化器调用该索引。只需将查询语句修改为匹配函数索引的形式:

SELECT COUNT(*) FROM users WHERE ISNULL(sent_at) = 1;

执行后用EXPLAIN查看,会发现优化器已选中index_users_sent_at_is_null索引,访问类型转为ref或range,避免全表扫描。

方案2:创建虚拟列并建立索引

若不想修改现有查询语句,可通过生成虚拟列让优化器自动关联条件:

  1. 添加存储型虚拟列(计算结果持久化,不额外消耗查询性能):
ALTER TABLE users ADD COLUMN sent_at_is_null TINYINT GENERATED ALWAYS AS (ISNULL(sent_at)) STORED;
  1. 给虚拟列建立索引:
CREATE INDEX idx_sent_at_is_null ON users(sent_at_is_null);

此时执行原查询SELECT COUNT(*) FROM users WHERE sent_at IS NULL;,优化器会自动将条件转换为sent_at_is_null = 1,从而使用该索引。虚拟列仅占用1字节存储,比全值datetime索引节省大量空间。

方案3:利用NULL值的索引特性(折中方案)

如果上述两种方式都不适用,可创建仅包含sent_at列的普通索引:

CREATE INDEX idx_sent_at_null ON users(sent_at);

虽然这是全值索引,但MySQL的索引会单独存储NULL值,查询sent_at IS NULL时,优化器会直接定位到索引中的NULL值区域,相比全表扫描效率提升明显。若表中NULL值占比很低,该索引的空间占用也不会过大。


内容的提问来源于stack exchange,提问作者Andrew France

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 08:12:38