2016-05-17 5 views
1

私はredditに投稿して新しくなりました。私は自分のSQLスキルを磨くように努力してきて、次のように走った。 として定義されているテーブルがあります:テーブル検索の最適化(大)

CREATE TABLE [Positions]( 
    [load_id] [int] NOT NULL, 
    [acct_cd] [varchar](20) NOT NULL, 
    [acct_num] [varchar](255) NULL, 
    [sec_id] [varchar](50) NOT NULL, 
    [long_sht_cd] [varchar](3) NOT NULL, 
    [sedol] [varchar](15) NULL, 
    [isin] [varchar](15) NULL, 
    [cusip] [varchar](9) NULL, 
    [sec_type] [varchar](8) NULL, 
    [sec_name] [varchar](100) NULL, 
    [currency_cd] [varchar](3) NULL, 
    [total_holding] [decimal](18,4) NULL, 
    [mkt_price] [float] NULL, 
    [datetime_stamp] [datetime] NULL, 
CONSTRAINT [pk_Positions] PRIMARY KEY CLUSTERED (
    [load_id] ASC, 
    [acct_cd] ASC, 
    [sec_id] ASC, 
    [long_sht_cd] ASC) 
) 

表には、複数回の日に追加されたアカウントの位置データを保持しています。現在、テーブルには約2,400万行があります。追加のポジションを追加するたびに、このテーブルに約32,000のエントリが追加され、32,000のエントリはすべて同じload_idになります。 load_idは、32,000エントリのバッチをロードするたびに1ずつインクリメントされます(つまり、最初の32Kエントリはload_id = 1、次の32Kはload_id = 2など)。

datetime_stampフィールドは、エントリがロードされた時間を示し、1回のロードですべての32Kエントリで同じです。 たとえば、今日、ポジションは最初に午前9時などにテーブルにロードされました。その日の終わりに、午前9時にどのポジションがロードされたかを知りたいと思います。

上記の表の定義で、1日の最初の位置の読み込みを取得する最も効率的な方法は何ですか?

私の最初の(単純な)答えは単純

SELECT * FROM Positions 
WHERE datetime_stamp = todays_date_9am; 

になります。しかし、私はナイーブされています知っています。テーブルが大量であるので、私は、load_idを利用して、より長いものの代わりに検索O(1)を行うことができるはずであることを知っているはずです。

提案がありますか?ありがとうございました。

+0

あなたが提示したクエリのパフォーマンスを向上させるために 'datetime_stamp'列にインデックスを追加することができます。 –

+0

また、load_idとdatetime_stampだけで小さなテーブルを保持し、負荷をかけるたびにそのテーブルを設定することもできます。次に、最初からload_idを取得してから、load_idに基づいて位置を照会することができます。古い行を別のテーブルにアーカイブする価値があることがわかっていなくても、UNIONを使用して完全なセット全体をクエリできますが、最近のデータのパフォーマンスを向上させることができます。 – OldBoyCoder

+1

このサイトはレッドではありません。 –

答えて

0

次を試すことができます。

1) SELECT top(1) * FROM Positions 
WHERE datetime_stamp = todays_date_9am; 

2)これは、あなたdatetime_stampは、午前9時の負荷のdatetime_stampに等しい最初のレコードを与えるだろう。このレコードから午前9時にLoadIdを取得します。

3)LoadIdが主キーの一部であるため、このLoadIdを使用して必要なレコードを取得できるようになりました。

select * from Positions 
WHERE LoadId = 9_AM_LoadId 
+0

とにかくテーブルスキャンを行うdatetime_stampのインデックスがありません。少なくとも、top(1)loadIdを選択して、ネットワーク上を移動するデータを減らします。ロードタイムスタンプに対するloadidを別のテーブルに格納するというコメントで私の提案に従う方が良いでしょう。 – OldBoyCoder

+0

@OldBoyCoder:テーブルスキャン全体を行うのではなく、タイムスタンプが一致する最初のレコードを選択するだけです。サーバーに負荷がかかりすぎることはありません。 –

+0

しかし、それはどのようにその行を見つけるのだろうか?インデックスがないので、datetime_stampにマッチするものが見つかるまで、最初のクエリがテーブル全体をスキャンする必要があります。幸運なことに早ければそれを見つけることができますが、それに対してオッズは反対です。 – OldBoyCoder

0
CREATE NONCLUSTERED INDEX ix_Positions_datetime_stamp 
ON [Positions] ([datetime_stamp]); 

このインデックスは次のクエリをサポートします:

SELECT 
    MIN([load_id]) AS StartID 
FROM 
    [Positions] 
WHERE 
    [datetime_stamp] = todays_date_9am; 
関連する問題