我们正在运行 SQL Server 2000。在我们的数据库中,我们有一个“Orders”表,其中大约有 750,000 行。我们可以在此表上执行简单的 SELECT 语句。但是,当我们想要运行查询(例如 SELECT TOP 100 * FROM Orders ORDER BY Date_Ordered DESC)时,我们会收到以下消息:
错误:9002,严重性:17,状态:6 数据库“tempdb”的日志文件已满。备份数据库的事务日志以释放一些日志空间。
我们的数据库中还有其他表,其大小与表中的记录数量相似(即 700,000 条记录)。在这些表上,我们可以运行任何我们想要的查询,并且永远不会收到有关“tempdb 已满”的消息。
为了解决这个问题,我们备份了数据库,缩小了实际数据库,还缩小了 tempdb 系统数据库中的数据库和文件,但这并没有解决问题。
我们的日志文件的大小设置为自动增长。
我们不确定下一步该怎么做。你知道为什么我们仍然会收到这条消息吗?
错误:9002,严重性:17,状态:6 数据库“tempdb”的日志文件已满。备份数据库的事务日志以释放一些日志空间。
答案1
根据本文,如果排序所需的内存比 SQL Server 分配的内存多,则使用临时数据库。
如果对未索引的列进行排序,数据库服务器将执行全表扫描并跟踪表中所有记录的所有 Date_Ordered 值(和主键值)。
在 Orders.Date_Ordered 上创建索引以加快排序速度并减少内存使用量。
答案2
除了 devio 的建议外,还请考虑:
- 您是否真的需要执行 SELECT *,如果您只需要几列,请将它们拼写出来;如果订单是一个非常宽的表,则会使排序的开销更高;如果有 blob/文本字段,它们会被拖着走。
您可以添加日期选择,例如 WHERE Date_Ordered > getdate() -1;即使您获得的记录多于所需,也不必将整个表复制到 Tempdb;您可以执行以下操作
从 (select * from orders where date_ordered >getdate() - 10) 中选择 TOP 100 * 按 date_ordered 降序排序
但迄今为止,在 date_ordered 上添加索引是最好的解决方案。
答案3
好的,第一个问题是,您的 SQL Server 需要更多 RAM。机器上安装了多少 RAM。
之后,您需要增加承载 tempdb 数据库的硬盘大小。此数据库用于各种用途,您需要它完全发挥作用,才能使整个 SQL Server 正常工作。
短期内,重新启动 SQL 服务,这将删除 tempdb 数据库并按其初始大小重新创建它。长期内,您需要增加硬盘大小,以便 tempdb 可以增长到所需的大小。
答案4
您的磁盘上是否有足够的空间来存储 tempdb 文件。
尝试运行不带 order by 子句的相同查询,看看错误是否消失。