2016-05-17 77 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) 
) 

表認爲被附加到在一天內多次帳戶位置的數據。表中目前有大約2400萬行。每次我們添加額外的職位時,我們都會爲此表添加約32,000個條目,並且所有32,000個條目都具有相同的load_id。每當我們加載一批32,000個條目時(即,第一個32K條目具有load_id = 1,下一個32K具有load_id = 2等等),load_id就加​​1。

datetime_stamp字段顯示條目加載的時間,並且對於單個加載中的所有32K條目都是相同的。 例如,今天上午9點,職位首先被加載到表格中。在一天結束時,我們想知道在上午9點加載的職位。

根據上述表定義檢索當天的第一個位置負載的最有效方法是什麼?

我最初的(簡單)的答案是簡單地

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查詢Positions。如果不知道系統是否值得將較舊的行存檔到單獨的表中,您仍然可以使用UNION在整個集合中進行查詢,但是會提高最近數據的性能。 – OldBoyCoder

+1

這個網站不是reddit。 –

回答

0

,你可以嘗試以下方法:

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

2)這會給你第一個記錄,其中datetime_stamp等於datetime_stamp上午9時加載的。您將從此記錄中獲得9 AM加載的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;