首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL ISNULL 與 IS NULL 深度解析:函數差異、索引利用與高效寫法

     編輯:MySQL 資料庫相關知識

MySQL 中 ISNULL() 函數與 IS NULL/IS NOT NULL 運算符易混淆,且關於「是否能用到索引」長期存在誤解。本文系統釐清函數與運算符差異、NULL 語義、索引利用機制、改寫優化策略與實戰測試結論。

一、 核心概念釐清

形式類型語法返回值備註
ISNULL(expr)函數ISNULL(column)1 (NULL) / 0 (非NULL)MySQL 專有,兼容性差
expr IS NULL運算符column IS NULLTRUE / FALSE / UNKNOWNSQL 標準,跨數據庫通用
expr IS NOT NULL運算符column IS NOT NULLTRUE / FALSE / UNKNOWNSQL 標準
expr = NULL比較運算column = NULL永遠為 UNKNOWN (即 FALSE)錯誤寫法! NULL 不參與比較

關鍵示例:

-- 正確查找 NULL
SELECT * FROM t WHERE name IS NULL;
SELECT * FROM t WHERE ISNULL(name);  -- 同義,但非標準

-- 正確查找非 NULL
SELECT * FROM t WHERE name IS NOT NULL;

-- 錯誤:永遠返回空結果
SELECT * FROM t WHERE name = NULL;  -- 永遠不匹配任何行

二、 索引利用機制:打破「IS NULL 不走索引」迷思

官方文檔明確:

MySQL 可以對 IS NULL 和 IS NOT NULL 使用索引。優化器根據數據分佈、表大小、選擇性自動決定是否使用索引,**並非語法層面限制**。

實測場景分析:

-- 測試表:1025014 行,describle 列僅 1 行為 NULL,有索引
SELECT `id`,`title`,`describle` FROM bnsdh_table WHERE describle IS NOT NULL;

優化器兩種執行路徑權衡:

  1. 全表掃描 + 過濾: 讀取每行,判斷 describle IS NOT NULL。
  2. 索引掃描 + 回表: 走 describle 索引(不存 NULL 值的二級索引特性),獲取非 NULL 行的主鍵,再回表。

決策依據: COST 估算。若非 NULL 行佔比極高(如 99.99%),全表掃描成本可能低於「索引掃描+大量回表」;若非 NULL 行佔比低,索引掃描更優。不是「不能用索引」,而是「優化器按成本選擇」。

改寫測試對比:

-- 原查詢
SELECT click FROM bsga_table WHERE click IS NOT NULL;

-- 改寫為範圍查詢(假設 click 為正整數)
SELECT click FROM bsga_table WHERE click > 0 AND click < 100001;

結論: 改寫後**不一定更快**。若 click 有索引且數據分佈均勻,優化器對 IS NOT NULL 和範圍查詢均能正確選擇索引。盲目改寫反而增加維護成本。**核心優化點在於:確保列有索引、統計信息準確(ANALYZE TABLE)、避免隱式轉換導致索引失效。**

三、 ISNULL() 函數的特殊行為

SELECT ISNULL(NULL);      -- 1
SELECT ISNULL('abc');     -- 0
SELECT ISNULL(0);         -- 0
SELECT ISNULL('');        -- 0 (空串非 NULL)

用途: 在選擇列表中轉換 NULL 顯示:

SELECT id, IFNULL(name, '未知') AS name, ISNULL(description) AS desc_is_null FROM articles;

四、 實戰最佳實踐

  1. 統一使用標準運算符: IS NULL / IS NOT NULL,避免 ISNULL() 移植問題。
  2. 為高頻 NULL 過濾列建立索引: 二級索引默認**不存儲純 NULL 鍵值**(MyISAM/InnoDB),故 IS NOT NULL 往往能走索引掃描。
  3. 避免 col = NULL / col <> NULL: 永遠不會命中任何行。
  4. 統計信息維護: 定期 ANALYZE TABLE,確保優化器成本估算準確。
  5. 複合索引設計: 若常用 WHERE a IS NOT NULL AND b = ?,建立 INDEX (a, b) 可覆蓋查詢。

五、 總結

IS NULL/IS NOT NULL 完全可以利用索引,關鍵在於優化器成本模型與數據分佈。拋棄「改寫為範圍查詢」的迷思,專注於:建正確索引、維護統計信息、用標準語法、EXPLAIN 驗證執行計劃,才是解決 NULL 過濾性能問題的正道。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved