使用WHERE为JOIN编制索引的列

时间:2014-08-13 10:23:47

标签: sql join indexing

假设您有JOIN WHERE

SELECT   * 
FROM     partners
JOIN     orders 
    ON   partners.partner_id = orders.partner_id
WHERE    orders.date 
    BETWEEN 20140401 AND 20140501

1)两个表中partner_id的索引会加快JOIN,对吧? 2)orders.date上的索引会加快WHERE条款的速度吗? 3)但据我所知,一个SELECT不能使用多个索引。那么将使用哪一个?

5 个答案:

答案 0 :(得分:3)

这是您的查询,引用是固定的(假设orders.date实际上是日期类型):

SELECT *
FROM partners JOIN
     orders
     ON partners.partner_id = orders.partner_id
WHERE orders.date BETWEEN '2014-04-01' AND '2014-05-01';

对于内连接,基本上有两种执行策略。引擎可以从partners表开始,并查找订单中的所有匹配项。或者它可以从订单开始,可以找到合作伙伴的所有匹配。 (然后可以使用不同的算法。)

对于第一种方法,唯一有帮助的索引是orders(partner_id, orderdate)。对于第二种方法,最佳索引是orders(orderdate, partner_id)。请注意,这些不等同。

在大多数情况下,我希望订单表更大,过滤很重要。这表明最佳执行计划是从orders表开始并使用第二个选项首先对其进行过滤。

答案 1 :(得分:2)

首先,索引用于运算符,不用于 SELECT 语句。因此,一个索引将用于从partner表中读取数据,另一个索引可用于从orders表中获取数据。

我认为在这种情况下,最佳策略是在partners.partner_id上设置聚簇索引,在orders.partner_idorders.date上设置一个非聚集索引

答案 2 :(得分:0)

查看案例。这是一个案例

SELECT  * 
FROM    [dbo].[LUEducation] E
JOIN    LUCitizen C On C.skCitizen = E.skCitizen
WHERE   C.skCitizen <= 100 
AND     E.skSchool = 26069

执行计划:

enter image description here

sql引擎一次使用多个索引。

答案 3 :(得分:0)

在不知道您正在使用哪个DBMS的情况下,很难知道优化程序将选择哪个执行计划。

这是一个典型的:

  

对orders.date执行范围扫描,使用为此目的排序的索引。   对结果执行循环连接,执行一次查找   每个条目的partners.partner_id,使用该字段的索引。

在此计划中,不会使用orders.partner_id的索引。

但是,如果没有WHERE子句,您可能会看到

的执行计划
  

使用partners.partner_id和上的索引进行合并连接   orders.partner_id。

此术语可能令人困惑,因为您的DBMS文档可能使用不同的术语。

答案 4 :(得分:0)

一个选择只能使用一个索引每个表(索引合并是一个例外) 你在问题中指出了正确的索引 对于此查询,您实际上不需要orders.partner_id上的索引, 但是对于外键约束是必要的,并加入其他方向。