SQL Server何时选择索引扫描?
select
a.Transport_Mode, sum(a.Inv_Qty)
from
dbo.DespSum_Year a, dbo.Item_Master b
where
a.Inv_Date between '2011-04-01' and '2012-03-31'
and a.item_name = b.itemcode
group by
a.Transport_Mode
我在despsum_year
中有1000万行,而在Inv_date
上有非聚集索引。SQL Server何时选择索引扫描?
当我运行上面的查询时,它显示了它使用表扫描。任何人都可以告诉我如何使用索引扫描进行查询?
您的查询有三个部分需要排序表。
1. JOIN
2. WHERE
条款
3. GROUP BY
您的查询不使用索引,因为其他人都被认为是更重要的。将索引放在其他字段上,并在合适的位置放置合成索引。
我会给更多的细节,但不幸的是你的查询并没有说哪个字段属于哪个表。请给出完整详细信息的每个表的架构和索引更多细节。此外,知道更多的数据行为将是很好的:将通过Transport_Mode的Gouping给几个大组或许多小组? item_name/itemcode是一个表中的唯一键吗?等等,等等
编辑
感谢您将这些表的字段查询。在不了解数据的情况下,它仍然非常有限,但我会尽力帮助你。
1)。你不使用你的SELECT
或GROUP BY
的Item_Master
这意味着你要么用它无论是作为过滤器(1:0..1),或倍数(1:1..many) ,或两者(1:0..many)。
我假设你将它用作过滤器。
2)。您使用BETWEEN
过滤Inv_Date
我假设Inv_Date
是DATETIME,没有时间部分;它总是午夜 - 只表示日期。给你366日期的情况下(闰年)。
连同这些意味着你必须要由两列组由第三方来过滤表。您需要确定应该对这些字段进行排序的次序,以尽最大努力为您提供最终结果。
有6种可能性...
1). Transport_Mode => Item_Name => Inv_Date
2). Transport_Mode => Inv_Date => Item_Name
3). Item_Name => Transport_Mode => Inv_Date
4). Item_Name => Inv_Date => Transport_Mode
5). Inv_Date => Transport_Mode => Item_Name
6). Inv_Date => Item_Name => Transport_Mode
如果你有Transport_Mode
第一,这是你的GROUP BY
非常友好。每种可能的模式将被预先分组在一起,准备汇总而不需要分类。然后,对于每个组,你只需要过滤记录,具有JOIN
过滤Item_Name
和BETWEEN
过滤Inv_Date
。
因此,在(Transport_Mode, Item_Name, Inv_Date)
覆盖索引似乎对我好。
但是,这部分是因为你有Inv_Date
你的查询占地面积366个值。如果你在一天内只感兴趣,这将是最好有(Inv_Date, Transport_Mode, Item_Name)
但是,如果你有Item_Name
在Transport_Mode
和许多值很少价值观,也许你会从具有Item_Name
在索引Transport_Mode
之前受益?
如果没有更多的细节上的数据,我会建议创建所有6项指标,尽显你的表达表示现实生活中的情况(如果没有的话),然后运行查询。当你检查执行计划时,你可以看到优化器喜欢哪个索引。
或者创建一个在时间和因为它使用不同的指标和执行计划轮廓查询。然后,您可以在所有查询中保留对您最有用的一个,而不仅仅是一个。
但,在所有情况下,确保你在Item_Master
表索引itemcode
以及!
非常优秀和详细的答案给予我的理解。感谢它。 – 2012-03-30 10:10:54
这取决于很多因素。您可以尝试强制在查询提示中使用索引,并比较执行计划(特别是主键查找的估计行数和成本)。日期条件的选择性是什么?一般来说,对于这个查询(实际上它取决于数据结构,但仅仅作为一个假设),索引on(item_name,Transport_Mode)会更好。
OP很好地隐藏了它,但这是一个加入...'从DespSum_Year,Item_Master'' – MatBailie 2012-03-30 08:23:33
架构?我们不知道什么是什么桌子。 – 2012-03-30 08:20:26
表扫描表明是一个**堆** - 没有聚集索引。修复**第一**。然后你需要确保在'inv_date','item_name'和'itemcode'上有一个索引 - 甚至可能有'transport_mode'。 – 2012-03-30 08:24:47
@marc_s:OP隐藏得很好,但这是一个来自DespSum_Year,Item_Master'的连接......所以我们需要每个表的更多细节。 – MatBailie 2012-03-30 08:25:36