2017-10-04 5 views
5

SQLコードが正しくない可能性があるさまざまな状況を説明する記事があります。しかし、私には驚くべきことが1つあるpointです。彼らはISNULLのない状態は臭いですか?

を主張し、明示的にNULL可能列にNULLを処理するために賢明である、

ISNULLデフォルト値を提供するために、COALESCEを使用することにより、同様言及されています。彼らはまたISNULLと例を与えるこのMSDN web pageを参照します。結果は全くISNULLに影響されない、一方で、ここでの基本的な考え方は、その後、

SELECT COUNT(*) FROM [dbo].[Table1] WHERE [c2] > 2; 

SELECT COUNT(*) FROM [dbo].[Table1] WHERE ISNULL([c2],0) > 2; 

を使用した方が良いということですが、第一の変形は、SARGではありません。私は、しかし、私は常に述語でNULLを処理するためにIS NULLまたはIS NOT NULLを使用しようとすると、出力にISNULLまたはCOALESCEを使用してNULLを処理する必要性を理解しています。私は何かが恋しいですか? MSDNの問題点は何ですか?

EDIT:議論をし、主にこのpostに反応するために、私は簡単なテスト

IF OBJECT_ID('dbo.LogTable', 'U') IS NOT NULL DROP TABLE dbo.LogTable 

SELECT TOP 100000 DATEADD(day, (ABS(CHECKSUM(NEWID())) % 65530), 0) datesent , 
     CASE WHEN (ABS(CHECKSUM(NEWID())) % 100) = 1 THEN NULL ELSE (ABS(CHECKSUM(NEWID())) % 1000) END ivalue 
INTO [LogTable] 
FROM sys.sysobjects 
CROSS JOIN sys.all_columns 

CREATE INDEX ix_logtable_ivalue ON LogTable(ivalue asc) INCLUDE(datesent); 

-- Q1 
select * from logtable where isnull(ivalue, 0) > 998 

-- Q2 
select * from logtable where ivalue > 998 

しかし、第1四半期のivalueがSARGではありません用意しました。何かキャッチはありますか?この特定のデータとクエリに対してSARG属性をどのように設定する必要がありますか?あなたが提供した例では

+4

あなたは正しいです。インデックスの使用を妨げる可能性があるので、不要な 'NULL'チェックを入れないでください。 'IS NULL' /' IS NOT NULL'を強くお勧めします。これらはANSIの標準構造です。 –

+9

この例は、改善のために悪いデータベースコードを検出すると主張するものから来ているという事実は非常に気になるものです。あなたは 'NULL 'になる可能性のある値を比較するときに何が起こるか考える必要がありますが、反射的に' ISNULL'をどこに置いても間違っています。 –

+0

'MSDNの問題点は何ですか? ' Dunno :-) [元のソース](https://www.red-gate.com/simple-talk/sql/t-sql-programming/sql-code-smells/#not-handling-null- [MSDN(https://msdn.microsoft.com/en-us/library/dd172133(V = VS.100)からで-null許容-列値 - )のものを計算しながら、理にかなっているが、与えられた例の.aspx)完全に間違っている。 –

答えて

6

isnullチェックは無意味です。 「真」ではありませんので、これらの行は、とにかく、クエリから除外されますnull > 2戻りnull、。そのような方法でisnullを使用すると、c2のインデックスがオプティマイザで使用できなくなります。要するに

- これが悪いアドバイスのように聞こえます。

+1

"null> 2がnullを返します" - いいえ、この比較は不明を返します。少し賢明だが、nullは混乱している。ポイントはまだ正しいです - ヌルをチェックする理由はありません。 – SMor

+1

@SMor:ブーリアンデータ型は事実上T-SQLにしか存在しないので、非常にペダンティックです。実際に存在していれば(それは非常に便利だと思う)、UNKNOWNの結果がNULLで表されることはほぼ確実です。しかし、「NULL」がUNKNOWNよりどのように「もっと混乱している」のかは分かりませんが、それはまず最初に問題があるからです。 –

+0

'Pankaj Manekがここに明るく示されているように' 'インデックススキャン 'が発行されるかもしれないので、オプティマイザがc2のインデックスを使用しないようにisnullを使用することは禁止されます(http: /www.sqlservercentral.com/blogs/sqlyse-with-pankaj-manek/2015/08/20/isnull-around-the-predicate-and-sargability/)。この文は、 '' index seek''にも当てはまります。 –

関連する問題