【问题标题】:select 17 milion records in sql server is very slow在sql server中选择1700万条记录很慢
【发布时间】:2021-11-07 13:06:53
【问题描述】:

我尝试选择一个包含 1700 万条记录的表。 大约需要 10 分钟。 在这里您可以看到 Live 执行计划。

这是我的表结构:

CREATE TABLE [bas].[GatewayReceipt](
    [Id] [INT] IDENTITY(1,1) NOT NULL,
    [CustomerId] [INT] NULL,
    [UserId] [INT] NOT NULL,
    [RefNumber] [NVARCHAR](200) NULL,
    [ResNumber] [NVARCHAR](200) NULL,
    [Price] [DECIMAL](18, 5) NOT NULL,
    [GatewayChannelId] [INT] NOT NULL,
    [StatusId] [INT] NOT NULL,
    [EntryDate] [DATETIME] NOT NULL,
    [ModifyDate] [DATETIME] NULL,
    [RowVersion] [TIMESTAMP] NOT NULL,
 CONSTRAINT [PK_Bas_GatewayReceipt] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [FG_ATS]
) ON [FG_ATS]
GO

作为说明,我有 3 个非聚集索引 1:客户编号 2:客户ID和用户ID 3:gatewaychannelId

我的查询:

select * from  bas.GatewayReceipt where  gatewaychannelId in (1,2,3)

为什么我的查询很慢?

【问题讨论】:

  • 你的问题是什么? SELECT * FROM 没有 WHERE 不能使用索引
  • @Sergey 抱歉,我更改了查询。我在 gatewaychannelid 上有一个 where 子句
  • @Sergey 作为主要问题 为什么没有 where 的选择查询应该这么慢?
  • 你们似乎都认真地忽略了这件事。是否有索引并不重要——即使没有索引,1700 万行扫描也不应该在现代硬件上花费 10 分钟。在 5 年的手机、20 年的电脑上运行?非常非常非常少的内存? 10 分钟太离谱了,索引与否。
  • “大约需要 10 分钟”到底是什么意思?您是否从应用程序的角度进行测量?应用程序检索结果集并对其进行处理的速度有多慢?该应用程序对结果集做了什么?服务器和应用程序之间的网络连接有多慢?即使可以改进执行计划,但如果问题出在结果集的消耗范围内,您可能看不到多少改进。

标签: sql-server indexing sql-execution-plan


【解决方案1】:

结果缓慢主要是由于客户端应用程序 (SSMS) 需要时间来呈现 1700 万行的大型结果。

也就是说,SSMS 大约需要 70 秒才能在我的 PC 上以网格的形式显示此查询的 1000 万行结果,并且任务管理器显示 SSMS 在执行期间完全受 CPU 限制:

WITH 
     t10 AS (SELECT n FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) t(n))
    ,t1k AS (SELECT 0 AS n FROM t10 AS a CROSS JOIN t10 AS b CROSS JOIN t10 AS c)
    ,t10m AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS num FROM t1k AS a CROSS JOIN t1k AS b CROSS JOIN t10 AS c)
SELECT num
FROM t10m;

重复相同的查询而不完整呈现(Query-->Options-->Grid-->Discard results after execution),只需 12 秒即可检索行但不显示它们。

考虑端到端响应时间是客户端和服务器时间的度量。

【讨论】:

    【解决方案2】:

    表格需要INDEX gatewaychannelId开头

    但是,如果表中的大多数或所有行都是值 1、2 或 3,则索引实际上会减慢查询速度。在这种情况下,简单地读取表格,过滤掉少数不适用的行会更快。

    【讨论】:

      猜你喜欢
      • 2016-04-12
      • 1970-01-01
      • 1970-01-01
      • 2013-09-25
      • 1970-01-01
      • 2019-01-06
      • 1970-01-01
      • 1970-01-01
      • 2016-03-06
      相关资源
      最近更新 更多