Raz*_*zle 0 sql performance sql-server-2008
想知道为什么这个查询执行缓慢.如果有人可以告诉我如何处理它将是伟大的.被查询的DB有超过5亿行.这个查询是否真的写得不好,以至于TOP 10需要很长时间才能完成它可能永远不会完成?假设我仍然希望按月+年查询数据,我该如何改进查询?
SELECT TOP 10 *
FROM ADB.dbo.Stuff tt
WHERE MONTH(tt.SomeDate) = 5
AND
YEAR(tt.SomeDate) = 2011
Run Code Online (Sandbox Code Playgroud)
SELECT TOP 10不仅在获得10个结果后停止吗?还是需要这么长时间,因为它在通过500米+行时还没有找到我的条件?
谢谢,抱歉这么简单的问题.
它扫描整个表,因为MONTH(column)并YEAR(column)没有优化搜索,你还没有告诉SQL服务器你的意思TOP.虽然SQL Server可能能够短路,但它找到了你的10行,但是当发生这种情况时,它可能会进入扫描范围,这对你来说差别很小.如果您发现零行或<10行与您的where子句匹配,则尤其如此.
一个更好的WHERE条款是:
WHERE SomeDate >= '20110501' AND SomeDate < '20110601';
Run Code Online (Sandbox Code Playgroud)
如果您不想构造字符串,可以将它们作为参数/变量传递并执行以下操作:
DECLARE @year INT;
DECLARE @month INT;
SET @year = 2011;
SET @month = 5;
...
WHERE SomeDate >= DATEADD(MONTH, @month-1, DATEADD(YEAR, @year-1900, '19000101'))
AND SomeDate < DATEADD(MONTH, @month, DATEADD(YEAR, @year-1900, '19000101'));
Run Code Online (Sandbox Code Playgroud)
在任何一种情况下,如果有索引SomeDate,则可以使用它并且可以避免表扫描.您希望避免在具有5亿行的表上进行表扫描,即使您只查找10行,即使可能发生短路.
但是,即使没有表扫描,此查询仍然效率低下.你真的需要所有的专栏吗?如果使用了索引,SomeDate则搜索仍然必须查找聚簇索引或覆盖索引以检索其余列.如果您不需要这些列,请不要包含它们.
而作为bluefeet指出,这个TOP 10东西是没有意义的,如果你还没有告诉SQL服务器这你的意思是10,和你做,使用ORDER BY.如果ORDER BY使用合适的索引,您可以避免使用额外的昂贵的排序运算符,您可能认为ORDER BY无论如何都要避免使用它.
| 归档时间: |
|
| 查看次数: |
745 次 |
| 最近记录: |