SQL Server-奇怪的索引用法
这是我处理的原始查询SQL Server-奇怪的索引用法,sql,tsql,indexing,seek,Sql,Tsql,Indexing,Seek,这是我处理的原始查询 SELECT TOP(10) * FROM Orders o WHERE (o.DateAdded >= DATEADD(DAY, - 30, getutcdate())) AND (o.DateAdded <= GETUTCDATE()) ORDER BY o.DateAdded ASC, o.Price ASC o.Quantity DESC 这一切都会下地狱(不幸的是,我需要这条线)。如果只是o.Price,它的行为也是一样的。我认为这是由于前10名不
SELECT TOP(10) *
FROM Orders o
WHERE (o.DateAdded >= DATEADD(DAY, - 30, getutcdate())) AND (o.DateAdded <= GETUTCDATE())
ORDER BY o.DateAdded ASC,
o.Price ASC
o.Quantity DESC
这一切都会下地狱(不幸的是,我需要这条线)。如果只是o.Price,它的行为也是一样的。我认为这是由于
前10名
不能在订购人
之前发生。
而且,必须等待结果集准备就绪后,才能执行此ORDER BY
如果没有额外的价格范围,前10名
可以直接从现有指数中获取。但添加第二个范围将强制首先运行另一个操作
简言之:
- 首先,过滤器必须获取价格范围的行以及日期范围
- 对结果集进行排序,并取前10行
- 将一个按日期范围过滤的中间集写入临时表,然后从那里开始。您甚至可以在那里的price列上创建一个索引(取决于预期的行数。可能是最好的选择)
- 使用CTE定义按日期范围过滤的集合,并使用此集合应用您的价格范围。但CTE与临时表不同。最终执行计划可能与以前相同
- 使用两个CTE定义两个集合(每个范围一个),并使用
作为与内部联接
相同的方法WHERE condition1和condition2
- 优化器不可能同时使用两个范围谓词
想想看:它从索引中按
DateAdded
排序的某个点开始扫描。现在,它需要在每个单独的DateAdded
值中查找特定的价格
,开始扫描,并在另一个价格
处停止,然后跳到下一个DateAdded
这称为跳过扫描,只有当第一个谓词的值不是很多时,它才有效,否则效率就低,因此,只有Oracle实现了它,而不是SQL Server。两个范围很难优化。
AND o.Price BETWEEN convert(decimal(19,8), 0) AND @BuyPrice