22. eq_ref类型扫描实例
root@localhost: sakila 09:48:41> EXPLAIN SELECT f.film_id, f.title, c.name
> FROM film f INNER JOIN film_category fc
> ON f.film_id=fc.film_id INNER JOIN category c
> ON fc.category_id=c.category_id WHERE f.title LIKE 'T%' G
*************************** 1. row ***************************
select_type: SIMPLE
table: c
type: ALL
possible_keys: PRIMARY
key: NULL
key_len: NULL
ref: NULL
rows: 16
Extra:
*************************** 2. row ***************************
select_type: SIMPLE
table: fc
type: ref
possible_keys: PRIMARY,fk_film_category_category
key: fk_film_category_category
key_len: 1
ref: sakila.c.category_id
rows: 1
Extra: Using index
*************************** 3. row ***************************
select_type: SIMPLE
table: f
type: eq_ref
possible_keys: PRIMARY,idx_title
key: PRIMARY
key_len: 2
ref: sakila.fc.film_id
rows: 1
Extra: Using where
我们注意到,第三行显示使用
了eq_ref访问,即使在作为
where条件的„film.title „有一可
用索引,但是优化器选择使用
primary key,这是为什么呢?
其实我们可以看到在表
category中有16行,通过
film_category表的链接列能够
快速获取数据,16列比通过
tittle索引过滤得到的结果集46
行要少。
www.2345.com
23. 一个重要的分割索引列
mysql> EXPLAIN SELECT * FROM film WHERE title LIKE 'Tr%'G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: film
得到一个不错的范围查询,tittle上的
type: range
索引得到使用
possible_keys: idx_title
key: idx_title
key_len: 767
ref: NULL
rows: 15
Extra: Using where
mysql> EXPLAIN SELECT * FROM film WHERE LEFT(title,2) = 'Tr' G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: film
情况就不乐观了,索引没有得以使用,
type: ALL
导致全表扫描为什么呢?
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 951
Extra: Using where
www.2345.com
25. unique_subquery访问实例
root@localhost: sakila > EXPLAIN SELECT * FROM rental r WHERE r.customer_id IN (
-> SELECT customer_id FROM customer WHERE last_name LIKE 'S%') G
*************************** 1. row ***************************
id: 1
select_type: PRIMARY
table: r
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 15646
Extra: Using where
*************************** 2. row ***************************
id: 2
select_type: DEPENDENT SUBQUERY
table: customer
type: unique_subquery
possible_keys: PRIMARY,idx_last_name
key: PRIMARY
key_len: 2
ref: func
rows: 1
Extra: Using index; Using where
外表(rental)通过一个全表扫描,
并通过customer_id 常量集,where过
滤后,把此结果集应用到子查询中的
select,逐个进行自查询。注意,这里
的查询类型提示为依赖子查询
(DEPENDENT SUBQUERY),从技
术上说,这是不正确的,因为这里的
子查询不是相关子查询,而应该返回
一个常量列表。因此,这个查询的
“customer.last_name”上的索引没有仸
何价值 …
www.2345.com
26. 重写子查询为标准join
root@localhost: sakila> EXPLAIN SELECT * FROM rental r
-> INNER JOIN customer c ON r.customer_id=c.customer_id WHERE last_name LIKE 'S%' G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: c
type: range
possible_keys: PRIMARY,idx_last_name
key: idx_last_name
key_len: 137
ref: NULL
rows: 54
Extra: Using where
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: r
type: ref
possible_keys: idx_fk_customer_id
key: idx_fk_customer_id
key_len: 2
ref: sakila.c.customer_id
rows: 13
Extra:
优化器为标准连接给
了一个更好的执行计
划,并且有相同的查
询结果。这一方法值
得推荐-把相关子查询
重写为标准连接查询
www.2345.com
27. 下讲引题
mysql> EXPLAIN SELECT r.staff_id, COUNT(*)
-> FROM rental r GROUP BY r.staff_id G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: r
type: index
possible_keys: NULL
key: idx_fk_staff_id
key_len: 1
ref: NULL
rows: 15646
Extra: Using index
mysql> EXPLAIN SELECT r.return_date, COUNT(*)
-> FROM rental r GROUP BY r.return_date G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: r
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 15646
Extra: Using temporary; Using filesort
我们注意到
Extra:的信息
完全不一样,这
是为什么呢? …
www.2345.com