回答

收藏

“泪不为零”和“不为零”之间的区别是什么?

技术问答 技术问答 449 人阅读 | 0 人回复 | 2023-09-14

SELECT id FROM customers WHERE type IS NOT Null;7 e* |( k* q# q9 m4 o
相对:0 V* ?* F, `; b0 C/ u
SELECT id FROM customers WHERE NOT type IS NULL;
! y7 \  T5 d, `4 g( U3 y1 D2 N8 F) `以上任一返回的数据将完全相同。; r8 R  o5 a9 Q2 ^7 Z% P" K* l; e
有什么区别,为什么其中之一更可取?
( Y8 l" c2 J7 d) k7 U编辑:
0 J, t1 c5 @4 g7 d' {# w7 Z在我看来,性能可能有所不同。有人愿意对此进行详细说明吗?
: S% H& u: X" h/ Q" v               
6 q' T5 A; h. Y& O8 ~解决方案:" f2 K. A( R. {9 [
               
- Z) {8 d/ u$ o# N9 Q" N! _5 ?; G; ~+ H- `+ R, Z

' A# N" {3 b8 b) a8 Z5 ?                没有区别。/ Z0 b6 F1 n1 ^5 B
. H: H6 V6 L8 H1 o! h4 n0 q( j
在我看来,性能可能有所不同。有人愿意对此进行详细说明吗?# `0 R0 y6 n2 r. U( N5 w  e/ D
; W3 ^" g( B6 f1 Q' ~3 S, ~
所有主要搜索引擎(即MySQL,SQL Server,Oracle和PostgreSQL)将合并在分析阶段,从他们制作计划相同,这些谓词。
$ k6 Y* e9 w; ^+ u+ c- ~: o这些条件的处理比仅以一个或另一个顺序应用运算符更为复杂。" d4 g$ q3 \- m+ ~# n" m) E
例如,在中Oracle,IS NOT NULL(或NOT IS NULL)条件表示有可能使用索引,因此查询如下:
+ Z* r% e, g9 Z; z1 I. j2 GSELECT  column) y; E+ w9 H; h% @  B  d
FROM    mytable) p0 D" e: \& c* ]1 h% v, d1 i3 c3 J3 N( |
WHERE   column IS NOT NULL7 f/ }" J2 l0 G) K
将最有可能使用来执行index fast full
! \' V& F$ V" j" oscan,而在运行时NULL不会进行任何其他检查(因为这些值不会进入索引,因此没有必要对其进行检查)。
! t  C" X; v- l& V即使需要检查每个记录,检查的顺序也将由优化器定义(而不是由谓词和运算符出现在WHERE子句中的顺序)。
' {5 N/ i; c' c* o+ q例如,这是一个Oracle查询计划:
  y2 T& I9 H( V: d( i  b0 j& GSQL> EXPLAIN PLAN FOR
, b0 I8 L  b8 L  2  4 ^  a, j# M) P1 t$ U
  2  SELECT *0 O2 u  z$ K- U3 k
  3  FROM   t_test1 C6 X6 E1 Z/ D- i" _& }
  4  WHERE  NOT column IS NULL
3 k8 y  ]8 x6 V. U3 O; ?. `, A  y  5  /  K$ z( s- R6 m1 r; V
Explained
4 W' n! r& E2 P  F$ l! }, XSQL> SELECT  *2 _& o( F% C- ~! b1 ~3 ~
  2  FROM    TABLE(DBMS_XPLAN.display())
7 t& ?' \- J7 B1 _  y. s: D$ X  3  /
3 r1 i% a& a- |+ x8 B" d4 g9 \PLAN_TABLE_OUTPUT! v8 U. n, v' T8 H- V1 d
--------------------------------------------------------------------------------- x4 V9 i8 W5 i+ V6 P
Plan hash value: 9586998307 X, i5 s; _, A
----------------------------------------------------------------------------) l6 `" M3 G0 P3 ~* L. c
| Id  | Operation         | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
( }* e! Z6 f# o1 l0 P----------------------------------------------------------------------------9 G9 N& T' i+ ?% ]4 p" w
|   0 | SELECT STATEMENT  |        |    30 |  1260 |     3   (0)| 00:00:01 |4 t8 l) v* c" ^- ^( m0 w3 K7 y! R
|*  1 |  TABLE ACCESS FULL| T_TEST |    30 |  1260 |     3   (0)| 00:00:01 |
' v3 P2 P# \; j& |2 r----------------------------------------------------------------------------
6 u. Q, w) O/ F. j) s, GPredicate Information (identified by operation id):. R8 }& Q5 w8 F
---------------------------------------------------
/ h+ X3 \% V% o7 @: A: j   1 - filter("COLUMN" IS NOT NULL)/ g! v+ h! L- j1 R
如您所见,的内容filter已在内部翻译成IS NOT NULL(Oracle与大多数评论者似乎都认为是更合适的形式)' l9 T- P. ~% B, e' }2 z! k
更新:
" |! T* a5 Q4 G, k正如乔纳森·莱夫勒(Jonathan Leffler)所指出的,在评估元组(与单列相对)时,这些是不同的。
4 H+ h- l& _+ B5 u0 f2 Q# n9 V+ J由混合值NULL和非NULL值组成的元组既不是aNULL也不是a NOT NULL。
% q: Q2 Q  n4 l' V在PostgreSQL(支持针对元组的谓词)中,这两个表达式:
# \  P+ s1 U' N8 @, b4 B* nSELECT  (1, NULL) IS NULL2 f  `1 J5 p# N
SELECT  (1, NULL) IS NOT NULL( b; T$ p* b! _
评估为假。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则