【问题标题】:SQL query slow performance 'LIKE CNTR%04052021%SQL查询性能慢'LIKE CNTR%04052021%
【发布时间】:2021-07-09 15:14:35
【问题描述】:

我们有一个每天都在增长的数据库。截至今天,大约有 4000 万条记录。

此表/数据库位于 Azure。

表有一个主键“ClassifierID”,查询正在这个主键上运行。

主键的格式为ID+时间戳(mmddyyy HHMMSS),例如'CNTR00220200 04052021 073000'

这是按日期获取所有 ID 的查询

 **Select distinct ScanID
 From ClassifierResults
 Where ClassifierID LIKE 'CNTR%04052020%**

非常简单明了,但有时需要一分钟才能完成。您对我们如何优化查询有什么建议吗?非常感谢。

【问题讨论】:

  • 这是一个糟糕的主键候选者 - 键应该尽可能窄并且是原子的 - 即 - 不是多个不同的属性混合在一起。
  • 性能不佳可能是因为每个值都以“CNTR”开头并且您执行类似“CNTR%”的操作,因此选择性为零,因此必须执行扫描 - 每个 i> 行就像 CNTR?
  • 同意。主键设计不正确。没想到数据会增长到这种规模。

标签: sql azure query-optimization


【解决方案1】:

最好的办法是修复您的设计,以便 a) 您不会将 ID 和时间戳存储在同一个文本字段中,并且 b) 您将时间戳存储在正确的日期/时间戳列中。使用您的单点数据,我建议以下表格设计:

ID           | timestamp
CNTR00220200 | timestamp '2021-04-05 07:30:00'

然后,在(ID, timestamp) 上创建一个索引,并使用以下查询:

SELECT *
FROM yourTable
WHERE ID LIKE 'CNTR%' AND
      timestamp >= '2021-04-05' AND timestamp < '2021-04-06';

上述查询搜索具有IDCNTR 开头并恰好落在日期2021-04-05 的记录。您的 SQL 数据库应该能够在此查询中使用我上面建议的复合索引。

【讨论】:

  • 同意。桌子应该设计得更好。在我们添加另一列之前,是否还有优化查询的空间?可能不是基于你所说的,对吗?
  • LIKE 'CNTR%04052020%' 是一个真正的性能杀手,因为它无法被 AFAIK 索引。我建议尽可能更改您的设计,因为随着表格的继续增长,您的问题只会变得更糟。也许其他人会给你一个临时的解决方法。
  • 非常感谢您的想法
  • 创建一个视图或一个计算列以仅从文本列中提取日期部分;然后可以在其上创建索引并用于过滤行。
  • ID和Time一起创建索引时,是否需要定期更新索引?数据库自己处理这个更新吗?
猜你喜欢
  • 2016-09-19
  • 1970-01-01
  • 2017-06-29
  • 2012-02-22
  • 2011-09-07
  • 2010-12-06
  • 2014-03-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多