【发布时间】:2012-12-27 00:09:14
【问题描述】:
我遇到了如下奇怪的情况:
我在名为“Table1”的数据库中有一个巨大的表。 然后,我使用以下代码复制完全相同的表。
Select *
into Table2
from Table1
在那之后, 我发现查询性能差异很大。
Select count (distinct ID)
from Table1
大约需要 2 分钟才能完成。 (旧表)
与此同时,
Select count (distinct ID)
from Table2
只需大约 10 秒即可完成(新表)
顺便说一句,我发现数据在“选择进入”之后已经在新表中重新排序。 此外,在“选择”新表之前,Table1(旧表)中添加了一列 (即 Alter a table ,将 col1 添加为 col2。)
那么,这是怎么发生的呢?
(注意:问题的原始版本说新表是慢表。这是一个错误。另外,它没有提到对 Table1 的数据操作)
对更多信息请求的回应
这是 Sebastian 代码的结果。
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
上图参考“表1”(数据库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') 的结果。
确实,两张表之间存在巨大差异。 同理,红色为“表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') 的结果。
确实,两张表之间存在巨大差异。 同理,红色为“表1”,另一种为“表2”
这个问题很烦人,让我发疯,因为我一直在问自己是否应该重建所有表。 :(
其实很奇怪,注意record_count是不同的。
但是,当我重新检查时
select COUNT (ID) from id2000 ,(即计算此表上的总数据行)
两个结果都是2324798,也就是Table_2的record_count
此外,“Table2”是由“select * into”语句创建的,我想两者应该是相同的,但现在我很困惑。
【问题讨论】:
-
你在 table1 中有索引,而它们在 table2 中不存在?
-
我检查了,两个表上都没有索引。 :(
-
table1有什么限制吗?
-
Nop :( ,Table1 只是一个非常简单的表,从 txt 文件中以常规方式导入,无需执行任何进一步操作。我唯一修改的是添加一个列ALTER TABLE Table1 ADD age AS 2012-birthyear
-
再次检查。没有任何主键、外键、索引、约束集...
标签: sql sql-server sql-server-2008