2

私のDBには約150KDocumentNamesのレコードがあり、私がしているのはNameTypes. NameTypeID は DocumentNames の外部キーです。

これは私のクエリです:

With cte as 
(
    Select ROW_NUMBER() OVER 
    (Order By nm.Name asc ) 
    peta_rn,    
    dn.DocumentNameID,
    dn.DocumentID  
    From DocumentNames dn

    Left Join NameTypes nm On dn.NameTypeID = nm.NameTypeID
) 
Select * from cte Where peta_rn >= 10000 And peta_rn <= 10050

これはスクリーンショットです:

ここに画像の説明を入力

ソートには 90% のコストがかかります。この時点で何をすべきか完全に混乱しています。頭をたたきたいけど周りに人がいるからできない。どうすればいいですか?

4

3 に答える 3

3

なんらかの理由 (就職の面接など) で、このようなクエリを最適化する必要がある場合は、UNION.

[エイリアス列を認識するように修正]

With cte as 
(
  Select ROW_NUMBER() OVER 
  (Order By nm.Name asc ) AS
  peta_rn,    
  dn.DocumentNameID,
  dn.DocumentID  
  From DocumentNames dn

  INNER Join NameTypes nm On dn.NameTypeID = nm.NameTypeID /* note change */
),  
cte2 as 
(
  Select ROW_NUMBER() OVER 
  () AS /* yes, this is random */
  peta_rn,    
  dn.DocumentNameID,
  dn.DocumentID  
  From DocumentNames dn

  WHERE dn.NameTypeID  NOT IN SELECT (nm.NameTypeID FROM NameTypes nm)
) 

Select * from cte Where peta_rn >= 10000 And peta_rn <= 10050

UNION

Select * from cte2 Where peta_rn >= 10000 And peta_rn <= 10050

私はUNIONCTE を使用したことがないため、これを有効にするには追加の括弧が必要になる場合があります。また、ORDER BY結果全体の です。それは演習として残しておきます。

ポイントは、INNER JOINが のインデックスを使用できるようになるnm.Name一方で、2 番目の節がインデックス付きの反セミジョインを実行できることです。2 つのインデックス付きクエリは、1 つのインデックスなしクエリよりもはるかに高速です。

于 2013-04-04T14:07:32.053 に答える