2009-04-21 63 views
2

如果某個特定列的值是否爲空,哪個SQL會更快以驗證它,爲什麼?驗證列是否具有空值

1)SELECT * FROM表1 WHERE COL1 IS NULL

執行此查詢,然後檢查是否能夠讀取任何記錄。如果是,則存在空值。

2)SELECT COUNT(COL1)FROM表1 WHERE COL1 IS NULL

閱讀被返回,以確定是否有任何空記錄

用於Oracle10g和SQLServer2005的工作計數。

回答

4

我不知道甲骨文,但對於SQL Server此選項可能會是最快的是:

SELECT TOP 1 COL1 FROM TABLE1 WHERE COL1 IS NULL; 

這樣的數據庫管理系統只給你答案之前閱讀單行;其他選項必須讀取全部非空行。並且我已指定COL1而不是*,因此可能可以通過COL1上的索引滿足查詢,使查詢更快。

+0

只是選擇一個nit,數據庫可能仍然需要讀取多行。當它最終達到符合標準的一個時,它就能夠停下來。它仍然必須閱讀任何不符合標準的內容,直到達到該標準。另外,使用EXISTS會帶來相同的優勢,我相信它將與ANSI兼容。 – 2009-04-21 13:55:27

5

大廈kquinn的回答,在Oracle中,這將是

SELECT COL1 FROM TABLE1 WHERE COL1 IS NULL AND ROWNUM = 1; 

這樣的數據庫管理系統只給你答案之前閱讀單行;

但是,該陳述有誤導性。它必須讀取所有行,直到找到缺少列值的行。然後它可以停止並返回該行。

如果沒有這樣的行,它會讀取整個表格。

所以可以用COL1上的索引滿足查詢,使查詢更快。

僅指定COL1不會產生太多的影響,至少在Oracle上,(常規B-Tree)索引不能用於查找NULL值。

如果您有興趣稍後確定行,您可能需要選擇更多的列(例如主鍵值)。

+1

Hm,在PostgreSQL(我選擇的數據庫),B-Tree索引(默認值)* do *存儲關於NULL值的信息,*可以*用於滿足查詢中的IS NULL條件;我同意你的觀點,如果索引無法使用,那麼使索引覆蓋查詢不會有多大幫助。您需要了解SQL Server索引如何處理NULL並查看其行爲是否像Postgres或Oracle一樣。 – kquinn 2009-04-21 07:07:16

6

計數(列名),我決不算NULL值,計數時,您指定的列名,當您使用*

運行不計NULLS跳過NULLS這

CREATE TABLE testnulls (ID INT) 
INSERT INTO testnulls VALUES (1) 
INSERT INTO testnulls VALUES (2) 
INSERT INTO testnulls VALUES (null) 

SELECT count(*) FROM testnulls WHERE ID IS NULL --1 

SELECT count(ID) FROM testnulls WHERE ID IS NULL --0 

我會用存在替代,因爲這是一個布爾操作,將在NULL中第一次出現停止

IF EXISTS (SELECT 1 FROM testnulls WHERE ID IS NULL) 
PRINT 'YES' 
ELSE 
PRINT 'NO' 
0

多解(列包含空值的一些|列全是NULLs *測試單列|如果你需要測試多個列測試與表格結果多列)

,你可以使用以下命令:

Column_1 Column_2 Column_3 
-------- -------- -------- 
1  2  NULL 
1  NULL  NULL 
5  6  NULL 

首先,測試空值並計數:

select 
    sum(case when Column_1 is null then 1 else 0 end) as Column_1, 
    sum(case when Column_2 is null then 1 else 0 end) as Column_2, 
    sum(case when Column_3 is null then 1 else 0 end) as Column_3, 
from TestTable 

產生NULL的計數:

Column_1 Column_2 Column_3 
0   1   3 

Wher e結果爲0,沒有NULL。

,讓我們計算非空值:

select 
    sum(case when Column_1 is null then 0 else 1 end) as Column_1, 
    sum(case when Column_2 is null then 0 else 1 end) as Column_2, 
    sum(case when Column_3 is null then 0 else 1 end) as Column_3, 
from TestTable 

...但因爲我們這裏計算非空值,這可以簡化爲:

select 
    count(Column_1) as Column_1, 
    count(Column_2) as Column_2, 
    count(Column_3) as Column_3, 
from TestTable 

無論是一個產出:

Column_1 Column_2 Column_3 
3   2   0 

如果結果爲0,則列爲irely由NULL組成。

最後,如果你只需要檢查一個特定的列,那麼TOP 1更快,因爲它應該停止在第一個命中。然後,您可以選擇使用COUNT(*),得到一個布爾風格的結果:

select count(*) from (select top 1 'There is at least one NULL' AS note from TestTable where Column_3 is NULL) a 

0 =沒有空值,1 =至少有一個NULL

select count(*) from (select top 1 'There is at least one non-NULL' AS note from TestTable where Column_3 is not NULL) a 

0 =他們所有NULL,1 =至少有一個非NULL我希望這有助於。