让我们有一个付款表,其中35列包含主键(autoinc bigint)和3个非聚集的非唯一indeces(每个列在一个int列上)。
在表的列中,我们有两个日期时间字段:
payment_date datetime NOT NULL
edit_date datetime NULL
该表约有1 200 000行。 只有~1000行有edit_date column = null。 9000行的edit_date不为null且不等于payment_date 其他人有edit_date = payment_date
当我们运行以下查询1 :
时select top 1 *
from payments
where edit_date is not null and (payment_date=edit_date or payment_date<>edit_date)
order by payment_date desc
服务器需要几秒钟才能完成。但是如果我们运行查询2 :
select top 1 *
from payments
where edit_date is not null
order by payment_date desc
执行结束时数据库'tempdb'的日志文件已满。备份数据库的事务日志以释放一些日志空间。
如果我们用某些列替换*,请参阅查询3
select top 1 payment_date
from payments
where edit_date is not null
order by payment_date desc
它也会在几秒钟内完成。
魔法在哪里?
修改 我已经更改了查询1,以便它在与第二个查询完全相同的行数上运行。并且它仍会在一秒钟内返回,而查询2则填充tempdb。
ANSWER 我按照建议添加索引,为两个日期字段执行此操作 - 一切都按预期开始快速运行。虽然,问题是 - 为什么在这种情况下,sql server在类似的查询上表现不同(查询1与查询2);我想了解服务器优化的逻辑。我同意如果两个查询都使用了类似的tempdb,但他们没有....
最后,我标记为第一个答案,在那里我看到了问题的必然症状,第一个,以及关于如何避免这种情况的想法(即凹痕)
答案 0 :(得分:5)
这种情况正在发生,因为执行计划中的某些步骤可能会触发对tempdb
的写入,特别是涉及大量数据的某些sorts
和joins
。
由于您正在使用列载荷列对表进行排序,因此SQL决定在没有关联数据的情况下在temp db中单独执行排序会很疯狂。如果它这样做,它将需要在底层表上执行gazzilion低效的书签查找。
遵循以下规则:
答案 1 :(得分:4)
通常,当磁盘空间不足或者为数据库增长设置了不合理的低最大大小时,tempdb会填满。 许多人认为tempdb仅用于#temp表。实际上,您可以轻松填充tempdb而无需创建单个临时表。其他一些可能导致tempdb填满的场景:
使用带有“创建临时存储”选项的ODBC DSN 程序集可以在那里留下物品 连接。
使用tempdb GO
SELECT name
FROM tempdb..sysobjects
SELECT OBJECT_NAME(id), rowcnt
FROM tempdb..sysindexes
WHERE OBJECT_NAME(id) LIKE '#%'
ORDER BY rowcnt DESC
行数越高,值可能表示占用空间的最大临时表。
短期修复
DBCC OPENTRAN -- or DBCC OPENTRAN('tempdb')
DBCC INPUTBUFFER(<number>)
KILL <number>
长期预防
-- SQL Server 7.0, should show 'trunc. log on chkpt.'
-- or 'recovery=SIMPLE' as part of status column:
EXEC sp_helpdb 'tempdb'
-- SQL Server 2000, should yield 'SIMPLE':
SELECT DATABASEPROPERTYEX('tempdb', 'recovery')
ALTER DATABASE tempdb SET RECOVERY SIMPLE
参考:https://web.archive.org/web/20080509095429/http://sqlserver2000.databases.aspfaq.com:80/why-is-tempdb-full-and-how-can-i-prevent-this-from-happening.html
其他参考文献:http://social.msdn.microsoft.com/Forums/is/transactsql/thread/af493428-2062-4445-88e4-07ac65fedb76