2017-07-20 46 views
2

私は2つのデータベーステーブルがあります:私は間のセンサ値を取得するためにそれらを結合 SQL Serverの:遅いクラスタ化インデックス

値メッセージセンサーが含まれているGPSメッセージ

  • MessageDataが含まれてい

    1. Messageテーブルを2つの日付。

      クエリは、クラスタ化インデックスを検索するのに99%の時間を要して結果をゆっくり返します。

      このパフォーマンスを改善するにはどうすればよいですか?インデックスやクエリ側のアドバイスはありますか?

      私が参加するため、次のクエリを実行します。私は、これらのインデックスを持っている

      SELECT 
          t.MessageId, t.DataSourceId, t.[Value], 
          DataSource.SourceNameId, DataSource.Name 
      FROM 
          [MessageData] t 
      INNER JOIN 
          [Message] m ON t.MessageId = m.MessageId 
      LEFT JOIN 
          DataSource ON t.DataSourceId = DataSource.DataSourceId 
      WHERE 
          t.MessageId > 3264353049 
          AND m.ObjectId = @objId 
          AND m.GpsTime BETWEEN @dtFrom AND @dtTo 
          AND m.Valid = 1; 
      

      Query plan time ?

      query plan screen2

      最後の年から行と日付を求める防ぐために、主キー> 3264353049でフィルタ:

      ALTER TABLE [MessageData] 
          ADD CONSTRAINT [AnalogData_PK] 
          PRIMARY KEY CLUSTERED ([MessageId] ASC, [DataSourceId] ASC) 
      
      CREATE NONCLUSTERED INDEX [MessageData_DataSourceId_IDX] 
      ON [MessageData] ([DataSourceId] ASC) 
      GO 
      
      CREATE NONCLUSTERED INDEX [IX_gpstime_objectid] 
      ON [Message] ([GpsTime] ASC) 
      INCLUDE ([MessageId], [ObjectId]) 
      GO 
      
      CREATE UNIQUE CLUSTERED INDEX [Message_Object_UK] 
      ON [Message] ([ObjectId] ASC, [GpsTime] ASC, [MessageId] ASC) 
      GO 
      

      メッセージテーブルデータ:

      MessageId   ObjectId VectorAngle VectorSpeed Altitude GpsTime      X      Y      VisibleSatelites 
      -------------------- ----------- ----------- ----------- ----------- ------------------------------ ---------------------- ---------------------- ---------------- 
      9988600080   192   0   0   0   2017-07-19 00:03:20   0    0    0 
      9988600082   192   0   0   0   2017-07-19 00:08:20   0    0    0 
      9988600086   192   0   0   0   2017-07-19 00:13:20   0    0    0 
      9988600089   192   0   0   0   2017-07-19 00:18:20   0    0    0 
      9988600092   192   0   0   0   2017-07-19 00:23:20   0   0    0 
      

      MessageData表データ:

      MessageId   DataSourceId Value     SourceNameId Name 
      -------------------- ------------ ---------------------- ------------ ------------------------------ 
      9988600080   6364   0      1   Engine 
      9988600080   6365   0      2   Digital Input Status 2 
      9988600080   325346  0      179   DOUT 1 
      9988600080   325347  0      180   DOUT 2 
      9988600080   334214  0      69   Bettary 
      9988600082   6364   0      1   Engine 
      9988600082   6365   0      2   Digital Input Status 2 
      9988600082   325346  0      179   DOUT 1 
      9988600082   325347  0      180   DOUT 2 
      9988600082   334214  0      69   Bettary 
      9988600086   6364   0      1   Engine 
      9988600086   6365   0      2   Digital Input Status 2 
      9988600086   325346  0      179   DOUT 1 
      9988600086   325347  0      180   DOUT 2 
      9988600086   334214  0      69   Bettary 
      9988600089   6364   0      1   Engine 
      9988600089   6365   0      2   Digital Input Status 2 
      9988600089   325346  0      179   DOUT 1 
      9988600089   325347  0      180   DOUT 2 
      9988600089   334214  0      69   Bettary 
      9988600092   6364   0      1   Engine 
      9988600092   6365   0      2   Digital Input Status 2 
      9988600092   325346  0      179   DOUT 1 
      9988600092   325347  0      180   DOUT 2 
      9988600092   334214  0      69   Bettary 
      
  • +0

    マージ結合? –

    +0

    @SahanSerasingheどのようにそれを改善するために、任意のアドバイスのインデックス側、クエリ参加側? –

    +0

    あなたのWHERE *はおそらくあなたがやろうとしていることをしていません。 JOINの後に実行されるフィルタリングメカニズムはWHEREです。だから、あなたは*おそらく*いくつのレコードをつかむことに制限していない*。オプティマイザがクエリの処理方法を最終的に決めるため、オプティマイザが最終的にクエリを異なる方法で解釈する可能性があるため、おそらく*と言います。 – yanman1234

    答えて

    0

    だけでなく、コメントに記載された私は間違いなく私の統計情報を更新します。しかし、その後、私は、このインデックスになります。

    CREATE UNIQUE CLUSTERED INDEX [Message_Object_UK] 
    ON [Message] ([ObjectId] ASC, [GpsTime] ASC, [MessageId] ASC) 
    

    それはシークとの各レコードの撤退を持っている特定のメッセージIDを持つレコードを見つける必要があるため、クエリが厄介なネステッド・ループが参加することをやっていますメッセージテーブルインデックスそれを変更してみてください:

    CREATE UNIQUE CLUSTERED INDEX [Message_Object_UK] 
    ON [Message] ([MessageId] ASC, [ObjectId] ASC, [GpsTime] ASC) 
    

    これはあなたのハッシュを得ることのチャンスを持っているか、そう、あなたの質問は何ですか

    +0

    ですが、ここではMessageIdが主キーです。その場合、主キー索引を探しますか? –

    +0

    スクリプトから、MessageIDはMessageDataテーブルの主キーです。私はあなたのメッセージテーブルにPKが何であるか分かりません。 –

    +0

    いいえ、MessageID Messageの主キーです。MessageDataキーはクラスタ化インデックス[MessageId、DatasourceId]であり、そのインデックスはクエリ時間の99%になります –

    関連する問題