Sql 与何处连接的索引列

Sql 与何处连接的索引列,sql,join,indexing,Sql,Join,Indexing,假设您有一个连接和其中: SELECT * FROM partners JOIN orders ON partners.partner_id = orders.partner_id WHERE orders.date BETWEEN 20140401 AND 20140501 1) 两个表中的partner\u id索引将加速加入,对吗? 2) orders.date上的索引将加速WHERE子句? 3) 但据我所知,一个SELECT不能使用多

假设您有一个
连接
其中

SELECT   * 
FROM     partners
JOIN     orders 
    ON   partners.partner_id = orders.partner_id
WHERE    orders.date 
    BETWEEN 20140401 AND 20140501
1) 两个表中的
partner\u id
索引将加速
加入
,对吗?
2)
orders.date上的索引将加速
WHERE
子句?

3) 但据我所知,一个
SELECT
不能使用多个索引。那么将使用哪一个呢?

首先,索引用于操作符,而不是选择语句。因此,一个索引将用于从
合作伙伴
表中读取数据,另一个索引可用于从
订单
表中获取数据


我认为在这种情况下,最好的策略是在
合作伙伴.partner\u id
上有一个聚集索引,在
订单.partner\u id
订单.date

上有一个非聚集索引。首先,索引用于操作符而不是SELECT语句。因此,一个索引将用于从
合作伙伴
表中读取数据,另一个索引可用于从
订单
表中获取数据


我认为在这种情况下,最好的策略是在
合作伙伴.partner\u id
上有一个聚集索引,在
订单.partner\u id
订单.date
上有一个非聚集索引参见案例。这是一个例子

SELECT  * 
FROM    [dbo].[LUEducation] E
JOIN    LUCitizen C On C.skCitizen = E.skCitizen
WHERE   C.skCitizen <= 100 
AND     E.skSchool = 26069
选择*
来自[dbo][LUEducation]E
在C.skCitizen=E.skCitizen上加入LUCitizen C

其中C.skcident参见案例。这是一个例子

SELECT  * 
FROM    [dbo].[LUEducation] E
JOIN    LUCitizen C On C.skCitizen = E.skCitizen
WHERE   C.skCitizen <= 100 
AND     E.skSchool = 26069
选择*
来自[dbo][LUEducation]E
在C.skCitizen=E.skCitizen上加入LUCitizen C

其中C.skCitizen如果不知道您正在使用哪个DBMS,就很难知道优化器将选择什么执行计划

这是一个典型的例子:

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

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

但是,如果WHERE子句不存在,您可能会看到一个执行计划

使用partners.partner\u id和 orders.partner\u id


这个术语可能会混淆,因为DBMS的文档可能使用不同的术语

如果不知道您使用的是哪种DBMS,就很难知道优化器将选择什么执行计划

这是一个典型的例子:

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

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

但是,如果WHERE子句不存在,您可能会看到一个执行计划

使用partners.partner\u id和 orders.partner\u id


这个术语可能会混淆,因为DBMS的文档可能使用不同的术语

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

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

对于第一种方法,唯一有用的索引是
订单(合作伙伴id,orderdate)
。对于第二种方法,最好的索引是
orders(orderdate,partner\u id)
。请注意,这些不是等效的


在大多数这样的场景中,我希望orders表更大,过滤也更重要。这表明最好的执行计划是从
orders
表开始,首先使用第二个选项对其进行过滤。

这是您的查询,报价是固定的(假设
orders.date
确实是日期类型):

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

对于第一种方法,唯一有用的索引是
订单(合作伙伴id,orderdate)
。对于第二种方法,最好的索引是
orders(orderdate,partner\u id)
。请注意,这些不是等效的


在大多数这样的场景中,我希望orders表更大,过滤也更重要。这表明最好的执行计划是从
orders
表开始,首先使用第二个选项对其进行过滤。

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

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

请参阅执行计划,我认为将使用两个索引。我不认为优化器一次只使用一个索引。根据SQL语句中的倒勾添加了
mysql
标记。partners.partner\u id(大概)是一个主键,所以它已经被索引了。(orders.partner\u id,orders.date)[或相反]上的复合索引可能是最佳的。@A\u horse\u的名称不是mysql,主要是Oracle和DB6那么,如果不使用mysql,为什么要使用mysql特定的语法呢?还有什么