假设您有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
不能使用多个索引。那么将使用哪一个?
答案 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_id
和orders.date
上设置一个非聚集索引
答案 2 :(得分:0)
查看案例。这是一个案例
SELECT *
FROM [dbo].[LUEducation] E
JOIN LUCitizen C On C.skCitizen = E.skCitizen
WHERE C.skCitizen <= 100
AND E.skSchool = 26069
执行计划:
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上的索引, 但是对于外键约束是必要的,并加入其他方向。