web-dev-qa-db-ja.com

一般に、実際のテーブルに選択するよりも一時テーブルに選択する方が速いですか?

Tempdbへの書き込みはtempdbにない実際のテーブルよりも高速であるとどこかで読んだことがあると思いました。これはどのような点でも当てはまりますか? tempdbとメモリへのデータの格納について何か特別なことを言っていることを思い出したと思いますか?

34
J.D.

tempdbへの書き込みは、tempdbにない実際のテーブルよりも高速です。

それは本当です。 TempDbには、2つのIO拡張機能があります。

ユーザーデータベースのテーブルへの書き込みでは、コミット時にログレコードをディスクにフラッシュする必要があります。または、最小限のログに記録された挿入(SELECT ... INTOなど)の場合、コミット時にデータベースページをディスクにフラッシュする必要があります。ユーザーデータベースで最小限のログが機能する方法は、データベースページがディスクに直接書き込まれることです。 SELECT ... INTOが完了するまでに、新しいページはすべて物理ファイルに書き込まれています。

TempDbは障害後に回復されないため、TempDb書き込みはコミット時にディスクにフラッシュする必要はありません。つまり、そうではありません。変更によってログレコードが生成されますが、ログバッファーは、コミットごとではなく、いっぱいになったときにのみディスクにフラッシュされます。

そして SQL Server 2014以降 TempDbの最小限のログに記録された挿入も常にディスクに書き込まれるわけではありません。小さくて寿命の短い一時テーブルをロードすると、ディスクにまったく書き込まれない場合があります。ログには、テーブルのページ割り当てとメタデータエントリに関するいくつかのレコードがありますが、それだけです。

EGは、tempdb、フルリカバリデータベース、シンプルリカバリデータベースで次のバッチを実行して、違いを確認します。

drop table if exists foo
go
declare @data bigint
declare @log bigint 
select @log = sum(case when type_desc = 'LOG' then num_of_bytes_written end) 
      ,@data =  sum(case when type_desc = 'ROWS' then num_of_bytes_written end) 
from sys.database_files f
cross apply sys.dm_io_virtual_file_stats(db_id(),f.file_id) fs

select * 
into foo
from sys.objects 

select -@log + sum(case when type_desc = 'LOG' then num_of_bytes_written end)  log_bytes
      ,-@data +  sum(case when type_desc = 'ROWS' then num_of_bytes_written end) data_bytes
      , (select recovery_model_desc from sys.databases where database_id = db_id()) recovery_model
from sys.database_files f
cross apply sys.dm_io_virtual_file_stats(db_id(),f.file_id) fs

次のようなものが表示されます。

単純な回復の場合:

log_bytes            data_bytes           recovery_model
-------------------- -------------------- ---------------
24576                16384                SIMPLE

完全回復の場合:

log_bytes            data_bytes           recovery_model
-------------------- -------------------- ---------------
36864                0                    FULL

tempdbの場合:

log_bytes            data_bytes           recovery_model
-------------------- -------------------- ---------------
0                    0                    SIMPLE

Tempdbの場合、ログバッファがフラッシュされることがあります。

log_bytes            data_bytes           recovery_model
-------------------- -------------------- ---------------
61440                0                    SIMPLE

David Browne's answer で拡張されているように、tempdbへの書き込みがすべてのヒットディスク/ネットワークIOであるとは限りませんが、IO構成によっては、データは、ディスクにスプールする必要があるほど十分に大きいため、「通常の」テーブルに選択するよりも高速です。

  • TempDBは異なるドライブ上にある可能性があるため、独自のIO帯域幅を持っています。これは、SSDではなく回転ドライブで特に重要です。およびからの読み取り同じデータベース(または同じドライブ上の別のデータベース)へのヘッドの移動が増えると、さらにIOレイテンシが追加され、有効な帯域幅が抑制される可能性がありますIO帯域幅。コピー異なるドライブ/アレイ上のデータベース間のデータには、同じ追加のレイテンシはありません。

  • TempDBは、メインストレージよりも高速なメディアにある場合もあります。おそらく、メインストレージがネットワーク上にあるローカルドライブ、またはメインストアが従来のドライブ上にあるNVMe SSDです。

複数のファイルグループを使用してデータの一部を異なるドライブ/アレイ間で分散する場合、これらの違いは両方とも同じデータベース内で見られる可能性があります。

アクティブに使用されているデータベースが複数ある場合も、逆のことが当てはまります。 TempDBは共有リソースであるため、TempDBと、それをホストするドライブ/ネットワークは、個々のDBのデータファイルよりも負荷が高い可能性があります。

7
David Spillett