を除去する方法の時間分の日付時刻値(SQL Server)?
-
08-06-2019 - |
質問
こちらは何を使ってい:
SELECT CAST(FLOOR(CAST(getdate() as FLOAT)) as DATETIME)
私は考えていることにより、より優雅に。
要件:
- では早めに以下キャストしております
- 最終的な結果であることが
datetime
タイプではなく、文字列になります。
解決
SQL Server2008年まで
SQLサーバーは、2008年まで、インターネットには想像もつかなが Convert(date, @date)
.このキャストできることを datetime
または datetime2
が必要です。
何が本当に最高のSQL Server2005年以上の?
などの見矛盾した債権う最速のための切り捨に日からSQLサーバーが、人によって言って試験が、私の経験が異なります。しましょういくつかのより厳しい試験および皆様のスクリプトなのか必ず本人が補正することが可能です。
Floatの変換が正確ではありません
まず、宿泊したいと思いましたら変換する datetime
へ float
, ませんので変換します。まぐらいの時間-除去も正しいと思うものは悪いことを利用で暗黙のうちに伝える開発者は安全な操作 ではない.しくは:
declare @d datetime;
set @d = '2010-09-12 00:00:00.003';
select Convert(datetime, Convert(float, @d));
-- result: 2010-09-12 00:00:00.000 -- oops
これは、私たちがすべき教える我々にとって、コードの例です。
また、もありませんの最速!
防性能試験
の場合を行っていきたいと考えてい試験によって自分をどのように異なる方法んのスタックを行い、必要なこのセットアップ実行するスクリプトの試験は遠い。
create table AllDay (Tm datetime NOT NULL CONSTRAINT PK_AllDay PRIMARY KEY CLUSTERED);
declare @d datetime;
set @d = DateDiff(Day, 0, GetDate());
insert AllDay select @d;
while @@ROWCOUNT != 0
insert AllDay
select * from (
select Tm =
DateAdd(ms, (select Max(DateDiff(ms, @d, Tm)) from AllDay) + 3, Tm)
from AllDay
) X
where Tm < DateAdd(Day, 1, @d);
exec sp_spaceused AllDay; -- 25,920,000 rows
なお、この作427.57MBテーブルデータベースとすようなものを15~30分です。場合データベースが小さく、10%の成長では、以下の場合サイズに十分に大きい。
しかし、実際の性能試験を記述します。合もございますのでご了承下さいの目的には戻れない列で、クライアントにして夢中高26百万円を行う非表示の性能の違います。
その結果を
set statistics time on;
-- (All queries are the same on io: logical reads 54712)
GO
declare
@dd date,
@d datetime,
@di int,
@df float,
@dv varchar(10);
-- Round trip back to datetime
select @d = CONVERT(date, Tm) from AllDay; -- CPU time = 21234 ms, elapsed time = 22301 ms.
select @d = CAST(Tm - 0.50000004 AS int) from AllDay; -- CPU = 23031 ms, elapsed = 24091 ms.
select @d = DATEDIFF(DAY, 0, Tm) from AllDay; -- CPU = 23782 ms, elapsed = 24818 ms.
select @d = FLOOR(CAST(Tm as float)) from AllDay; -- CPU = 36891 ms, elapsed = 38414 ms.
select @d = CONVERT(VARCHAR(8), Tm, 112) from AllDay; -- CPU = 102984 ms, elapsed = 109897 ms.
select @d = CONVERT(CHAR(8), Tm, 112) from AllDay; -- CPU = 103390 ms, elapsed = 108236 ms.
select @d = CONVERT(VARCHAR(10), Tm, 101) from AllDay; -- CPU = 123375 ms, elapsed = 135179 ms.
-- Only to another type but not back
select @dd = Tm from AllDay; -- CPU time = 19891 ms, elapsed time = 20937 ms.
select @di = CAST(Tm - 0.50000004 AS int) from AllDay; -- CPU = 21453 ms, elapsed = 23079 ms.
select @di = DATEDIFF(DAY, 0, Tm) from AllDay; -- CPU = 23218 ms, elapsed = 24700 ms
select @df = FLOOR(CAST(Tm as float)) from AllDay; -- CPU = 29312 ms, elapsed = 31101 ms.
select @dv = CONVERT(VARCHAR(8), Tm, 112) from AllDay; -- CPU = 64016 ms, elapsed = 67815 ms.
select @dv = CONVERT(CHAR(8), Tm, 112) from AllDay; -- CPU = 64297 ms, elapsed = 67987 ms.
select @dv = CONVERT(VARCHAR(10), Tm, 101) from AllDay; -- CPU = 65609 ms, elapsed = 68173 ms.
GO
set statistics time off;
一部の回遊解析
一部についてです。まず、場合にだけ行グループは、比較、変換する必要があるに戻る datetime
.で保存することができます。CPUを回避しなければ必要なもの最終値を表示。できるグループのunconverted値の変換にのみ選択項:
select Convert(datetime, DateDiff(dd, 0, Tm))
from (select '2010-09-12 00:00:00.003') X (Tm)
group by DateDiff(dd, 0, Tm)
また、どのように数値の変換だけで少しお時間の変換に戻る datetime
, ものの、 varchar
変換をほぼ倍?これらの部分CPUの専門日付で計算されます。部分があるのでCPU使用しないる日付を計算し、これに近いものになる19875ms上記のクエリ.その後の変換がかかる追加の金額である場合は二つの変換は、その金額を約ます。
より察に比べて Convert(, 112)
, は、 Convert(, 101)
クエリはCPU追加費用を使用していく varchar
?), での変換に戻る date
なコストなどの初期化 varchar
, が、 Convert(, 112)
では同じ20000ms CPU。
ここでは計算にCPU時間使用した上記の解析:
method round single base
----------- ------ ------ -----
date 21324 19891 18458
int 23031 21453 19875
datediff 23782 23218 22654
float 36891 29312 21733
varchar-112 102984 64016 25048
varchar-101 123375 65609 7843
丸 のCPU時間の往復帰
datetime
.シングル はCPU時間のためのシングル変換を代替データタイプのつの側面を取り除く効果の部).
ベース の計算を差し引いから
single
との間の差は二つのメソッドの呼び出し:single - (round - single)
.このボールパーク図ることを前提としているとの変換にかかるデータタイプdatetime
がほぼ同じであることが分かります。でこの想定は完全というわけではありませんが近いので、値はすべて近20000ms。
一興味深いリックするとnhkサイトを離れベースのコストはほぼ等しいシングル Convert(date)
方法が必要となるほぼ0費用としては、サーバ内部の抽出、整数日分の最初のバイトの datetime
データタイプ)です。
結論
このように見えるのは、単方向 varchar
変換方式約1.8µsの一方向 DateDiff
法歩0.18µsよりはるかに小さいです。私はこの最も保守的な"ベースのCPU時間"私の試験の18458ms計25,920,000行う23218ms/25920000=0.18µsよりはるかに小さいです。を明らかに10xの改善のように多く、それは正直ほどの小さなまでを取り扱何十万人もの行(617k rows=1秒の
それでも小型の絶対値の改善は、私の考えでは、 DateAdd
法勝利で最高の性能と透明度その答えを入れることによって行われる"魔法数"の 0.50000004
への食い込み人日(五つのゼロまたは六???), スペシャル"ホットスポットのくする。
注意事項
私が思変更 0.50000004
へ '12:00:00.003'
としていませんのでご注意くださいます。次のように入力してくださる同 datetime
価値と思うのですく、覚えておいてください。
興味のある方は、上記のテストを実施、サーバ@@版は以下のように返信します:
Microsoft SQL Server2008(RTM)-10.0.1600.22(Intel X86)月9 2008 14:43:34Copyright(c)1988-2008マイクロソフト社スタンダード版Windows NT5.2(建3790:サービスパック2がインストール)
他のヒント
SQL Server2008年には新しい 日 データタイプ こ簡単にこの問題:
SELECT CAST(CAST(GETDATE() AS date) AS datetime)
Itzik Ben-Ganに 計算したDATETIME、1部 SQLサーバーの雑誌、2007年)は、以下の二つの方法等の変換遅いる最速の;の違いを第三の方法が小さい):
SELECT CAST(CONVERT(char(8), GETDATE(), 112) AS datetime)
SELECT DATEADD(day, DATEDIFF(day, 0, GETDATE()), 0)
SELECT CAST(CAST(GETDATE() - 0.50000004 AS int) AS datetime)
の技術(鋳造 float)のようなリーダーにはしません。彼によれば、この性能に匹敵する第二の方法。
ご CAST
-FLOOR
-CAST
ているように最適な、少なくともMS SQL Server2005年.
一部の他のソリューションなどの見ている文字列変換のように、 Select Convert(varchar(11), getdate(),101)
している減速効果を明確にする必要がある10.
てみてください:
SELECT CONVERT(VARCHAR(10),[YOUR COLUMN NAME],105) [YOURTABLENAME]
SQL2005:私のおすすめキャストの代わりにdateadd.例えば、
select cast(DATEDIFF(DAY, 0, datetimefield) as datetime)
平均10%程度 高速 自分のデータセット、
select DATEADD(DAY, DATEDIFF(DAY, 0, datetimefield), 0)
(鋳造にsmalldatetimeの速い)