【问题标题】:How do I improve performance when querying on a column that changes frequently in SQL Azure using LINQ to SQL使用 LINQ to SQL 在 SQL Azure 中查询频繁更改的列时如何提高性能
【发布时间】:2014-03-02 19:05:54
【问题描述】:

我有一个 SQL Azure 数据库,其中一张表包含超过 40 万个对象。此表中的一列是对象下载次数的计数。

我有几个查询包括这个特定的列(称为timesdownloaded),按降序排序,以便找到结果。

这是 LINQ to SQL 中的示例查询(我在 C# .NET 中编写所有这些):

var query = from t in db.tablename
    where t.textcolumn.StartsWith(searchfield)
    orderby t.timesdownloaded descending
    select t.textcolumn;

// grab the first 5
var items = query.Take(5);

这个查询平均每分钟调用 90 次。

平均每分钟可能会下载 10 次对象,因此 timesdownloaded 列的更新频率很高。

您可以想象,任何涉及timesdownloaded 列的索引都会在几个小时内产生超过 30% 的碎片。我已经实施了一个索引维护计划,每隔几个小时检查和重建这些索引。这会有所帮助,但是当我希望避免或最小化重建索引时,当然会增加查询响应时间的峰值。

我尝试了多种索引方案。

表现最好的索引覆盖了同时包含textcolumntimesdownloaded 列的索引。重建这些索引后,查询速度当然快得惊人。

但是,这些索引碎片严重,由于重建索引和其他我不了解的因素,我最终会出现相当频繁的延迟峰值。

我也尝试过不索引timesdownloaded 列。这似乎在整体上表现得更加一致,尽管当然速度较慢。当我检查 SQL 查询执行计划时,SQL 尝试优化此查询的方式似乎非常不一致。当然,它以逻辑读取日志结束,因为它必须从表中获取timesdownloaded 列,而不是有组织的索引。所以这不是最优的。

我想弄清楚的是,我是否从根本上遗漏了我配置或管理此数据库的方式。

我不是 SQL 专家,我还没有找到如何做到这一点的好答案。

我看到了一些存储过程可以提供帮助的建议,但我不明白为什么,也没有尝试让这些建议与 LINQ 一起使用。

如下所述,我考虑过缓存,但还没有采取这一步。

在某些情况下,此查询是搜索建议功能的一部分。所以它经常被许多不同的搜索词调用。

任何建议将不胜感激!

【问题讨论】:

  • 您只需要 Take(5) 还是您还需要更深入地查询表格?否则缓存前 5 名将是一个解决方案
  • 在这个例子中,我只选择了前 5 名。在本专栏的其他查询中,我需要更深入。
  • 我仍然会将 topX 缓存在内存或另一个表/索引视图中,然后转到该表...
  • 对于 400k 的对象,每分钟 10 次更新和每分钟 90 次查询,您的索引需要重建是正常的,如果不是,查询速度很慢。我建议您将更新(下载)存储在单独的表中并定期更新真实表以尽量减少更新次数,以便尽可能长时间地将更新与读取分开。例如,当数据库工作负载最低时,您可以每天更新一次表。但是,在您的情况下,当然需要任何形式的缓存。
  • 感谢您的建议。

标签: sql .net performance linq-to-sql azure-sql-database


【解决方案1】:

根据我的问题的 cmets 和进一步的测试,我最终使用 Azure 表来缓存我的结果。这工作得非常好,我的缓存命中率很高,SQL 查询也少得多。我的 API 的整体性能现在好多了。

我确实尝试过在角色缓存中使用 Azure,但该方法似乎不能很好地满足我的需求。它最终使用了太多内存(无论我如何配置它,我都不明白),疯狂地交换到磁盘并让我的小 Small 实例屈服。我现在不想多付钱,所以是 Tables。

感谢您的建议!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-16
    • 2021-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多