Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL Server-奇怪的索引用法_Sql_Tsql_Indexing_Seek - Fatal编程技术网

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