假设SQL Server有巨大的内存来容纳整个数据库,那么索引有什么好处呢?

var*_*ble 6 index sql-server sql-server-2019

据我所知,索引查找允许服务器通过查找索引快速转到所需的页面,因此无需将查询表的所有页面从磁盘读取到内存中即可获得好处。

这个问题假设:

  1. 整个数据库有巨大的内存存储在内存中,
  2. 被查询的表没有索引,
  3. 查询是从表中选择数据,其中说rate>100
  4. 带有上述 WHERE 子句的第一个查询将进行扫描,将整个表的数据页从磁盘拉入内存(因为 上没有索引rate)。

在这种情况下,我的问题是,对于使用相同 WHERE 子句 ( rate>50) 对该表进行的后续查询,SQL 引擎将对已驻留在内存中的页面执行表扫描。rate当整个表位于内存中并且不需要访问磁盘时,列上是否有索引对第二个查询有任何好处吗?

Pau*_*ite 23

做更少的工作几乎总是比做更多的工作更快。

\n

假设基表和索引都完全存在于内存中,如果表很大,则索引查找将执行更少的工作。

\n

这项工作主要表现为 CPU 时间和等待内存获取。与大多数持久存储相比,内存速度很快,但与 CPU 相比仍然非常慢。

\n

表扫描将必须访问更多的内存页,并测试更多的行以查看是否rate > x。执行这些比较测试会消耗 CPU。

\n

索引查找将有效地定位第一个匹配行(通过向下导航 b 树),然后沿着下一页指针扫描到索引的末尾。它永远不需要测试各个行来查看是否rate > x。索引的排序保证找到的所有行都与谓词匹配,而不进行任何值比较。

\n

假设采用行存储布局,基表每 8KB 页将具有尽可能少的行数\xe2\x80\x94所有行内列都出现在该页上。

\n

该索引可能比基表更密集,因为它只包含索引数据。与基表情况相比,每 8KB 页的行数更多,需要的页访问次数更少。

\n

还有其他注意事项,例如属于目标(表或索引)的页面首先如何定位。对于堆表,这是使用 IAM 页完成的。索引查找从元数据中定位 b 树的根,然后按照已经描述的方式进行导航。这些方法是不同的,但对于完全内存中的情况,两者之间不太可能存在非常可测量的差异。

\n

扫描整个表还需要使用更多的锁和页锁存器,从而消耗 CPU 并可能阻塞并发写入器。

\n

请记住,索引是以不同方式排序的基础数据的单独子集。更高效的搜索的代价是当基础数据发生变化时需要额外的存储和索引维护。

\n

如果您担心特定硬件上的特定情况,请运行基准测试。

\n


Mic*_*een 19

完全相同的论点适用,只是涉及的速度要高得多。数据仍然需要从内存移动到 CPU 缓存并进入寄存器。需要移动的数据越少,完成得越快。索引消除了此移动中的数据。

以前,磁盘到内存的速度是限制因素。相比之下,内存对 CPU 来说是微不足道的。现在磁盘读取已被消除,读取 RAM 是限制因素。索引可以帮助解决这个问题。