2022.06.22
SQLチューニング(第31回)「NULL処理構文の理解と効率的なSQLの作成」(7/7回)
「NULL処理構文の理解と効率的なSQLの作成」の7回目は、「’ ‘(BLANK)とNULLデータ処理」についてのお話です。それでは、始めましょう。
7.7 ’ ‘(BLANK)とNULLデータ処理
7.7.1 ’ ‘(BLANK)データはNULLか?
WITH T AS (
SELECT NULL AS C1 FROM DUAL
UNION ALL
SELECT ' ' FROM DUAL
)
SELECT 'NULL', COUNT(*)
FROM T
WHERE C1 IS NULL
UNION ALL
SELECT 'NOT NULL',COUNT(*)
FROM T
WHERE C1 IS NOT NULL ;
'NULL' COUNT(*)
------------ --------
NULL 1
NOT NULL 1
”(以下空白)はNULLではなくNOT NULLデータであることを確認できます。 空白は、文字の中で最も小さい値でアスキーコードを文字に置き換えるCHR関数で表現するとCHR(0)です。 これは、空白がNULL以外の文字であることを意味します。
7.7.2 TRIM & NVL処理
空白データにTRIM関数を使用した後、NVL処理をするとどうなるか確認してみましょう。 TRIM関数は、列の前/後の空白データを取り除く関数で、空白が入力されている列にTRIM関数を使用すると、以下のようにNULLと認識することがわかります。
WITH T AS (
SELECT NULL AS C1 FROM DUAL
UNION ALL
SELECT ' ' FROM DUAL
)
SELECT COUNT(*)
FROM T
WHERE NVL(TRIM(C1),'ISNULL') = 'ISNULL' ;
COUNT(*)
----------
2
上記のようにNVLで抽出されるデータ件数が2件なので、空白データがNULLと認識されることが分かる。
7.7.3 ’ ‘とNULLデータ処理関連性能問題
SQLチューニングをしていると、以下のように照会される場合が見られるが、Where節の意味はカラムデータのうち空欄とNULLデータの両方を抽出しようとする時に使われます。
…
WHERE (
RESULT = ' '
OR RESULT IS NULL
)
このようなSQLはカラムRESULTにインデックスがあっても、Full Table Scanを選択することになって性能問題を引き起こすことがあります。 このような場合Oracleが提供するFunction Based Indexを生成して、Where節を下記のように変えれば、効率的なインデックス処理が可能となります。
-新規INDEX生成
CREATE INDEX … ( NVL(TRIM(RESULT),’ISNULL’) );
-変更WHERE CLAUSE
…
WHERE NVL(TRIM(RESULT),'ISNULL') = 'ISNULL'
今までNULLに対する基本的な内容と、NULLデータをどのように処理するべきかに対して調べてみてきました。 そしてNULLデータを処理する時、どのようにSQLを作成することで、効率的な実行になるのかに対しても調べてみてきました。 NULLデータを扱うにあたって誤った処理はデータ完全性をき損できるだけでなく性能問題も発生させることがあるので注意して使わなければなりません。 今回の場を通じてNULLデータ処理に対するより深い理解をして、今後データ完全性と性能という二匹のウサギを全部捉えることができるようになることを願います。
7回にわたってお伝えしてきました「NULL処理構文の理解と効率的なSQLの作成」は今回が最後です。いかがでしたでしょうか?次回からは、「日データ関連関数紹介」と題しまして、3回シリーズでお送りします。ご期待下さい。では、see you ^^