Mysql中使用索引的典型场景
来源:互联网 发布:idea 测试java代码 编辑:程序博客网 时间:2024/05/17 03:47
(1)匹配全值,对索引中的所有列都指定具体值,也就是对索引中的所有列都有等值匹配的条件。
mysql> show create table rental\G;
*************************** 1. row ***************************
Table: rental
Create Table: CREATE TABLE `rental` (
`rental_id` int(11) NOT NULL AUTO_INCREMENT,
`rental_date` datetime NOT NULL,
`inventory_id` mediumint(8) unsigned NOT NULL,
`customer_id` smallint(5) unsigned NOT NULL,
`return_date` datetime DEFAULT NULL,
`staff_id` tinyint(3) unsigned NOT NULL,
`last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`rental_id`),
KEY `idx_fk_inventory_id` (`inventory_id`),
KEY `idx_fk_customer_id` (`customer_id`),
KEY `idx_fk_staff_id` (`staff_id`),
KEY `idx_rental_date` (`rental_date`,`inventory_id`,`customer_id`),
CONSTRAINT `fk_rental_customer` FOREIGN KEY (`customer_id`) REFERENCES `customer` (`customer_id`) ON UPDATE CASCADE,
CONSTRAINT `fk_rental_inventory` FOREIGN KEY (`inventory_id`) REFERENCES `inventory` (`inventory_id`) ON UPDATE CASCADE,
CONSTRAINT `fk_rental_staff` FOREIGN KEY (`staff_id`) REFERENCES `staff` (`staff_id`) ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=16050 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
上面是表结构,我们用explain分析下面的语句
mysql> explain select * from rental where rental_date = '2005-05-25 17:22:10' and inventory_id = 373 and customer_id = 343\G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: rental
type: ref
possible_keys: idx_fk_inventory_id,idx_fk_customer_id,idx_rental_date
key: idx_rental_date
key_len: 10
ref: const,const,const
rows: 1
Extra: NULL
1 row in set (0.01 sec)
从上面我们可以看到,利用了索引idx_rental_date,因为idx_rental_date中的所有列,都有指定的值。
(2)匹配值的范围查询,对索引的值能够进行范围查找。
mysql> explain select * from rental where customer_id>373 and customer_id<400\G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: rental
type: range
possible_keys: idx_fk_customer_id
key: idx_fk_customer_id
key_len: 2
ref: NULL
rows: 682
Extra: Using index condition
1 row in set (0.01 sec)
从上面的分析中我们可以看出,对索引idx_fk_customer_id而言,给定了查找的范围,从而利用索引来加速访问。Using index condition 表示mysql使用到了ICP来进行进一步的优化,在检索的时候,把条件customer_id的过滤操作下推到存储引擎来完成,这样能够降低不必要的IO访问(注意,这个是mysql5.6的新特性,如果是mysql5.5或者之前的版本,会显示Using where)
(3)匹配最前缀,仅仅使用索引中的最左边列进行查找。例如col1+col2+col3字段上的联合索引能够被包含col1,(col1+col2),(col1+col2+col3)的等值查询利用到,可是不能被col2,(col2+col3)的等值查询利用到。
mysql> show create table payment\G;
*************************** 1. row ***************************
Table: payment
Create Table: CREATE TABLE `payment` (
`payment_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
`customer_id` smallint(5) unsigned NOT NULL,
`staff_id` tinyint(3) unsigned NOT NULL,
`rental_id` int(11) DEFAULT NULL,
`amount` decimal(5,2) NOT NULL,
`payment_date` datetime NOT NULL,
`last_update` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`payment_id`),
KEY `idx_fk_staff_id` (`staff_id`),
KEY `idx_fk_customer_id` (`customer_id`),
KEY `fk_payment_rental` (`rental_id`),
KEY `idx_payment_date` (`payment_date`,`amount`,`last_update`),
CONSTRAINT `fk_payment_customer` FOREIGN KEY (`customer_id`) REFERENCES `customer` (`customer_id`) ON UPDATE CASCADE,
CONSTRAINT `fk_payment_rental` FOREIGN KEY (`rental_id`) REFERENCES `rental` (`rental_id`) ON DELETE SET NULL ON UPDATE CASCADE,
CONSTRAINT `fk_payment_staff` FOREIGN KEY (`staff_id`) REFERENCES `staff` (`staff_id`) ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=16050 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
我们分析下面的语句:
mysql> explain select * from payment where payment_date = '2006-02-14 15:16:03' and last_update = '2006-02-15 22:12:32'\G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: payment
type: ref
possible_keys: idx_payment_date
key: idx_payment_date
key_len: 5
ref: const
rows: 182
Extra: Using index condition
1 row in set (0.00 sec)
上面我们可以看到,利用了索引idx_payment_date,所以我们可以知道(col1+col3)的模式,也可以利用到索引,但是(col2+col3)的模式,是不会利用到索引的,我们看下面的语句:
mysql> explain select * from payment where amount = 3.98 and last_update = '2006-02-15 22:12:32'\G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: payment
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 16086
Extra: Using where
1 row in set (0.00 sec)
(4)仅仅对索引列进行查找,当查询的列,都在索引字段中的时候,查询的效率更高。
mysql> explain select last_update from payment where payment_date = '2006-02-14 15:16:03' and amount = 3.98\G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: payment
type: ref
possible_keys: idx_payment_date
key: idx_payment_date
key_len: 8
ref: const,const
rows: 8
Extra: Using index
1 row in set (0.00 sec)
上面的例子,就是典型的利用到了索引来查询(Using index)
(5)匹配列前缀,仅仅使用索引中的第一列,并且只包含索引第一列的开头一部分进行查找。
mysql> show create table film_text\G;
*************************** 1. row ***************************
Table: film_text
Create Table: CREATE TABLE `film_text` (
`film_id` smallint(6) NOT NULL,
`title` varchar(255) NOT NULL,
`description` text,
PRIMARY KEY (`film_id`),
KEY `idx_title_desc_part` (`title`(10),`description`(20)),
FULLTEXT KEY `idx_title_description` (`title`,`description`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
分析下面的语句:
mysql> explain select title from film_text where title like 'AFRIC%'\G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: film_text
type: range
possible_keys: idx_title_desc_part,idx_title_description
key: idx_title_desc_part
key_len: 32
ref: NULL
rows: 1
Extra: Using where
1 row in set (0.00 sec)
从上面我们可以看出,利用到了idx_title_desc_part,其实,Using where表示优化器需要通过索引回表来查询数据。
(6)能够使用索引匹配部分精确而其他部分进行范围匹配,例如,需要查询出租日期rental_date为指定日期客户编号customer_id为指定范围的库存。
mysql> explain select inventory_id from rental where rental_date = '2006-02-14 15:15:03' and customer_id>300 and customer_id<400\G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: rental
type: ref
possible_keys: idx_fk_customer_id,idx_rental_date
key: idx_rental_date
key_len: 5
ref: const
rows: 1
Extra: Using where; Using index
1 row in set (0.00 sec)
从上面我们可以看出,使用了索引idx_rental_date
(7)如果列名是索引,使用column_name is null 就会使用索引.
mysql> explain select * from payment where rental_id is null\G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: payment
type: ref
possible_keys: fk_payment_rental
key: fk_payment_rental
key_len: 5
ref: const
rows: 5
Extra: Using index condition
1 row in set (0.00 sec)
(8)Index Condition PushDown(ICP),这个特性,只针对mysql5.6之后的版本
mysql> explain select * from rental where rental_date = '2006-02-14 15:16:03' and customer_id >300 and customer_id <400\G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: rental
type: ref
possible_keys: idx_fk_customer_id,idx_rental_date
key: idx_rental_date
key_len: 5
ref: const
rows: 182
Extra: Using index condition
1 row in set (0.00 sec)
- Mysql中使用索引的典型场景
- 每天进步一点点——MySQL中能够使用索引的典型场景
- MySQL MHA 典型使用场景
- Mysql中存在索引但是不能使用索引的典型情况
- Mysql使用索引可能失效的场景
- Mysql的索引以及使用索引可能失效的场景
- spring schedule的几个典型使用场景
- RabbitMQ的几种典型使用场景
- RabbitMQ的几种典型使用场景
- RabbitMQ的几种典型使用场景
- RabbitMQ的几种典型使用场景
- RabbitMQ的几种典型使用场景
- RabbitMQ的几种典型使用场景
- RabbitMQ的几种典型使用场景
- RabbitMQ的几种典型使用场景
- RabbitMQ的几种典型使用场景
- RabbitMQ的几种典型使用场景
- RabbitMQ的几种典型使用场景
- 09python生成文件脚本
- pycharm ImportError: No module named caffe
- 灏瀚科技his系统运维过程中遇到的问题---1
- synchronized和lock的区别
- 用nim写一个简单的windows程序
- Mysql中使用索引的典型场景
- s:select 默认值问题
- 黑马程序员--反射
- ORA-01033: ORACLE initialization or shutdown in progress数据文件损坏错误解决方案
- Maven实践(二):Spring与classpath*加载配置文件
- wampserver出现You don’t have permission to access/on this
- KVC和KVO操作
- ActionBar的使用方式+Selector
- 一看就懂的iOS触摸事件