1

このタイプのクエリが何と呼ばれているのかわからないため、適切に検索できませんでした。テーブルが 2 つあり、テーブル A には約 10,000 行あります。テーブル B には可変数の行があります。

テーブル A のすべての結果を取得するクエリを作成したいのですが、列を追加すると、その列の値は、結果がテーブル B にも表示されるかどうかを示すブール値になります。

私はこのクエリを作成しましたが、これは機能しますが遅いです。ブール値を使用するのではなく、0 または 1 になるカウントを使用します。提案された改善は、感謝して受け入れられます。

SELECT u.number,u.name,u.deliveryaddress, 
            (SELECT COUNT(productUserid) 
             FROM ProductUser 
             WHERE number = u.number and productid = @ProductId) 
             AS IsInPromo

FROM Users u

アップデート

実際の実行計画を有効にしてクエリを実行しましたが、結果を表示する方法がわかりませんが、さまざまなコストは次のとおりです。

ネストされたループ (左半結合): 29%]

クラスター化インデックス スキャン (ユーザー テーブル): 41%

クラスタ化インデックス スキャン (ProductUser テーブル): 29%

数値 users テーブルには 7366 人のユーザーがおり、productUser テーブルには現在 18 行あります (ただし、これは変更され、数千になる可能性があります)

4

3 に答える 3

4

一致するすべての行を -ing するのEXISTSではなく、最初の行が見つかった後に短絡するために使用できます。COUNT

SQL Server にはブール データ型がありません。最も近いものはBIT

SELECT u.number,
       u.name,
       u.deliveryaddress,
       CASE
         WHEN EXISTS (SELECT *
                      FROM   ProductUser
                      WHERE  number = u.number
                             AND productid = @ProductId) THEN CAST(1 AS BIT)
         ELSE  CAST(0 AS BIT)
       END AS IsInPromo
FROM   Users u 

RE: 「このタイプのクエリの名前がわかりません」. これにより、半結合のある計画が得られます。詳細については、CASE 式のサブクエリを参照してください。

于 2013-03-29T10:26:02.323 に答える
1

どの管理システムを使用していますか? これを試して:

SELECT u.number,u.name,u.deliveryaddress, 
            case when COUNT(p.productUserid) > 0 then 1 else 0 end
FROM Users u
left join ProductUser p on p.number = u.number and productid = @ProductId
group by u.number,u.name,u.deliveryaddress

UPD: これは mssql を使用すると高速になる可能性があります

;with fff as
(
    select distinct p.number  from ProductUser p where p.productid = @ProductId
)
select u.number,u.name,u.deliveryaddress,  
    case when isnull(f.number, 0) = 0 then 0 else 1 end 
from Users u left join fff f on f.number = u.number 
于 2013-03-29T10:31:09.007 に答える
-1

パフォーマンスを懸念しているように見えるため、このクエリはindex seek、テーブルとテーブルの両方で発生するため、より高速に実行できindex scanます。

SELECT u.number,
       u.name,
       u.deliveryaddress,       
       ISNULL(p.number, 0)  IsInPromo
FROM   Users u 
       LEFT JOIN ProductUser p ON p.number = u.number
WHERE   p.productid = @ProductId
于 2013-03-29T10:33:28.710 に答える