我如何一起使用'not in'和'null'?

时间:2015-12-16 07:17:12

标签: mysql

这是我的问题:

SELECT last_response
FROM   bank_payments
WHERE  fk_bank_id = 2
       AND creation_timestamp BETWEEN
           '2015-12-16 00:00:00' AND '2015-12-16 11:00:00'
       AND last_response NOT IN ( -2, 0, 152 )
        OR last_response IS NULL; 

我在这里想说的是,除了时间戳之外,还有这样的:返回last_response所在的行:

  • 不等于-20152,或
  • 等于null

这个查询需要很长时间才能完成,而我猜测我的方法是错误的。查询不等于某些值的行的正确方法是什么,或null是什么?

2 个答案:

答案 0 :(得分:2)

由于ANDOR的执行顺序,您应该在last_responses的术语周围使用括号。

  SELECT last_response
  FROM bank_payments
  WHERE fk_bank_id = 2
        AND creation_timestamp BETWEEN
        '2015-12-16 00:00:00' AND '2015-12-16 11:00:00'
        AND (last_response NOT IN (-2, 0, 152)
             OR last_response IS NULL); 

目前,您正在寻找应用last_response IS NULL或其他条件组合的任何内容。

如果您感到好奇,请检查两个执行计划,看看到底发生了什么。

答案 1 :(得分:2)

我推荐这个:

WORD COLON INDENT WORD DEDENT

这增加了读者和数据库的清晰度,您希望数据在银行ID 2的特定时间戳之间。此外,最后一个响应可以没有值,或者如果它有值,则不应该是0,-2,152。

要加快查询速度,请检查表格上的索引。您可以在last_response上创建索引(如果尚未存在),如下所示:

SELECT last_response
FROM   bank_payments
WHERE  fk_bank_id = 2
       AND creation_timestamp BETWEEN
           '2015-12-16 00:00:00' AND '2015-12-16 11:00:00'
       AND (last_response NOT IN ( -2, 0, 152 ) OR last_response IS NULL); 

将向您解释MySQL希望如何检索数据以及它将利用哪些索引。基于此,您可以选择将索引更改为覆盖索引,如下所示:

create index idx_bank_payments_last_response on bank_payments(last_response);

explain select ...