MySQL EXPLAIN:"使用索引"与"使用索引条件"

Pis*_*3.0 31 mysql optimization

关于使用EXPLAIN优化查询MySQL 5.4文档说明了这些额外的评论:

  • 使用索引

仅使用索引树中的信息从表中检索列信息,而不必另外寻找读取实际行.当查询仅使用属于单个索引的列时,可以使用此策略.

[...]

  • 使用索引条件

通过访问索引元组并首先测试它们以确定是否读取完整的表行来读取表.以这种方式,索引信息用于推迟("下推")读取全表行,除非有必要.

我错过了什么,或者这两个意思是相同的事情(即"没有阅读行,索引就够了")?

mjv*_*mjv 71

一个例子最好地解释了:

SELECT Year, Make --- possibly more fields and/or from extra tables
FROM myUsedCarInventory
WHERE Make = 'Toyota' AND Year > '2006'

Assuming the Available indexes are:
  CarId
  VIN
  Make
  Make and Year
Run Code Online (Sandbox Code Playgroud)

该查询将与"使用索引",因为它并不需要解释所有,"打"的myUsedCarInventory表本身,因为"制作和年"指数"覆盖"其需要与问候WHERE子句的元素属于该表.

现在,想象一下,我们保持查询相同,但是为了在颜色上添加条件

...
WHERE Make = 'Toyota' AND Year > '2006' AND Color = 'Red'
Run Code Online (Sandbox Code Playgroud)

这个查询可能是EXPLAIN的'使用索引条件'('可能',这里的情况是丰田+年不会被估计有足够的选择性,优化器可能决定只扫描表).这意味着MySQL的将FIRST使用索引来解决制作+年,并且它会查找相应行的表也,只为满足制作+新年条件的行.这有时被称为" 下推优化 ".


And*_*mar 6

区别在于"使用索引"不需要从索引到表的查找,而"使用索引条件"有时必须.我将尝试用一个例子来说明这一点.假设你有这张桌子:

id, name, location
Run Code Online (Sandbox Code Playgroud)

带索引

name, id
Run Code Online (Sandbox Code Playgroud)

然后这个查询不需要任何表的表,它可以检索它的所有信息"使用索引":

select id, name from table where name = 'Piskvor'
Run Code Online (Sandbox Code Playgroud)

但是这个查询需要对名称等于'Piskvor'的所有行进行表查找,因为它无法从索引中检索位置:

select id from table where name = 'Piskvor' and location = 'North Pole'
Run Code Online (Sandbox Code Playgroud)

查询仍然可以使用索引将结果限制为具有特定名称的小行集,但是它必须查看表中的那些行以检查位置是否也匹配.

  • "它可以使用索引检索所有信息" - 它只能使用复合索引中的第二列?我认为对于`select id,name from table name ='Piskvor'`索引`(id,name)`将不会被使用,而不是索引`(name,id)`.你能澄清一下吗? (2认同)