MarketPlane
表包含超过6000万行。
当我需要特定日期的飞机总数时,我执行此查询需要超过7分钟。我怎样才能减少这段时间?
SELECT COUNT(primaryKeyColumn)
FROM MarketPlan
WHERE LaunchDate > @date
我已经实现了链接中提到的所有内容,即使现在我已经实现了With(nolock)
,这可以将响应时间减少到5分钟。
答案 0 :(得分:3)
您必须在桌面上create an index,或者按日期partition the table。
您可能还想查看
SQL Server 2000/2005 Indexed View Performance Tuning and Optimization Tips
答案 1 :(得分:0)
相关表格是否在LaunchDate
列上有索引?另外,你真的想发帖LaunchDate>@date
吗?
答案 2 :(得分:0)
假设基于@date的SQL-Server,尽管可以将其应用于大多数数据库。
如果您的主要查询是选择一系列数据(基于样本),添加或更改CLUSTERED INEDX将大大有助于缩短查询时间。
请参阅:http://msdn.microsoft.com/en-us/library/ms190639.aspx
默认情况下,SQL-Server将主键创建为聚簇索引,从事务的角度来看这是很好的,但如果您的重点是检索数据,那么更改默认值会产生巨大的差异。
CREATE CLUSTERED INDEX name ON MarketPlan (LaunchDate DESC)
注意:假设LaunchDate是一个静态日期值,主要以递增/顺序顺序插入,以最小化索引碎片。
答案 3 :(得分:0)
这里有一些很好的建议,如果所有其他方法都失败了,请考虑一点非规范化,创建另一个包含累积计数的表并用触发器更新它。如果您有更多这种性质的疑问,请考虑OLAP
答案 4 :(得分:0)
您的特定查询不需要日期列上的群集密钥。使用带有前导日期列的非聚簇索引实际上会更好地运行,因为您不需要在此查询中执行键查找,因此非聚簇索引将覆盖并且比聚簇更紧凑(它隐式包括聚簇键列)。 如果你正确索引它并且它仍然没有执行它很可能是碎片。在这种情况下,对索引进行碎片整理并重试。
答案 5 :(得分:0)
像这样创建一个新索引:
在MarketPlan上创建INDEX xLaunchDate(LaunchDate,primaryKeyColumn)
查看这篇关于索引如何提高性能的好文章。
答案 6 :(得分:0)
“WHERE LaunchDate> @date”
参数@date的值是否在同一批次(或事务或上下文)中定义? 如果不是,那么如果其值来自当前批次之外(例如,存储过程的输入参数),则这将导致聚集索引扫描(所有行)而不是聚集索引搜索(仅满足WHERE条件的行)或udf功能) SQL Server优化器(在编译时)无法完全优化查询,导致全表扫描,因为参数值仅在运行时知道
更新:评论提出OLAP的答案 OLAP只是概念,SSAS多维数据集只是OLAP实现的可能方式之一 获取/使用OLAP概念是方便而非义务 您尚未使用SSAS来使用OLAP概念 例如,见Simulated OLAP
更新2:评论评论to answer:
MDX是SSAS提供的选项/便利/功能/功能(cube / OLAP)没有义务
答案 7 :(得分:0)
你能做的最简单的事情是:
SELECT COUNT(LaunchDate)
FROM MarketPlan
WHERE LaunchDate > @date
这将保证您对任何LaunchDate索引的索引检索。
另外(这取决于你的执行计划),我见过实例(但不是特定于SQL Server),其中&gt;做过表扫描,BETWEEN使用了索引。如果您知道最新日期,可以尝试WHERE LaunchDate BETWEEN @date AND <<Literal Date>>
。
答案 8 :(得分:0)
桌子有多宽?如果表是宽的(即:(n)char,(n)varchar或xml的许多列),可能会有大量的IO导致查询由于使用聚簇索引而运行缓慢。
要确定IO是否导致长查询时间,请执行以下操作:
运行下面的查询,计算LaunchDate并强制使用新索引。
SELECT COUNT(LaunchDate)
FROM MarketPlan WITH(INDEX = TheNewIndexName)
WHERE LaunchDate&gt; @date
我不喜欢使用索引提示,我只建议此提示仅用于证明IO是否导致查询时间过长。
答案 9 :(得分:0)
有两种方法可以做到这一点
首先在日期列上创建聚簇索引,因为查询是特定于日期范围的,所有数据都将按实际顺序排列,这将避免必须扫描表中的所有记录
< / LI>您可以尝试使用水平分区,这会影响您现有的表设计,但这是最佳方式,请参阅此 http://blog.sqlauthority.com/2008/01/25/sql-server-2005-database-table-partitioning-tutorial-how-to-horizontal-partition-database-table/