如何使用分组和筛选来加速SQL Server查询

时间:2013-07-20 22:15:00

标签: sql sql-server performance

我的常规任务是在我们的Web应用程序(asp.net + mssql)中显示销售历史。 我有一张销售交易表,如:

 - SellerID (string)
 - Product PartNumber
 - Product ManufacturerName
 - ProductID (string uniq normalized PN+MN)
 - Date of sale
 - Price
 - Qty
 - Option 1
 - Option 2
 - Option 3

选项是一些特定属性(如合同号等)。

我需要显示按productID分组的销售数据,其中包含数量和金额的总和。 此外,我需要提供按SellerId,日期和选项筛选的功能。 所以用户应该看表:

 - Part Number
 - Manufacturer Name
 - Sum(Qty)
 - Sum(Price)

用户也可以按显示的列进行排序和过滤,然后浏览页面

目前我们有大约5M的销售记录,并且使用这种分组,过滤和排序的“直接”查询花费了太多时间(并且它没有想到这个Web服务可以被几个并发用户使用)。

为了使其更快地工作,我们习惯通过查询中使用的所有标准创建缓存键,并使用相同的方案(加上缓存键)复制缓存表中查询的整个结果。但是有一些缺点,比如缓存表的快速增长,以及在缓存表中创建凹陷的困难(它减慢了插入速度)

我非常确定这项任务非常普遍,并且对于大多数使用销售的业务应用程序来说都很有用。

人们如何解决所有这些问题?

UPD: 我忘了提。

  1. 没有销售数据的插入(我们过去每季度手动加载一次)

  2. 我在考虑olap,但从未真正使用它。使用olap是否有意义?

  3. 我们对SQL Server没有很大的限制,如果有意义我们可以使用任何其他数据库

1 个答案:

答案 0 :(得分:2)

问题的解决方案取决于查询和数据结构的混合。

对于您所描述的内容,自然格式将是一个星型模式,中间有一个事实表。但是,事实表可能与您现在的情况非常接近。不同之处在于记录的大小。事实记录会将大部分“可读”内容移动到引用表,因此每条记录都尽可能小。它可能看起来像:

  • SellerID - 整数id
  • ProductID - 整数id
  • 销售日期
  • 价格
  • 数量
  • 选项1 - smallint
  • 选项2 - smallint
  • 选项3 - smallint

类似的事情:

  • 产品PartNumber
  • 产品制造商名称
  • 卖家名称

将在参考表中。

这本身可能会将事实表降低到适合您缓存的大小。

接下来,开始构建索引。您可能需要多个索引,具体取决于过滤条件:(date, salesid, productid, option1, option2, option3)(productid, date)等等。我意识到索引确实需要额外的插入工作。影响取决于每天的插入次数。对于决策支持系统,您应该能够忍受“数据延迟”,您可以定期更新数据。批量插入有助于索引构建开销。

如果您的要求是用于实时报告,那么请考虑对数据进行分区,以便将最新数据放在一个小分区中。分区索引较小,因此插入的开销应该更小。

而且,如果您的要求非常繁重 - 每分钟有大量实时更新,大量实时报告切片和切块,以及需要完整历史记录的大量查询 - 那么就会投入更多内存,因此表格将会更多容易融入记忆中。在此过程中,您可以优化中央数据结构,使其由ID和数字量组成,参考表包含其他数据。主键上的连接比存储数据更快,否则会更多时间。