我被要求帮助解决SQL Server安装的性能问题。我不是SQL Server专家,但我决定看看。我们正在使用一个看似正常的闭源应用程序。然而,在从2000年到2005年的SQL Server升级之后,据报道应用程序性能遭受了相当大的损失。我运行SQL分析器并捕获以下查询(字段名称已更改以保护无辜者)大约需要30秒才能运行。我的第一个想法是我应该优化查询。但这是不可能的,因为应用程序是封闭源代码并且供应商没有帮助。所以我离开了,试图找出如何使这个查询快速运行而不改变它。我还不清楚这个查询如何在较旧的SQL Server 2000产品上运行得更快。也许在该实例上应用了某种性能调整,这种性能调整没有在新的SQL服务器上进行或不能正常工作。想到DBCC PINTABLE。
无论如何,这是违规的查询:
select min(row_id) from Table1 where calendar_id = 'Test1'
and exists
(select id from Table1 where calendar_id = 'Test1' and
DATEDIFF(day, '12/30/2010 09:21', start_datetime) = 0
)
and exists
(select id from Table1 where calendar_id = 'Test1' and
DATEDIFF(day, end_datetime, '01/17/2011 09:03') = 0
);
Table1有大约6200个条目,看起来像这样。我试过创建各种指数没有效果。
id calendar_id start_datetime end_datetime
int, primary key varchar(10) datetime datetime
1 Test1 2005-01-01... 2005-01-01...
2 Test1 2005-01-02... 2005-01-02...
3 Test1 2005-01-03... 2005-01-03...
...
如果有人能帮助解决这个谜团,我将非常感激。
提前致谢。
答案 0 :(得分:2)
应该有用的一件事是calendar_id上的覆盖索引:
create index <indexname>
on table (calendar_id, id)
include (start_datetime, end_datetime);
这将满足calendar_id = 'Test1'
谓词min(row_id)
排序,并将提供评估非SARG能DATEFIFF
谓词的材料。如果表中没有其他列,那么这可能是您需要的聚簇索引,而id
主键应该是非聚簇索引。
答案 1 :(得分:1)
确保索引进行转换。然后更新统计信息
答案 2 :(得分:1)
检查旧sql server和新sql server上的执行计划之间的差异。 http://www.sql-server-performance.com/tips/query_execution_plan_analysis_p1.aspx
答案 3 :(得分:0)
除了Remus Rusanu的索引建议之外,您可以做的另一件事就是升级到具有更高级扫描功能的企业版(在SQL Server 2005和2008 Enterprise Edition上),它允许多个任务共享全表扫描。
除此之外,如果您无法更改查询,我认为您无法做任何事情。原因是查询正在对Where子句中的函数结果进行比较。这意味着它将强制SQL Server在每次执行时对Table1执行表扫描。