2011-12-22 9 views
1

5つのテーブルのデータが必要なクエリを作成しています。 過去のDBAから、列のリストの指定とすべての列(*)を指定することは、パフォーマンス/メモリーの観点から優先されると言われました。 私はまた、データベースがFROM句にテーブルのリストがあるときに、1つのテーブル(またはビュー)を作成するためにシーンの背後でJOIN操作を実行すると言われました。FROM句のネストされたselect文?内部結合ステートメントまたは単にテーブル名ですか?

私たちは非常に初期の段階であるため、既存のデータベースのデータはほとんどありません。実際にパフォーマンスヒットを測定できるかどうかは分かりません。 私はデータベースプロではありません。私は必要なデータを得ることができます。ディレマは、どんな価格である。

追加:現時点では、私はMS SQL Server 2008 R2を使用しています。

私の質問は以下のとおりです。 :

  1. は、以下の間、パフォーマンスの違いとその理由あります。 SELECT ...簡単にするためにtbl1、tbl2、tbl3などから? (何とか私はこれがパフォーマンスヒットかもしれないと感じている) b。 SELECT ... FROM tbl1 inner join tbl2 on ... inner join tbl3 on ...など(これはサーバーに明示的になり、パフォーマンス/メモリに保存されますか?) c。 SELECT ... FROM(tbl1からx、y、zを選択)をt1 inner join ...などとします(これはanythigを保存しますか?それとも、サーバーと私たちにとってより多くの作業を作成する余分なselect文ですか)。

  2. もっと良い方法がありますか?

以下は、必要なデータスライスを取得する2つのクエリです。 1つはネストされたselect文を含んでいます。

標準的な書式で書かれていないか、無謀に複雑すぎると謝っています。うまくいけば解読できます。私はそれらを可能な限り整理しておくようにしています。

洞察が最も高く評価されます。 これをチェックしていただきありがとうございます。

5テーブル:のDevicePool、ユーザー、旅行、TripTracker、注文

クエリ1(もっとSELECT文):

SELECT 
     username, 
     base.devid devid, 
     tripstatus, 
     stops, 
     stopnumber, 
     [time], 
     [orderstatus], 
     [destaddress] 

FROM  
((
( SELECT 
      username, 
      devicepool.devid devid, 
      groupid 
    FROM 
      devicepool INNER JOIN users 
      ON devicepool.userid = users.userid 

    WHERE devicepool.groupid = 1 
) 
AS [base] 

INNER JOIN 

(
     SELECT 
       tripid, 
       [status] tripstatus, 
       stops, 
       devid, 
       groupid 

     FROM 
       trips 
) 
AS [base2] 

ON base.devid = base2.devid AND base2.groupid = base.groupid 

INNER JOIN 

(
    SELECT 
      stopnumber, 
      devid, 
      [time], 
      MAX([time]) OVER (PARTITION BY devid) latesttime 
    FROM 
      TripTracker 
) 

AS [tracker] 
ON tracker.devid = base.devid AND [time] = latesttime) 

INNER JOIN 

(
     SELECT 
      [status] [orderstatus], 
      [address] [destaddress], 
      [tripid], 
      stopnumber orderstopnumber 
     FROM [order] 
) 
AS [orders] 

ON orders.orderstopnumber = tracker.stopnumber) 

クエリ2:

SELECT 
     username, 
     base.devid devid, 
     tripstatus, 
     stops, 
     stopnumber, 
     [time], 
     [orderstatus], 
     [destaddress] 

FROM  
((
( SELECT 
      username, 
      devicepool.devid devid, 
      groupid 
    FROM 
      devicepool INNER JOIN users 
      ON devicepool.userid = users.userid 

    WHERE devicepool.groupid = 1 
) 
AS [base] 

INNER JOIN 

    trips 

ON base.devid = trips.devid AND trips.groupid = base.groupid 

INNER JOIN 

(
    SELECT 
      stopnumber, 
      devid, 
      [time], 
      MAX([time]) OVER (PARTITION BY devid) latesttime 
    FROM 
      TripTracker 
) 

AS [tracker] 
ON tracker.devid = base.devid AND [time] = latesttime) 

INNER JOIN 

    [order] 

ON [order].stopnumber = tracker.stopnumber) 
+2

**適切なJOIN **構文 - INNER JOIN'、 'LEFT OUTER JOIN'などを使用することをお勧めします。これはa)ANSI標準であり、b)あなたがしたいことをSQLコードを読んでいる誰かにはっきりと明白であり、c)関与するテーブル間のJOIN条件を忘れて誤ってデカルト製品を導入しないでください。 –

+0

これはSQLEXPRESSとコードから実行されます。私は現在、SQLEXPRESSをデータベースサーバーとして使用しています。それがその質問にどのように関連しているのかを教えてください。 – RoyM

+1

私はちょうど確認しました - SQL Server 2008 R2のように見えます。もう一度更新します。 – RoyM

答えて

5

がありますパフォーマンスの違いとその理由は、次の間:a。 SELECT ...単純化のためにtbl1、tbl2、tbl3などから? (何とか私は がパフォーマンスヒットかもしれないと感じている)b。 SELECT ... FROM tbl1 inside tbl2に参加する... inner join tbl3 on ...など(これはサーバに明示的になり、パフォーマンス/メモリに保存されます) c。 SELECT ... FROM(tbl1からx、y、zを選択)をt1 inner join ...などとします( はanythigを保存しますか?それとも、サーバーと私たちのためにさらに を作成する余分なselect文ですか) ?

a)とb)は同じクエリプランになります(これはdbに固有です)。b)は、a)よりも移植性と可読性に優れています。 c)はひどい考えであり、読みやすさに害を及ぼします。もう一度それを話してはいけません。

もっと良い方法がありますか?

b)が標準的なアプローチです。一般的に、一番平易なANSI SQLを記述すると、クエリパーサーが実行しようとしていることを簡単に理解できるため、最高のパフォーマンスが得られます。トリックでコンパイラを凌駕しようとすると、特定の状況でうまくいく可能性がありますが、カーディナリティやデータ量が変更されたときやデータベースエンジンがアップグレードされたときにも機能するというわけではありません。だから、あなたが絶対に強制されない限り、それを避けてください。

+0

+1良い指導!私は間違いなく選択肢b)でも行くだろう! –

+0

あなたの答えをありがとう! – RoyM

関連する問題