【问题标题】:sql server partition table not performance in big tables?sql server 分区表在大表中没有性能?
【发布时间】:2020-11-04 19:48:56
【问题描述】:

我有 3500 万行的表格。当我选择如图所示的行时,它不起作用并且需要很长时间并最终出现内存错误(我的 ram 是 32GB)。

我根据每月日期对表进行了分区,我有 64 个表,如图所示

但查询无法再次工作,并且需要很长时间并最终出现内存错误 .我该如何解决这个问题?

【问题讨论】:

  • 35M 不算大。这是一个中等大小的事实表。如果您使用压缩或聚集列存储索引,它的占用空间不会那么大。
  • 分区也不是一种性能特性,它是一种数据管理特性。它实际上会使查询变慢,因为服务器必须搜索多个表。但是,这些都不能证明内存错误是合理的
  • 问题是错误的查询 - 除了子查询,那些try_convert(numeric(38, 12), student.Length ) 操作意味着不能使用字段上的索引,因此数据库引擎必须扫描整个表。这也意味着该表使用了错误的类型。数字应存储为数字,而不是文本。如果要用于过滤的字段,则应将它们编入索引。
  • 要清楚 - 错误是 SQL Server 错误消息,MsgLevelState 等,还是 管理Studio 错误提示您尝试将太多行加载到网格中?
  • 至于我怀疑它通常抱怨空间的错误 - 此查询需要 lot 使用 tempdb 来存储解析值,可能达到 tempdb 的最大大小或耗尽硬盘驱动器

标签: sql sql-server table-partitioning


【解决方案1】:

这基本上是您的查询:

select s.*
from student s
where s.id = (select max(si.id)
              from studentIndex si
              where si.family = s.name and si.name_ship = s.name_ship
             )    and 
      try_convert(numeric(38, 12), s.Length ) between 18.485411 and 23.51031 and
      try_convert(numeric(38, 12), s.Weight ) between 21.77079 and 77.13644 and
      s.time > 1594326600;

这基本上是一个全表扫描,所以我不明白为什么它会用完成员。例外是相关子查询。为此,您需要在 studentIndex(family, name_ship) 上建立一个索引——并确保这些列是同一时间的(否则,可能不会使用该索引)。

您的lengthwidth 比较看起来非常像地理坐标。我可能还会建议一个 GIS 解决方案。但是,如果这些是纬度和经度,则该区域非常大,因此 GIS 可能并没有那么有用。

【讨论】:

  • 转换虽然阻止了索引的使用。 lat between Lat1 and Lat2 and Lon between Lon1 and Lon2 只是一个范围查询,可以通过索引轻松加速
  • @PanagiotisKanavos 。 . .并不真地。这是一个不等式,需要 GIS 功能来提高性能。但这没关系。扫描表不应产生内存错误,因此问题更可能是相关子查询。
  • 确实很重要,并且空间索引在这里无济于事。这种不等式仍然是一个范围搜索——OP 是在一个简单的盒子里搜索点,而不是一个复杂的形状。修复此问题可以将表扫描转换为返回少量结果的搜索
  • 我过去曾尝试过这样的事情——搜索某个半径范围内的酒店。一旦计算了所需的边界框,SQL Server 在 Point 上的空间索引并不比在 Lat Lon 上的索引好。如果必须搜索形状而不是点,那将是一个非常不同的故事
猜你喜欢
  • 1970-01-01
  • 2011-03-17
  • 2014-12-19
  • 2020-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多