1

5 つのテーブルからのデータを必要とするクエリを作成しています。過去にDBAから、パフォーマンス/メモリの観点から、列のリストを指定するよりもすべての列を取得する(*)方が好ましいと言われました。また、FROM 句にテーブルのリストがある場合、データベースは舞台裏で JOIN 操作を実行し、1 つのテーブル (またはビュー) を作成すると言われています。

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

追加: 現在、MS SQL Server 2008 R2 を使用しています。

私の質問は次のとおりです。

  1. 以下の間にパフォーマンスの違いはありますか、またその理由は次のとおりです。SELECT ... FROM tbl1, tbl2, tbl3 などを簡単にするために?(どういうわけか、これはパフォーマンス ヒットになる可能性があると感じています) b. SELECT ... FROM tbl1 inner join tbl2 on ... inner join tbl3 on ... etc (これはサーバーにとってより明示的であり、パフォーマンス/メモリを節約できますか)? c. SELECT ... FROM (select x,y,z from tbl1) as t1 inner join ... etc (これで何か節約できますか? それとも、サーバーと私たちにとってより多くの作業を作成する追加の select ステートメントですか?)

  2. これを行うためのより良い方法はまだありますか?

以下は、必要なデータのスライスを取得する 2 つのクエリです。1 つには、さらにネストされた select ステートメントが含まれます。

それらが標準的な形式で書かれていない場合やどうしようもなく複雑すぎる場合は申し訳ありませんが、解読していただければ幸いです。それらをできるだけ整理しておくようにしています。

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

5 つのテーブル: devicepool、users、trips、TripTracker、orders

クエリ 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)
4

1 に答える 1

5

次の間にパフォーマンスの違いがありますか、またその理由は次のとおりです。簡単にするために、tbl1、tbl2、tbl3などから...を選択しますか?(どういうわけか、これはパフォーマンスのヒットになるかもしれないと思います)b。SELECT ... FROM tbl1 internal join tbl2 on ... internal join tbl3 on ... etc(これはサーバーに対してより明示的であり、パフォーマンス/メモリを節約しますか?)c。SELECT ... FROM(select x、y、z from tbl1)as t1 internal join ... etc(これは何かを保存しますか?それとも、サーバーと私たちのためにより多くの作業を作成する追加のselectステートメントですか?)

a)とb)は、同じクエリプランになります(ただし、これはデータベース固有です)。b)は、a)よりも移植性と読みやすさの点で非常に好まれます。c)は恐ろしい考えであり、読みやすさを損ない、どちらかといえばパフォーマンスを低下させることになります。二度とそれについて話さないようにしましょう。

これを行うためのより良い方法はまだありますか?

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

于 2011-12-22T15:28:05.263 に答える