在MySQL中is null, is not null对索引的影响【测试】

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在MySQL中is null, is not null对索引的影响【测试】相关的知识,希望对你有一定的参考价值。

参考技术A 一、索引字段不为null
使用select *查询
select * from a_user where name is null;

查询索引字段
select name from a_user where name is null;

select name from a_user where name is not null;

结果
select name from a_user where name is null; 未使用索引;
select name from a_user where name is not null; 使用索引;

多字段查询(索引字段+非索引字段)
select name,sex from a_user where name is null;

select name,sex from a_user where name is not null;

结果
select name,sex from a_user where name is null;未使用索引;
select name,sex from a_user where name is not null;未使用索引;

二、索引字段为null 时
使用select *查询
select * from b_user where name is null;

select * from b_user where name is not null;

结果:
select * from b_user where name is null;使用索引
select * from b_user where name is not null;未使用索引

查询索引字段
select name from b_user where name is null;

select name from b_user where name is not null;

结果:
select name from b_user where name is null;使用索引
select name from b_user where name is not null;使用索引

多字段查询(索引字段+非索引字段)
select name,sex from b_user where name is null;

select name,sex from b_user where name is not null;

结果:
select name,sex from b_user where name is null;使用索引
select name,sex from b_user where name is not null;未使用索引

总结以上测试:
1、当索引字段不为null 时,只有使用is not null 返回的结果集中只包含索引字段时,才使用索引;
2、当索引字段为null时候,使用 is null 不影响覆盖索引,但是使用 is not null 只有完全返回索引字段时才会使用索引

“IS NOT NULL”未在 mySQL 中产生所需的结果

【中文标题】“IS NOT NULL”未在 mySQL 中产生所需的结果【英文标题】:"IS NOT NULL" not producing the required results in mySQL 【发布时间】:2021-08-11 07:16:59 【问题描述】:

我正在尝试根据我的表格构建报告。这是我的桌子:

以下是获得所需结果的 SQL 查询。

SELECT
  `user`,
  SUM(
    CASE
      WHEN `event_time` >= '2021-04-01 00:00:00'
      AND `event_time` <= '2021-04-16 23:59:59'
      AND `sub_status` = 'TB'
      THEN pause_sec
    END
  ) AS 'Training Break',
  SUM(
    CASE
      WHEN `event_time` >= '2021-04-01 00:00:00'
      AND `event_time` <= '2021-04-16 23:59:59'
      AND `sub_status` = 'SB1'
      THEN pause_sec
    END
  ) AS 'Short Break 1',
  SUM(
    CASE
      WHEN `event_time` >= '2021-04-01 00:00:00'
      AND `event_time` <= '2021-04-16 23:59:59'
      AND `sub_status` = 'SB2'
      THEN pause_sec
    END
  ) AS 'Short Break 2',
  SUM(
    CASE
      WHEN `event_time` >= '2021-04-01 00:00:00'
      AND `event_time` <= '2021-04-16 23:59:59'
      AND `sub_status` = 'LB'
      THEN pause_sec
    END
  ) AS 'Long Break'
FROM
  `vicidial_agent_log`
GROUP BY `user`

我希望排除具有所有空值的条目,以下是我的语法,但它不起作用并产生相同的结果。

FROM
  `vicidial_agent_log`
WHERE 'Training Break' IS NOT NULL
  AND 'Short Break 1' IS NOT NULL
  AND 'Short Break 2' IS NOT NULL
  AND 'Long Break' IS NOT NULL
GROUP BY `user`

请在此处提供帮助或分享可以提供帮助的帖子。我一直在寻找,但是

【问题讨论】:

【参考方案1】:

不要对列名/别名使用单引号,因为例如 'Training Break' 在像 'Training Break' IS NOT NULL 这样的表达式中被解释为字符串文字,当然不为空。

在 MySql 中,您可以使用反引号将列名括起来。

另外,Training BreakShort Break 1Short Break 2Long Break 列是聚合函数的结果,因此它们不能在 WHERE 子句中使用。而是使用HAVING 子句。

最后,由于您希望这些列中至少有 1 个不为空的行,您应该使用运算符 OR 而不是 AND

FROM
  `vicidial_agent_log`
GROUP BY `user`
HAVING `Training Break` IS NOT NULL
    OR `Short Break 1` IS NOT NULL
    OR `Short Break 2` IS NOT NULL
    OR `Long Break` IS NOT NULL

或者:

FROM
  `vicidial_agent_log`
GROUP BY `user`
HAVING COALESCE(`Training Break`, `Short Break 1`, `Short Break 2`, `Long Break`) IS NOT NULL

【讨论】:

【参考方案2】:

首先,将SUM() 表达式的公共部分移至WHERE 子句。

其次,修正日期逻辑,以免错过一秒。

我也强烈推荐使用不需要转义的列名。所以:

SELECT user,
      SUM(CASE WHEN sub_status` = 'TB' THEN pause_sec END) AS Training_Break,
      SUM(CASE WHEN sub_status = 'SB1' THEN pause_sec END) AS Short_Break_1,
      SUM(CASE WHEN sub_status = 'SB2' THEN pause_sec END) AS Short_Break_2,
      SUM(CASE WHEN sub_status = 'LB' THEN pause_sec END) AS Long_Break
FROM vicidial_agent_log
WHERE event_time >= '2021-04-01' AND
      event_time < '2021-04-17'
GROUP BY user;

这可能会消除NULL 值并加快查询速度。但是,如果整行中仍有 NULL 值,那是因为有些行没有这些状态之一。因此,只需检查它们:

SELECT user,
      SUM(CASE WHEN sub_status` = 'TB' THEN pause_sec END) AS Training_Break,
      SUM(CASE WHEN sub_status = 'SB1' THEN pause_sec END) AS Short_Break_1,
      SUM(CASE WHEN sub_status = 'SB2' THEN pause_sec END) AS Short_Break_2,
      SUM(CASE WHEN sub_status = 'LB' THEN pause_sec END) AS Long_Break
FROM vicidial_agent_log
WHERE event_time >= '2021-04-01' AND
      event_time < '2021-04-17' AND
      sub_status IN ('TB', 'SB1', 'SB2', 'LB')
GROUP BY user;

SQL 在让您在聚合之前或之后进行过滤方面非常强大。但是,在聚合之前进行过滤通常要好得多(从性能角度来看)。

我还建议您使用不需要转义的标识符。并且,切勿将单引号用于字符串和日期文字以外的任何内容。

【讨论】:

以上是关于在MySQL中is null, is not null对索引的影响【测试】的主要内容,如果未能解决你的问题,请参考以下文章

17.MySQL中的IS NULL 和 IS NOT NULL

js火狐报错event is not defined

mysql 里面的isnull()和ifnull() is null 和 is not null

MySQL - IS NOT NULL 和 != NULL 的区别?

MySQL中 IS NULLIS NOT NULL!= 能用上索引吗?

mysql中is null 与 = null