【问题标题】:Clustered Index change on SQL Azure making INSERT very slow on a big table of sensor data (from ~30ms to 2000ms)SQL Azure 上的聚集索引更改使得在传感器数据的大表上插入非常慢(从 ~30 毫秒到 2000 毫秒)
【发布时间】:2013-03-02 05:32:27
【问题描述】:

我正在尝试提高我的多租户 SaaS 系统上的大型表的性能,以使报告速度更快。 当我在聚集索引上添加一列时,在系统上进行插入操作的时间从 ~30ms 增加到 1500~2500ms! 在这种情况下,应用于此表的最佳聚集索引选项和非聚集索引是什么:

  • 数据库:SQL Azure
  • 我只对该表执行 INSERT 和 SELECT,数据从不更新 (UPDATE)
  • 并发 INSERTS 的高负载(不同的 Worker 和线程使用队列中的数据)
  • 100.000 行/天(增长)
  • 实际上有 600 万行(增长中)
  • 每个租户只读取其 ID 的数据
  • 1 个租户将拥有 100-3000 个 DeviceId

表结构:
- TenantID (bigint)(我可以使用 smallint,但如果我将来需要使用 Azure 联合,我会更改为 bigint)
- 设备 ID (int)
- ReadID (bigint) (身份)
- UIDRead (GUID)
- ReadDate(日期时间)
- SensorState1 (tinyint)
- SensorState2 (tinyint)
- SensorState3 (tinyint)
...
- SensorState10 (tinyint)

常见的 WHERE 用于读取数据:
-WHERE DeviceId = @X 和 @XDate 和 @YDate 之间的 ReadDate
-WHERE DeviceId IN (X,Y,Z) AND ReadDate 在@XDate 和@YDate 之间
-WHERE TenantId = @Y and ReadDate BETWEEN @XDate and @YDate
-WHERE TenantId = @X AND DeviceID IN (X,Y,Z) AND ReadDate 在@XDate 和@YDate 之间
-WHERE TenantId = @X AND DeviceID =@Y AND ReadDate 在@XDate 和@YDate 之间

【问题讨论】:

  • 您将哪一列定义为聚集索引的键? ReadID 看起来应该是集群键,因为它是唯一的、相当窄的并且不断增加。如果它是该列(单独)并且您在插入数据时仍然遇到这些长时间的延迟,那么这里肯定会发生其他事情。

标签: sql-server indexing azure-sql-database


【解决方案1】:

什么是主键?我假设ReadDateTenantIdDeviceId 构成唯一标识符?如果是这样,通过在表定义中声明主键,按顺序对它们进行聚类。始终将日期放在时间序列数据的聚集索引的前面,因为范围是连续的。 (是的,我知道每个租户只读取他自己的数据。服务器不知道这一点,缓存将倾向于保存所有租户的所有数据,因为(我敢打赌)大多数租户都会对相同的日期感兴趣。 )

尽可能使用最窄的列。现在不要使用BIGINT,以防您以后想要联合;当那一天到来时,如果它来了,ALTER TABLE会等你。除非您需要几秒钟,否则请使用 smalldatetime。放弃ReadId,因为你已经有了一个自然键,它既浪费空间又是资源争用的来源。将UIDRead 更改为普通整数,并希望您拥有超过 20 亿读者的那一天。

如果生成的表在接受插入时仍然很慢,这不是表的错。见服务器。

【讨论】:

  • 不应该,根据你所说的。我提到的组合不是唯一的吗?如果不是,除了 ReadId 之外的两行有什么区别?如果没有,为什么是两行?如果您坚持保留它,请更改表,使其不在主键上集群,并在我推荐的列上集群(希望是唯一的)。
  • 你说的组合不是唯一的(我可以同时读取 2 个设备 ID)
  • 我会继续向主键添加列,直到我拥有唯一标识符或列用完为止。一旦所有列都在键中,我要么丢弃重复项,要么添加一个列,每当有额外的重复项到达时,我就会增加一列。我不会使用身份列来区分它们,因为如果它们“同时”发生,那么到达的顺序真的是微不足道的。
  • 没有成功,我尝试了 PK 聚集索引的这种配置: "ReadDate,TenantId,DeviceId,ReadId"/"ReadDate,TenantId,ReadId"/"TenantId,ReadId" 对于这一切我的插入时间是超过 2000 毫秒,当我只将“ReadId”作为 PK 聚集索引时,插入时间得到
  • 无法解释。其他事情正在发生。插入带有少量小列的单行的两秒钟太长了。我仍然认为 ReadID 不是你的朋友。我会与您的 DBA 核实以了解实际情况。不确定 Azure 会是谁。
猜你喜欢
  • 1970-01-01
  • 2012-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多