索引会消耗内存吗?


10

我刚刚开始了解SQL Server上的内存使用情况。在问题SQL Server 2008 R2“ Ghost Memory”问题的答案中使用查询时,我发现单个数据库占用了缓冲池中绝大部分的空间。再看一下,使用sys.allocation_unitssys.indexes,我确认这很可能是由于数据库中索引的大量使用引起的。大多数索引都是群集的。

另一位数据库开发人员认为我们在服务器上遇到内存问题-由于没有可用的内存,查询开始运行很长时间。

我的问题是-使用这些索引及其在缓冲池中的存在是否会占用其他进程可用的内存?


2
"Another database developer believes we are having memory issues on the server" - 根据什么?服务器有多少RAM,实例内存设置是什么,过程高速缓存正在消耗多少内存?
乔恩·塞格尔

基于延长的查询时间并查看任务管理器-我的研究表明这是“肮脏,肮脏的骗子”(感谢Brent Ozar-brentozar.com/archive/2011/09/…)。我可能发现没有内存问题-我正在关注这些评论和答案中提供的所有建议!
JHFB

2
由于我们将8滚到这里,我认为查询运行缓慢,因为它们是由“另一个”数据库开发人员编写的……
Remus Rusanu 2012年

Answers:


12

是的,缓冲池中缓存的已使用索引的数据页将占用数据缓存中的空间。但是不要让您转而使用索引(首先,聚集索引是实际的表数据,因此请记住这一点)。索引的使用(当然是正确设计和实现的)是一件好事。

您的内存问题很可能不是来自表上的索引。深入探讨内存问题,究竟是什么问题?您的页面预期寿命低吗?如何在服务器上配置内存?服务器最大内存是否不足以限制缓冲池的大小?

要获得数据高速缓存中索引页的细分,可以运行以下查询:

select
    count(*) as total_page_count,
    count(*) * 8 as total_consumption_kb,
    sum(row_count) as total_row_count
from sys.dm_os_buffer_descriptors
where page_type = 'INDEX_PAGE'
group by page_type

要通过数据库获取这些统计信息:

select
    db_name(database_id) as database_name,
    count(*) as total_page_count,
    count(*) * 8 as total_consumption_kb,
    sum(row_count) as total_row_count
from sys.dm_os_buffer_descriptors
where page_type = 'INDEX_PAGE'
group by database_id
order by total_consumption_kb desc

体面(?)页面预期寿命-4234。我需要研究缓冲区高速缓存命中率,并研究其他部分。
JHFB

PLE根本没有显示内存压力。根据经验,超过1000的任何值(当然,总有“取决于”)是可以接受的。
托马斯·斯金格

缓冲区高速缓存的命中率可能会产生很大的误导,或者出入无用。请参阅@JonathanKehayias的《Great SQL Server辩论:缓冲区高速缓存命中率》
Mark Storey-Smith'7

@ MarkStorey-Smith注意,感谢您的指导!
托马斯·斯金格

@JHFB让我们退后一步。是什么让您认为自己有记忆力不足?
托马斯·斯金格

7

索引占用缓冲池空间,是的。这是为什么您应该注意索引策略并尽量减少重复项的另一个原因。

我确认这很可能是由于数据库中索引的大量使用引起的。大多数索引都是群集的。

请记住,是聚集索引。聚集索引存在的唯一开销要高于堆开销(通常是不希望的),这是非叶子索引页以及该表的所有非聚集索引中都包含集群键的开销。这就是为什么首选窄群集密钥的原因。

金伯利·特里普(Kimberley Tripp)的有关集群键选择的文章对此非常有用。


+1 Tripp女士的文章是有关群集密钥的EPIC ...
Fabricio Araujo,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.