私は以下のような奇妙な状況を経験します:
「Table1」という名前のデータベースに巨大なテーブルがあります。次に、次のコードを使用してまったく同じテーブルを複製します。
Select *
into Table2
from Table1
その後、クエリのパフォーマンスが劇的に異なることがわかりました。
Select count (distinct ID)
from Table1
完了するまでに約2分かかります。(古いテーブル)
その間、
Select count (distinct ID)
from Table2
完了するのに約10秒かかります(新しいテーブル)
ちなみに、「selectinto」の後にデータがnewtableで並べ替えられていたことがわかりました。さらに、新しいテーブルを「選択」する前に、Table1(古いテーブル)に列が追加されました(つまり、テーブルを変更し、col1をcol2として追加します)。
では、これはどのように起こりますか?
(注:質問の元のバージョンでは、新しいテーブルは遅いテーブルであると述べられていました。これはエラーでした。また、Table1のデータ操作については言及されていませんでした)
詳細情報の要求への応答
これは、セバスチャンのコードからの結果です。
SELECT QUOTENAME(OBJECT_SCHEMA_NAME(t.object_id)) + '.' + QUOTENAME(t.name) tbl,
s.name stats_name,
cols.cols,
t.create_date table_date,
STATS_DATE(s.object_id, s.stats_id) AS statistics_date,
s.auto_created,
s.user_created,
s.no_recompute,
s.has_filter,
s.filter_definition
FROM sys.tables t
LEFT OUTER JOIN sys.stats s
ON s.object_id = t.object_id
OUTER APPLY (
SELECT STUFF((SELECT ',' + c.name
FROM sys.stats_columns sc
JOIN sys.columns c
ON sc.column_id = c.column_id
AND sc.object_id = c.object_id
WHERE sc.object_id = s.object_id
AND sc.stats_id = s.stats_id
ORDER BY sc.stats_column_id
FOR XML PATH(''),
TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 1, '') cols
) cols
--Update Table Name(s) here:
WHERE t.OBJECT_ID IN ( OBJECT_ID('[Sales].[SpecialOffer]'),
OBJECT_ID('[Sales].[SalesOrderDetail]') );
と
SELECT name,
compatibility_level,
is_auto_close_on,
is_auto_shrink_on,
state_desc,
is_auto_create_stats_on,
is_auto_update_stats_on,
is_auto_update_stats_async_on
FROM sys.databases
WHERE database_id = DB_ID();
実際、新しいテーブルを別のデータベースにコピーします。そして、テーブル名は実際にはID2000という名前です
上の画像は「Table1」(データベース1)を参照しています。下の画像は「Table2」(データベース2)を参照しています。
XMLコードが長すぎるので、Hamletのアドバイスに従った代替のプリントアウトを次に示します。SET SHOWPLAN_ALL ON GO
すべてのXMLコードを貼り付ける代わりに使用
します。お役に立てば幸いです。
赤い色は「表1」の計画を表し、黒い色は「表2」を表します。画像のテキストは少し小さいですが、このページサイズを大きくしてズームインすると、単に拡大されます。
どうもありがとうございます!!
の結果SELECT * FROM sys.dm_db_index_physical_stats(db_id(),object_id('YourTable'),NULL,NULL,'Detailed')
。
実際、2つのテーブルの間には大きな違いがあります。同様に、赤い色は「表1」を示し、別の色は「表2」を示します。
この問題は非常に厄介で、すべてのテーブルを再構築するかどうかを自問し続けるので、私は夢中になります。:(
実際には非常に奇妙です。record_countが異なることに注意してください。ただし、で再確認する
select COUNT (ID) from id2000
と(つまり、このテーブルの合計データ行を計算します)、両方の結果は2324798であり、これはTable_2のrecord_countです。
さらに、「Table2」は「select * into」ステートメントによって作成されました。両方とも同じである必要があると思いますが、今は混乱しています。
上記の表は、Sebastianコードのコード(Running stat)の結果です。
の結果SELECT * FROM sys.dm_db_index_physical_stats(db_id(),object_id('YourTable'),NULL,NULL,'Detailed')
。
実際、2つのテーブルの間には大きな違いがあります。同様に、赤い色は「表1」を示し、別の色は「表2」を示します。
この問題は非常に厄介で、すべてのテーブルを再構築するかどうかを自問し続けるので、私は夢中になります。:(
実際には非常に奇妙です。record_countが異なることに注意してください。ただし、で再確認する
select COUNT (ID) from id2000
と(つまり、このテーブルの合計データ行を計算します)、両方の結果は2324798であり、これはTable_2のrecord_countです。
さらに、「Table2」は「select * into」ステートメントによって作成されました。両方とも同じである必要があると思いますが、今は混乱しています。