SQL語句中的1

一、select 1 from table;select anycol(目的表集合中的任意一行)from table;select * from table;

從作用上來說是沒有差別的,都是查看是否有記錄,一般是作條件查詢用的。select 1 from table中的1是一常量(可以為任意數值),查到的所有行的值都是它,但從效率上來說,1>anycol>*,因為不用查字典表。

注意:
當只關心數據表有多少記錄行而不需要知道具體的字段值時,類似“select 1 from table”是一個很不錯的SQL語句寫法,它通常用于子查詢。
這樣可以減少系統開銷,提高運行效率。因為這樣寫的SQL語句,數據庫引擎就不會去檢索數據表里每條具體的記錄和每條記錄里每個具體的字段值并將它們放到內存里,而是根據查詢到有多少記錄行存在就輸出多少個“1”,每個“1”代表有1行記錄,同時選用數字1還因為它所占用的內存空間最小,當然用數字0的效果也一樣。

測試:

  1. select 1 from table增加臨時列,每行的列值是寫在select后的數。這條sql語句中是1。
  2. select count(1) from table不管count(a) 的 a值如何變化,得出的值總是table表的行數。
  3. select sum(1) from table計算臨時列的和。

在Oracle中用 1 測試了一下,發現結果如下:

  1. 測試結果,得出一個行數和table表行數一樣的臨時列,每行的列值是1;
  2. 得出一個數,該數是table表的行數;
  3. 得出一個數,該數是table表的行數;

然后又用“2”測試,結果如下:

  1. 得出一個行數和table表行數一樣的臨時列,每行的列值是2;
  2. 得出一個數,該數是table表的行數;
  3. 得出一個數,該數是table表的行數×2的數。

再用不同的數測試:

  1. 得出一個行數和table表行數一樣的臨時列,每行的列值是寫在select后的數;
  2. 還是得出一個數,該數是table表的行數;
  3. 得出一個數,該數是table表的行數×寫在select后的數。

綜上所述:第一種的寫法是增加臨時列,每行的列值是寫在select后的數;第二種是不管count(a)的a值如何變化,得出的值總是table表的行數;第三種是計算臨時列的和。

二、count(列名) 、count(常量) 、count(*)

【強制】不要使用 count(列名) 或 count(常量) 來替代 count(*) , count(*) 是 SQL 92 定義的標準統計行數的語法,跟數據庫無關,跟 NULL 和非 NULL 無關。
說明:count(*) 會統計值為 NULL 的行,而 count(列名) 不會統計此列為 NULL 值的行。
【強制】 count(distinct col) 計算該列除 NULL 之外的不重復行數,注意 count(distinct col 1, col 2 ) 如果其中一列全為 NULL ,那么即使另一列有不同的值,也返回為 0。
【強制】當某一列的值全是 NULL 時, count(col) 的返回結果為 0,但 sum(col) 的返回結果為NULL ,因此使用 sum() 時需注意 NPE 問題。
正例:可以使用如下方式來避免 sum 的 NPE(NullPointerException) 問題:
select if ( isNull ( sum(g) ) ,0, sum(g) ) from table;

1??count(1) and count(*)

當表的數據量大些時,對表作分析之后,使用count(1)還要比使用count(*)用時多!

從執行計劃來看,count(1)和count(*)的效果是一樣的。但是在表做過分析之后,count(1)會比count(*)的用時少些(1w以內數據量),不過差不了多少。

如果count(1)是聚集索引時,那肯定是count(1)快,但是差的很小。
因為count(*),自動會優化指定到那一個字段。所以沒必要去count(1),用count(),sql會幫你完成優化的。因此:在有聚集索引時count(1)和count(*)基本沒有差別!

2??count(1) and count(字段)主要區別

  • count(1) 會統計表中的所有的記錄數,包含字段為null 的記錄。
  • count(字段) 會統計該字段在表中出現的次數,忽略字段為null 的情況。即不統計字段為null 的記錄。

3??count(*) 和 count(1)和count(列名)區別

執行效果上:

  • count(*)包括了所有的列,相當于行數,在統計結果的時候,不會忽略列值為NULL
  • count(1)包括了忽略所有列,用1代表代碼行,在統計結果的時候,不會忽略列值為NULL
  • count(列名)只包括列名那一列,在統計結果的時候,會忽略列值為空(這里的空不是只空字符串或者0,而是表示null)的計數,即某個字段值為NULL時,不統計。

執行效率上:

  • 列名為主鍵,count(列名)會比count(1)快
  • 列名不為主鍵,count(1)會比count(列名)快
  • 如果表多個列并且沒有主鍵,則 count(1)的執行效率優于 count(*)
  • 如果有主鍵,則 select count(主鍵)的執行效率是最優的

如果表只有一個字段,則 select count(*) 最優。

4??實例分析

create table tab
(name char(1),
age char(2));
 
insert into tab values
('a', '14'),
('a', '15'),
('a', '15'),
('b', NULL),
('b', '16'),
('c', '17'),
('d', null),
('e', '');

select 
name,count(name),count(1),count(*),count(age),count(distinct(age))
from tab
group by name;

三、SQL查找是否“存在”

根據條件從數據庫表中查詢『有』與『沒有』,只有兩種狀態。

1??常見寫法

業務代碼中,需要根據一個或多個條件,查詢是否存在記錄,不關心有多少條記錄。普遍的 SQL 寫法如下:

select count(*) from table where a = 1 AND b = 2;

業務代碼:

##### Java寫法:
int num = countDao.countDataByCondition(params);
if ( num > 0 ) {
  //當存在時,執行這里的代碼
} else {
  //當不存在時,執行這里的代碼
}

2??優化之后

select 1 from table where a = 1 AND b = 2 limit 1;

業務代碼:

##### Java寫法:
Integer exist = existDao.existDataByCondition(params);
if ( exist != NULL ) {
 //當存在時,執行這里的代碼
} else {
 //當不存在時,執行這里的代碼
}

sql 不再使用 count,而是改用 limit 1,讓數據庫查詢時遇到一條就返回,不要再繼續查找還有多少條。明知只有或者只要一條查詢結果,使用 “limit 1”,可以避免全表掃描,找到對應結果就不會再繼續掃描了。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,106評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,441評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,211評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,736評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,475評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,834評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,829評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,009評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,559評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,306評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,516評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,038評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,728評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,132評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,443評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,249評論 3 399
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,484評論 2 379

推薦閱讀更多精彩內容