0

仕事で MS SQL Server 2005 を使用してデータベースを構築しています。ほとんどのテーブルは、構築された後、近い将来に 1,000,000 ~ 500,000,000 行のデータを保持するようになると言われています... これほど大きなデータセットを扱ったことはありません。ほとんどの場合、スキーマ、クエリなどを設定する方法について、最善の答えが何であるかを理解するために何を検討すべきかさえわかりません。

だから...何かの開始日と終了日、およびその期間中にIDに関連付けられている値を知る必要があります。SO ... 2 つの異なる方法でテーブルを作成できます。

create table xxx_test2 (id int identity(1,1), groupid int, dt datetime, i int) 

create table xxx_test2 (id int identity(1,1), groupid int, start_dt datetime, end_dt datetime, i int) 

どちらが良いですか?どうすればより適切に定義できますか? 最初のテーブルに約 100,000 行のデータを入力し、クエリに応じて 2 番目のテーブルの形式でセットアップするのに約 10 ~ 12 秒かかります...

    select  y.groupid,
            y.dt as [start], 
            z.dt as [end],   
            (case when z.dt is null then 1 else 0 end) as latest, 
            y.i 
    from    #x as y 
            outer apply (select top 1 * 
                            from    #x as x 
                            where   x.groupid = y.groupid and 
                                    x.dt > y.dt 
                            order by x.dt asc) as z         

または
http://consultingblogs.emc.com/jamiethomson/archive/2005/01/10/t-sql-deriving-start-and-end-date-from-a-single-effective-date.aspx

Buuuuut... 2 番目のテーブルで.... 新しい行を挿入するには、前の行があるかどうかを確認し、ある場合はその終了日を更新する必要があります。それで...データを取得するときと挿入/更新するときのパフォーマンスの問題ですか? その終了日を 2 回保存するのはばかげているように思えますが、もしかしたら……そうではありませんか? 私は何を見なければなりませんか?

これは私が偽のデータを生成するために使用したものです...何らかの理由でそれを試してみたい場合(乱数の最大値をより高い値に変更すると、偽のものをより速く生成します):

declare @dt datetime
declare @i int
declare @id int
set @id = 1
declare @rowcount int
set @rowcount = 0
declare @numrows int 

while (@rowcount<100000)
begin

set @i = 1
set @dt = getdate()
set @numrows = Cast(((5 + 1) - 1) * 
                Rand() + 1 As tinyint)

while @i<=@numrows
    begin
    insert into #x values (@id, dateadd(d,@i,@dt), @i)
    set @i = @i + 1
    end 

set @rowcount = @rowcount + @numrows
set @id = @id + 1
print @rowcount
end 
4

2 に答える 2

3

あなたの目的のために、私はオプション2がテーブルデザインに行く方法だと思います。これにより柔軟性が得られ、作業量を大幅に節約できます。

発効日と終了日を指定すると、 where句にこれを含めることで、現在有効なデータのみを返すクエリを作成できます。

where sysdate between effectivedate and enddate

その後、これを使用して、時間に敏感な方法で他のテーブルと結合することもできます。

キーを適切に設定し、適切なインデックスを提供すれば、(少なくともこのテーブルでは)パフォーマンスは問題になりません。

于 2012-06-20T22:22:44.427 に答える
0

SQL Server 2012 (または Oracle、DB2 など) のLEAD分析関数を使用できる人にとっては、最初のテーブル (1 つの日付列のみを使用する) からデータを取得する方が、この機能を使用しない場合よりもはるかに高速です。

select
  groupid,
  dt "start",
  lead(dt) over (partition by groupid order by dt) "end",
  case when lead(dt) over (partition by groupid order by dt) is null
       then 1 else 0 end "latest",
  i
from x
于 2012-06-20T22:51:47.700 に答える