【问题标题】:Sql table unresponsive when selecting or counting all rows选择或计算所有行时 Sql 表无响应
【发布时间】:2009-04-08 10:43:49
【问题描述】:

我们在数据库中有一个有 35 行的表,根据

exec sp_spaceused 部门。

我可以跑

SELECT TOP 1 * FROM Department,

并得到一个结果,但是当我运行时

从部门中选择 COUNT(*),

它的运行时间超过 2 分钟(然后我取消了它并且没有等待结果,因为我希望这是一个简单而快速的查询)。

这可能是什么原因?你有什么建议吗?

【问题讨论】:

    标签: sql sql-server select


    【解决方案1】:

    表上是否有打开的锁阻止您读取某些行?

    试试:

    sp_lock
    

    【讨论】:

    • 我没想到这会影响计数(*) - 一个体面的 DBMS 应该单独维护行数以提高速度。
    • 虽然有其他方法可以获得(近似)计数。
    • 行数通常由索引决定——锁定一行可以锁定索引
    【解决方案2】:

    这个查询会很快返回吗?

    SELECT COUNT(*) FROM Department WITH (NOLOCK)
    

    如果是这样,我肯定会说你的表/索引上有某种锁,正如建议的那样。

    马克

    【讨论】:

      【解决方案3】:

      如果您的表格确实有 35 行,则不需要两分钟。即使你的表有数十亿行,一个像样的 DBMS 也会存储行数以提高效率(我不知道微软是否这样做)。

      请记住,“top 1”只会以(看似)随机顺序获得第一行,因此速度会很快。

      我的第一个想法是数据库损坏 - 当您执行以下操作时会发生什么?

      select top 2 * from Department
      select top 3 * from Department
      select top 4 * from Department
      

      等等。

      【讨论】:

        【解决方案4】:

        找出发生了什么的最好方法是跟踪查询的执行,但我不知道如何在 SQL Server 中执行此操作。

        您还可以尝试查看查询的执行计划,这可能会告诉您是否有一些意想不到的事情发生在幕后(例如,如果 Department 确实是一个复杂的视图)。

        假设该表有一个名为 Department_ID 的主键,它始终是一个正整数,您可以尝试以下操作:

        SELECT COUNT(*) FROM Department WHERE Department_ID > 0
        

        这可能会强制它扫描索引而不是实际的表。

        【讨论】:

          【解决方案5】:

          检查桌子上的触发器。还可以启动性能监视器,以便查看服务器在资源上的运行情况。

          【讨论】:

            【解决方案6】:

            您期望的简单而快速的查询实际上会导致 Table Scan,它有效地从磁盘读取所有数据页并遍历每条记录。这是非常昂贵。你可以使用this method,但我不确定它是否准确。

            【讨论】:

            • 35 行的表应该不会很贵 :-)
            • 感谢您的评论。但是,这不是表扫描。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2019-01-25
            • 1970-01-01
            • 2018-11-26
            • 1970-01-01
            • 2021-11-08
            • 1970-01-01
            • 2022-01-26
            相关资源
            最近更新 更多