天天看點

ABAP-SQL 存在性校驗:查詢某一資料庫表是否存在一條{select single | up to 1 rows | select count(*)}問題描述:問題分析:結論:PS:

問題描述:

當我們需要确認某一資料表中是否存在某一資料時,有多種方式,但哪種是最優的呢?

使用single : 在where語句中如果使用了全部的key字段才可以使用single
single 取第一個符合條件的資料,不需要繼續再查找下去。
SELECT SINGLE *
	FROM dbtab	
	INTO (field)
	WHERE any_key.
IF sy-subrc = 0.
   …
ENDIF.
           
使用up to 1 rows : 在where語句中如果使用了部分或沒有使用key字段,則隻能使用up to 1 rows。
up to 1 rows 先查找所有資料,再取一條符合條件的資料。
up to n rows 可以取n條資料。
SELECT *
	FROM dbtab
	UP TO 1 ROWS	
	INTO (field)
	WHERE any_key.
IF sy-subrc = 0.
   …
ENDIF.
           
相較于前兩者,貌似從性能的角度防止了資料從DB傳輸到ABAP(前兩者某些時候甚至需要定義臨時工作區或者額外的清空操作),
但同樣資料庫必須根據你的where條件讀取所有受影響的資料。在最壞的情況下,資料庫必須分析整個表資料。
SELECT COUNT(*) 
	FROM dbtab
 	WHERE any_key.
IF sy-subrc = 0.
   …
ENDIF.
           

問題分析:

分析條件,因為我這裡沒有支援abap 7.4及以上的虛拟機,一下結果搬自SAP社群,感興趣的可以親測測試一下,歡迎在評論區讨論。 資料庫表:LIPS 資料量:450w

  • where主鍵時

    count(*) 要優于其他方法,select single次之但性能相差不多,up to 1 row相當差。

  • where部分或無主鍵時
關于single : 在where語句中如果使用了全部的key字段才可以使用single。這是對于基于要取資料的目的而言的,因為其取到一個符合條件值後就不會再查詢下去了(有可能會取到錯誤的條目)。但如果隻是确認是否存在(比如我要确定表中某一天存在業務記錄),也是可以用的。

此時性能多取決于你要選取的條目在表中記錄的位置,however count(*) 都是最差的。

  1. 當記錄在表的開頭,select single最優(@abap_true > ),up to 1 rows次之,count()相當差。
  2. 當記錄在表的中間,select single @abap_true最優。
  3. 當記錄在表的最末尾,select single @abap_true和count(*)相當接近,并且優于up to 1 rows和select single * INTO

當然表中記錄的位置和生産資料量級通常我們是無法知曉的,是以無疑最新的select single @abap_true是最優的,不支援新文法則select single *最優。

結論:

基于上面的分析,結論如下:

當where條件為主鍵時,采用count(*) (說實話有些意外,我本以為count會周遊整個表的,而select single查到即終止,莫非主鍵時count到一條之後也會終止查詢嗎?有懂的歡迎評論區指摘)。

非主鍵時采用select single * into方式。

當然,如果查詢表是自建表,你對其資料量有所了解,或者幹脆是某種辨別表,count(*)我覺得也可以(前面的是大前提,分析部分的原作者測試顯示:非主鍵查詢條目在最後時,查詢時間從1微妙到2秒)。這點兒性能浪費相較于其他的優化來說實在不值一提。

PS:

關于select single count(),我沒找到任何資料來說明它會在計數到一個之後就會停止計數,當你輸出n的時候你就會發現,和select count()結果一樣。包括上面的其他語句其實本身都不是作為存在性校驗的sql語句存在的,那麼是否真的存在某種差異?

事實上:我用主鍵查詢一個物料時反倒是select count()更快。非主鍵時select single count()更快。so…