【问题标题】:Select query takes long time even for 10 records from a very big records table即使对于非常大的记录表中​​的 10 条记录,选择查询也需要很长时间
【发布时间】:2021-05-25 11:12:49
【问题描述】:

我有一个非常大的记录表,大约有 650 万条记录。当我尝试从中选择一些记录时,即使是 10 条记录,我也必须等待很长的随机时间。

SELECT [Column1], [Column2], [Column3], [Column4], [Column5]
FROM [table]
WHERE deviceDataId = '640'
ORDER BY id ASC OFFSET 10 ROWS 
FETCH NEXT 10 ROWS ONLY

我的数据库部署在 azure 上,我也下载并部署在本地系统,但需要相同的时间。

查询执行计划:

【问题讨论】:

  • 性能问题需要附上你的执行计划Paste The Plan
  • 那为什么要传递'640',这是一个varchar?数值不包含在单引号中。只要有WHERE Id = 640。尽管它不太可能导致任何性能问题,但您仍应尽可能避免在 WHERE 中进行隐式转换。但是,我们仍然需要那个执行计划。我会冒险猜测您没有索引...
  • WHERE Id = x ORDER BY Id 没有意义;该顺序是不确定的,因为所有行都具有相同的Id。一般来说,使用OFFSET .. FETCH NEXT 时不要期望有好的性能,尤其是当偏移量变高时性能会下降。在这种情况下,它不应该是您的问题的原因,这可能是 Id 上缺少索引。
  • 那么问题就变成了“deviceDataId, Id 上是否有索引(最好是您需要的其他列INCLUDEd)”。如果没有,聚集索引扫描是唯一可用的选项。
  • 查看获取执行计划和真实查询所需的 cmets 数量,@Ahmad。您将Id 交替用于2 个不同的列,从而误导了我们很长时间;这可能很容易失去用户的兴趣并为你赢得了反对票。

标签: sql-server sql-server-2012


【解决方案1】:

现在我们有了您的真实查询,我们可以看到它似乎您的列deviceDataId 上没有索引;意味着需要扫描整个表。因此,即使您只需要 10 行,也需要扫描所有 650 万行并检查 deviceDataId 的值。

如果您在查询中的列deviceDataId 和最少INCLUDE 的其他列上创建索引,那么您将拥有一个覆盖索引,这将有很大帮助。这也假设 id 是您的CLUSTERED INDEX 被订购的列。

CREATE NONCLUSTERED INDEX IX_Table_DeviceTableID_Cols1_5
    ON dbo.[table] (deviceDataId)
    INCLUDE ([Column1], [Column2], [Column3], [Column4], [Column5]);

另外,正如我在 cmets 中所指出的,如果 deviceDataIdint,请在 WHERE 子句中使用 int 值。不要将数值用单引号括起来,即用于文字字符串。

WHERE deviceDataId = 640

【讨论】:

  • 他可能需要为 Id 列增加一个索引,以便 orderby 加快速度。
  • 如果它是聚集索引,那么我们应该没问题,因此我关于假设的注释是@AmitKumarSingh。
  • 我正在创建非聚集索引,然后返回这里。
  • 是的,感谢非聚集索引工作正常。记录获取成功。索引是否也有任何限制。多大的记录索引在 MSSQL 中完美运行?
猜你喜欢
  • 2019-03-09
  • 1970-01-01
  • 2016-12-01
  • 1970-01-01
  • 2013-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-11
相关资源
最近更新 更多