2016-05-17 86 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;