いくつかのSQL Tuningのドキュメントを読む私はこれを見つけました:
Select count(*)
:
- 行数をカウントします
- レコードの存在を確認するために不適切に使用されていることが多い
Select count(*)
は本当にそれほど悪いのでしょうか。
レコードの存在を確認するための適切な方法は何ですか?
以下のいずれかを使用することをお勧めします。
-- Method 1.
SELECT 1
FROM table_name
WHERE key = value;
-- Method 2.
SELECT COUNT(1)
FROM table_name
WHERE key = value;
最初の選択肢はあなたに結果がないか1つの結果を与えるべきです、2番目のカウントは0か1であるべきです。
あなたが使っているドキュメントは何歳ですか?良いアドバイスを読んだことがありますが、最近のRDBMSの最適化SELECT COUNT(*)
のほとんどのクエリオプティマイザーは、理論上の違いがありますが(そして古いデータベースでも)、実際には違いがあることに気付かないでください。
私はCount関数をまったく使わないほうがいいです。
IF [NOT] EXISTS ( SELECT 1 FROM MyTable WHERE ... )
<do smth>
たとえば、データベースに挿入する前にユーザーが存在するかどうかを確認したい場合、クエリは次のようになります。
IF NOT EXISTS ( SELECT 1 FROM Users WHERE FirstName = 'John' AND LastName = 'Smith' )
BEGIN
INSERT INTO Users (FirstName, LastName) VALUES ('John', 'Smith')
END
あなたが使用することができます:
SELECT 1 FROM MyTable WHERE <MyCondition>
条件に一致するレコードがない場合、結果のレコードセットは空です。
他の答えはかなり良いですが、不要な行のチェックを防ぐためにLIMIT 1
(または 相当する )を追加することも役に立ちます。
あなたが使用することができます:
SELECT COUNT(1) FROM MyTable WHERE ...
または
WHERE [NOT] EXISTS
( SELECT 1 FROM MyTable WHERE ... )
これはSELECT *
よりも効率的です。すべてのフィールドではなく、単に各行に値1を選択するだけだからです。
COUNT(*)とCOUNT(列名)の間にも微妙な違いがあります。
COUNT(*)
はnullを含む全ての行を数えますCOUNT(column name)
はカラム名のnull以外の出現のみをカウントしますSELECT COUNT(1) FROM MyTable WHERE ...
すべてのレコードをループします。これがレコードの存在のために使うのが悪い理由です。
私は使うだろう
SELECT TOP 1 * FROM MyTable WHERE ...
1レコードを見つけたら、ループを終了します。
あなたが使用することができます:
SELECT 1 FROM MyTable WHERE... LIMIT 1
不要なフィールドのチェックを防ぐためにselect 1
を使用してください。
不要な行のチェックを防ぐためにLIMIT 1
を使用してください。
その他のオプション:
SELECT CASE
WHEN EXISTS (
SELECT 1
FROM [MyTable] AS [MyRecord])
THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)
END
私はこのように使っています:
IIF(EXISTS (SELECT TOP 1 1
FROM Users
WHERE FirstName = 'John'), 1, 0) AS DoesJohnExist