是时候通过大表中的SQL Server索引检索单个记录

时间:2012-01-31 21:45:56

标签: sql-server performance indexing

问题的简短版本:

如果你有一个包含大量小行的表,并且你想通过一个可能由两列组成的索引从这个表中检索单个记录,这可能是低成本,快速或高成本的东西和慢

问题和背景的更长版本:

我是一名软件开发公司的顾问,我和他们讨论了我想要添加到他们正在构建的应用程序(我正在设计)中的一项功能的性能影响。

目前,每次有人检索客户记录时,我们都会写出日志记录。我想在每次检索到该记录时,将最后一个人的姓名和时间用于访问该记录到客户端页面上。

他们说这对性能的影响会很高但是基于我对B树如何工作的合理而非专业知识,即使桌子非常大,这似乎也不对。

如果您在客户端记录的GUID和访问日期/时间(降序)上创建索引,那么您应该能够通过索引扫描检索所需的记录,这只需要查找第一个条目那个GUID然后停止?并且使用b-tree索引,大多数索引都将被缓存,因此所需的物理磁盘访问次数将非常小,因此查询时间显着小于1s。

或者我完全错了

4 个答案:

答案 0 :(得分:1)

您将遇到GUID索引碎片问题,但由于行的大小不会增加(正如您在评论中所述),因此不会出现页面拆分问题。通过重组和重建可以解决随机插入问题。

除此之外,你的方法没有错。如果表大于RAM,则每次访问可能只有一个磁盘IO(中间索引级别将被缓存)。如果您的数据适合RAM,则每次查询将支付约0.2至0.5毫秒。如果您的数据位于磁盘上,则搜索可能需要8-12ms。在SSD上你可以回到0.2ms到0.5ms(可能还多0.05ms)。

为什么不直接创建一些测试数据(通过从1M行的sys.object中选择一个交叉产品)并进行测量。这需要很少的时间,你肯定会发现。

答案 1 :(得分:0)

应该是低成本和快速的,因为列被索引并且将是O(n)我认为

答案 2 :(得分:0)

你说最后一个人访问?你的意思是,对于每次阅读,你都会有写作? 那篇文章将改变索引日期时间列?

然后我也会担心。

写入每个读取的记录将导致大量额外的磁盘写入。这将阻止读取,也可能对您的缓存不利。您还需要更新索引,并且由于更改了索引数据,因此索引将非常分散。

答案 3 :(得分:0)

取决于。

单次检索将是低成本且快速的

  • 在一个体面的索引表上
  • 在体面的硬件上运行
  • 通过一个体面的网络

另一方面,仍然需要时间

如果我们每小时都在讨论一次检索,请不要为此而烦恼。如果我们每秒谈论成千上万的检索(而不是当前没有),那么开始加起来,这将是值得注意的。

您需要提出的一些问题

  • 我的硬件是否符合规范
  • 添加两个字段会导致page split (不太可能)
  • 常规结果集
  • 需要读取多少额外页面
  • 将进行多少次检索/秒
  • 将进行多少次插入/秒(触发索引更新)

在您解决了这些问题之后,您应该能够自己做出决定。就我的直觉而言,我会惊讶你会发现性能差异。