如何将整个数据库加载到内存中?

Joh*_*Doe 1 sql-server optimization memory cache sql-server-2014

我想将整个数据库加载到内存中,但是我该怎么做呢?我有大约 256 GB 的内存,我的数据库大约有 200 GB,所以我可以轻松地处理内存。

当我执行select count(*) from table1sqlserver 自动将表加载到内存之后,我可以非常快速地使用表,但我想知道如何将整个数据库加载到内存中?

如果我select count(*) from在每个表上都这样做,我可以更快地工作,但是有没有其他方法可以将整个数据库加载到内存中?我想通过一个命令加载整个数据库,而不是一个select count(*) from表一个表。

Sol*_*zky 5

我想将整个数据库加载到内存中,但是我该怎么做呢?

在弄清楚“如何”做某事之前,通常最好先弄清楚“为什么”应该做某事。那么,为什么要将整个数据库加载到内存中呢?内存是一种有限资源,因此需要有效/明智地使用它。

我有大约 256 GB 的内存,我的数据库大约有 200 GB,所以我可以轻松地在内存中处理

好的,所以您似乎拥有超出数据库大小的 56 GB RAM。但这里是数据本身之外没有考虑的内容:

  • 除非您的公司倒闭,否则数据库会增长,即使您归档了旧数据。56 GB 很快就不够用了吧?
  • 操作系统需要内存(Windows 以及相关服务,如计划任务等)
  • 3rd 方软件需要内存(监控、防病毒等)
  • 需要内存来运行数据库引擎进程(MSSQLSERVER 或 InstanceName NT 服务)
  • 运行 SQL Server 代理进程需要内存
  • 每个连接/会话都需要一定数量的内存
  • 查询需要内存(查看查询计划的“内存授予”):
    • 聚合操作
    • 计算
    • 排序
    • 等等
  • 当对象调用其他对象时,SQL Server 维护每个父上下文的调用堆栈,以便在当前上下文完成时控制可以恢复到该父上下文。这个调用栈是在内存中管理的。
  • 查询计划缓存
  • DMV 统计/信息
  • 结果集(或至少指向每个进程当前所在的每个结果集中的位置的指针)
  • 等等
  • 等等

现在,关于那 200 GB 的数据,您应该考虑:您是否使用了所有200 GB 的数据?我非常怀疑。将数据页加载到内存中而不引用它们是低效和浪费的。您最好按需加载页面,因为用于获取它们的磁盘 I/O 以及它们占用的内存将值得这两种资源,因为您不会将它们浪费在没人想要的页面上。

我想通过单个命令而不是SELECT *逐表加载整个数据库。

不,没有一个命令可以做到这一点。

此外,该SELECT COUNT(*)方法甚至没有实现这个目标。它所做的只是通过扫描加载它可以找到的最小对象,它可能是一个非聚集索引,或者它实际上可能是基表本身。但它不加载:

  • 内存中的任何索引(如果扫描表)或表本身到内存中(如果扫描索引),也没有未扫描COUNT(*)操作的任何对象。因此,如果操作使用非聚集索引,您仍然需要找到一种方法来强制对所有非聚集索引和/或表/聚集​​索引扫描进行索引扫描COUNT(*)。但这会更加浪费,因为它们不仅不总是被使用,而且每次加载它们都会违背您使用索引 DMV 来确定哪些索引实际上未被使用的能力!
  • 任何行外 LOB 数据页(可能不是溢出页)。您需要单独选择任何 LOB 列,以及任何具有溢出数据的可变长度列。