mysql> show engines;
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine | Support | Comment | Transactions | XA | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| ARCHIVE | YES | Archive storage engine | NO | NO | NO |
| BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO |
| MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO |
| FEDERATED | NO | Federated MySQL storage engine | NULL | NULL | NULL |
| MyISAM | YES | MyISAM storage engine | NO | NO | NO |
| PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO |
| InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES |
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO |
| CSV | YES | CSV storage engine | NO | NO | NO |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
show create table [student]
:查看表结构,其中表使用的数据库引擎和字符集等可以在配置文件中修改。windows下的配置文件为安装目录下的my.ini
,linux则在/etc/mysql/my.cnf
表相关文件目录:/var/lib/mysql
*.frm
,*.MYD
,*.MYI
,分别表示表结构、表数据、表索引*.frm
,*.ibd
,分别表示表结构、表数据和表索引,数据和索引放在一个文件中面试问题:为什么使用InnoDB存储引擎的表会自动生成主键,而使用MyISAM存储引擎的表不会自动生成主键?
因为MyISAM的数据和索引是单独存放的,手动加上主键会生成主键索引存放在*.MYI
,没有主键的话*.MYI
里就不用存放索引。而InnoDB会默认生成一个整型类型的索引,因为Innodb的数据和索引放在一个文件中,数据就是放在索引树上的,没有索引,数据也没有地方存放。
种类 | 锁机制 | B树索引 | 哈希索引 | 外键 | 事务 | 索引缓存 | 数据缓存 |
---|---|---|---|---|---|---|---|
MyISAM | 表锁 | 支持 | 不支持 | 不支持 | 不支持 | 支持 | 不支持 |
InnoDB | 行锁 | 支持 | 不支持 | 支持 | 支持 | 支持 | 支持 |
Memory | 表锁 | 支持 | 支持 | 不支持 | 不支持 | 支持 | 支持 |
当表中的数据量达到上百万的时候,SQL查询花费的时间会很长,需要使用索引加速SQL查询
由于 索引也是需要存储成索引文件的,因此使用索引也会涉及磁盘I/O操作。如果索引过多,使用不当,SQL查询时会造成大量无用的磁盘I/O操作,降低查询效率。
此外,我们 改动数据以后,不仅是数据文件需要做修改,索引文件也需要修改,索引过多,修改的索引也会更多,所以索引并不是越多越好。
索引是创建在表上的,是对数据库表中一列或多列的值进行排序的一种结果,其核心就是提高查询的速度
创建表的时候指定索引字段:
CREATE TABLE student(id INT,
name VARCHAR(50),
sex ENUM('male', 'female'),
INDEX(id));
在已经创建的表上添加索引:
CREATE [UNIQUE] INDEX 索引名 ON 表名(属性名(length) [ASC | DESC]);
length表示用该字段的前length个字符建索引,如果字段很长,索引文件就会很大,搜索也慢,如果前length个字符可以区分该字段,就可以使用前length个字符建立索引
删除索引:
DROP INDEX 索引名 ON 表名;
此时表结构如下:
show create table student \G
使用具有主键索引的id进行过滤查找:
explain select * from student where uid=3;
从索引树上直接获取数据,并没有整表扫描,对于当前uid创建了索引,无论查询uid是多少的信息,都能在索引树上取得,直接命中
使用没有索引的name属性扫描
explain select * from student where name="zhangsan";
就算zhangsan排在第一个,也需要整表扫描,不扫描完,不知道其他行有没有zhangsan
给name添加索引
create index nameidx on student(name);
用name索引加速搜索
然而添加索引后,不一定就能使用到索引,因为MySQL server有优化,它会先进行分析,如果发现使用索引需要扫描的数据基本上是所有数据的大概百分之七八十左右,其实是不会使用索引的,因为如果花费差不多,读索引文件花费磁盘I/O,还要扫描索引树,还不如直接整张表搜索取数据
对于相同的操作,若中间没有更新数据(insert/delete/update),则第一次花费时间长,第二次花费时间短,这是因为存储引擎对索引和数据进行了缓存。 第一次查询后的结果会放在数据缓存或者索引缓存里,第二次就不用花费磁盘I/O从磁盘读取索引了。
查看表结构后发现,password属性是varchar
,然而查询的时候使用的是int
,这就涉及到了类型转换,所以不会使用索引。此外,如果用到了mysql的聚集函数或表达式计算,也不会用到索引
drop index pwdidx on t_user;
阅读量:834
点赞量:0
收藏量:0