sql >> データベース >  >> RDS >> Sqlserver

SQLで2つの選択または1つの選択+ 1つの結合?

    彼らが同じ仕事をするべきだというあなたの考えは真実ではありません。このデータのテスト セットを想像してみてください:

    T1

    ID
    ----
    1
    2
    3
    4
    5
    

    T2

    ID
    ---
    1
    1
    1
    2
    2
    3
    

    DDL

    CREATE TABLE dbo.T1 (ID INT NOT NULL);
    INSERT dbo.T1 (ID) VALUES (1), (2), (3), (4), (5);
    
    CREATE TABLE dbo.T2 (ID INT NOT NULL);
    INSERT dbo.T2 (ID) VALUES (1), (1), (1), (2), (2), (3);
    
    SELECT  *
    FROM    dbo.T1
    WHERE   T1.ID IN (SELECT T2.ID FROM dbo.T2);
    
    SELECT  T1.*
    FROM    dbo.T1
            INNER JOIN dbo.T2
                ON T1.ID = T2.ID;
    

    結果

    ID
    ---
    1
    2
    3
    
    ID
    ---
    1
    1
    1
    2
    2
    3
    

    検索する列が一意である場合にのみ、結果は同じになります。

    CREATE TABLE dbo.T1 (ID INT NOT NULL);
    INSERT dbo.T1 (ID) VALUES (1), (2), (3), (4), (5);
    
    CREATE TABLE dbo.T2 (ID INT NOT NULL);
    INSERT dbo.T2 (ID) VALUES (1), (2), (3);
    
    SELECT  *
    FROM    dbo.T1
    WHERE   T1.ID IN (SELECT T2.ID FROM dbo.T2);
    
    SELECT  T1.*
    FROM    dbo.T1
            INNER JOIN dbo.T2
                ON T1.ID = T2.ID;
    

    結果は同じですが、実行計画は異なります。 IN を使用した最初のクエリ つまり、t2 のデータが不要であることを認識しているため、単一の一致が見つかるとすぐに、それ以上の一致のスキャンを停止できます。

    2 番目のテーブルを一意の値のみを持つように制約すると、同じプランが表示されます:

    CREATE TABLE dbo.T1 (ID INT NOT NULL PRIMARY KEY);
    INSERT dbo.T1 (ID) VALUES (1), (2), (3), (4), (5);
    
    CREATE TABLE dbo.T2 (ID INT NOT NULL PRIMARY KEY);
    INSERT dbo.T2 (ID) VALUES (1), (2), (3);
    
    SELECT  *
    FROM    dbo.T1
    WHERE   T1.ID IN (SELECT T2.ID FROM dbo.T2);
    
    SELECT  T1.*
    FROM    dbo.T1
            INNER JOIN dbo.T2
                ON T1.ID = T2.ID;
    

    要約すると、2 つのクエリが常に同じ結果をもたらすとは限らず、常に同じ計画を持つとは限りません。これは、インデックスとデータ/クエリの幅に大きく依存します。



    1. MySQL:エイリアスを列として使用

    2. PHPとMySQLを使用してマルチレベルのJSONを作成する

    3. mysqlでは、showdatabases。コマンドは私のデータベースのすべてをリストしません

    4. SQL Server 2008でテーブルを説明するにはどうすればよいですか?