【问题标题】:Slow performance on table with just over 1 million records: Are the indexes wrong?超过 100 万条记录的表性能缓慢:索引是否错误?
【发布时间】:2020-10-31 10:07:36
【问题描述】:

有人要求我调查一个越来越慢的应用的性能问题。很快,我就能够将问题缩小到单个数据库表。结构不佳的 C# 代码我可以优化。但是对于 SQL 表,我不太自信。所以我在这里希望得到一些帮助!

有问题的表格存储了应用程序中使用的某些关键字的多语言翻译。这是一张成长表。随着它的增长,基本 SELECT 和 JOIN 的性能开始急剧下降。目前,表中只有超过 100 万条记录,实际上并没有那么多。

例如:

SELECT * FROM PE_TranslationPhrase WHERE Phrase = 'ABC-123'

这可能需要 8 到 32 秒才能完成。

该表托管在 Azure SQL 上。下面在 SSMS 中看一下:

所以它没有那么复杂的表格。主键结构不仅仅是您正常的自动递增整数。 TranslationIdCultureName 一起构成主键(这很好)。

在处理性能问题时,首先要看的地方当然是索引。这就是现在摆在桌面上的东西:

CLUSTERED:
 - [TranslationId] ASC,
 - [CultureName] ASC

STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF

NON-CLUSTERED:
 - [CultureName] ASC,
 - INCLUDE ([Phrase])

STATISTICS_NORECOMPUTE = OFF, DROP_EXISTING = OFF, ONLINE = OFF

具有PhraseCultureName 的非聚集索引的原因是因为这些列一直用于过滤器和连接。示例:

LEFT JOIN 
    PE_TranslationPhrase TP 
    ON A.Description COLLATE Latin1_General_CS_AS = TP.Phrase COLLATE Latin1_General_CS_AS 
    AND A.CULTURENAME = TP.CultureName

我的尝试和问题:

我尝试重建索引:

ALTER INDEX ALL ON dbo.PE_TranslationPhrase REBUILD

这似乎对性能没有可衡量的影响。

我的问题是:将CultureName 作为两个索引的一部分是不是很糟糕? 我该如何/应该更改这些索引?

谢谢!!

【问题讨论】:

    标签: sql sql-server indexing azure-sql-database database-tuning


    【解决方案1】:

    对于这个查询:

    SELECT * FROM PE_TranslationPhrase WHERE Phrase = 'ABC-123'
    

    您想要一个索引,其中Phrase 是索引中的第一个键。

    您的所有索引都没有Phrase 作为第一列,因此数据库需要扫描整个表。

    【讨论】:

    • 好的,谢谢戈登!那个例子就是……一个例子。也许这不是一个很好的。我更担心同时使用 CultureNamePhrase 的 JOIN 性能缓慢
    • @CaseyCrookston 连接可能同时存在于CultureNamePhrase,但是什么限制了该连接的左侧部分?
    • 短语是nvarchar(max),所以你必须限制它来索引它。如果短语很长,也许你应该索引 PhraseHash 并在查找中使用它。
    • @GSerg,好问题。连接的另一半是作为参数传入的 JSON 数据。根据您之前的评论,我正在寻找“CultureName”是否存在,我认为不是。 (这是一个巨大的json文件)
    • @DavidBrowne-Microsoft - 很棒的收获!我会看一下该列中的数据,看看是否可以将其更改为远离(max)
    猜你喜欢
    • 2014-07-09
    • 2013-11-02
    • 2019-11-16
    • 2021-12-30
    • 2021-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多