mysql 命令与高级用法

目录

 

1.  mac mysql安装

2.   命令

mysql出现access denied for user 'root@localhost'(using password: YES)

3.  MySQL删除数据Delete与Truncate语句使用比较

4. 常用sql

数据库进阶

索引使用场景


1.  mac mysql安装

压缩包安装(社区版): 

http://blog.sina.com.cn/s/blog_9ea3a4b70101ihl3.html

 

注: 安装包的形式 或 brew 安装mysql后,一直登录报错(不知道什么原因)

 

注: 建表报错:MySQL:Error : Tablespace for table `database`.`temp` exists. Please DISCARD the tablespace before IMPORT.

解决办法

http://www.shaoqun.com/a/101373.aspx

 

mysql 环境变量配置:

 

vi .bash_profile 

export MYSQL_HOME=../mysql-5.7.13-osx10.11-x86_64/bin

PATH=$PATH:$MYSQL_HOME

source ~/.bash_profile--让以上所做的配置生效

 

 

 

2.   命令

 
查看端口:
status;
show global variables like  'port';
 
执行sql脚本,可以有2种方法:
  第一种方法:
 在命令行下(未连接数据库),输入 mysql -h localhost -u root -p123456 < F:\hello world\niuzi.sql (注意路径不用加引号的!!) 回车即可.
  第二种方法:
 在命令行下(已连接数据库,此时的提示符为 mysql> ),输入 source F:\hello world\niuzi.sql (注意路径不用加引号的) 或者 \. F:\hello world\niuzi.sql (注意路径不用加引号的) 回车即可
 
 

 

命令作用
show databases;所有数据库
use database;

show tables;
所有表
DROP DATABASE IF EXISTS sampledb;
CREATE DATABASE sampledb DEFAULT CHARACTER SET utf8;
USE sampledb;


##创建用户表
CREATE TABLE t_user (
   user_id   INT AUTO_INCREMENT PRIMARY KEY,
   user_name VARCHAR(30),
   credits INT,
   password  VARCHAR(32),
   last_visit datetime,
   last_ip  VARCHAR(23)
)ENGINE=InnoDB; 


##创建用户登录日志表
CREATE TABLE t_login_log (
   login_log_id  INT AUTO_INCREMENT PRIMARY KEY,
   user_id   INT,
   ip  VARCHAR(23),
   login_datetime datetime
)ENGINE=InnoDB; 


##插入初始化数据
INSERT INTO t_user (user_name,password) 
             VALUES('admin','123456');
COMMIT;
新建库 
新建表

describe t_login_log;

 

或者

 

desc log;

表结构
use 库名; 
create table 表名 (字段设定列表); 
 
drop database 库名; 
drop table 表名;

delete from 表名;
 
mysql -h110.110.110.110 -u root -p 123;

exit

或者:

cd /usr/local/mysql/bin

启动mysql服务器:sudo ./mysqld_safe --defaults-file=/etc/my.cnf --user=root &

sudo ./mysql -u root -p

输入密码:123

 

________________________

win7  mysql 

net start mysql  启动

net stop mysql 停止

 

win7 mysql登录出现:

mysql出现access denied for user 'root@localhost'(using password: YES)

解决:
1.关闭正在运行的MySQL(net stop mysql)。
  2.打开DOS窗口,转到mysql\bin目录。
  3.输入mysqld --skip-grant-tables回车。如果没有出现提示信息,那就对了。
  4.再开一个DOS窗口(因为刚才那个DOS窗口已经不能动了),转到mysql\bin目录。
  5.输入mysql回车
 
 
 

 

登录

退出
刚安装好MYSQL,超级用户root是没有密码的,故直接回车即可进入到MYSQL中了

再将root的密码改为123:
 

sudo ./mysqladmin -u root -p  password 123;

修改密码
select version(); 

select now(); //显示当前时间

select ((4 * 4) / 10 ) + 25;//当计算器
mysql版本
 insert into MyClass values(1,'Tom',96.45),(2,'Joan',82.99), (2,'Wang', 96.59);

update MyClass set name='Mary' where id=1;

alter table MyClass add passtest int(4) default '0';
 
select * from MyClass order by id limit 0,2;查看表 MyClass 中前2行数据
rename table MyClass to YouClass;修改表名
1.导出整个数据库
导出文件默认是存在mysql\bin目录下
    mysqldump -u 用户名 -p 数据库名 > 导出的文件名
    mysqldump -u user_name -p123456 database_name > outfile_name.sql

2.导出一个表
    mysqldump -u 用户名 -p 数据库名 表名> 导出的文件名
    mysqldump -u user_name -p database_name table_name > outfile_name.sql

3.导出一个数据库结构
    mysqldump -u user_name -p -d –add-drop-table database_name > outfile_name.sql
    -d 没有数据 –add-drop-table 在每个create语句之前增加一个drop table
备份数据库

 

 

3.  MySQL删除数据Delete与Truncate语句使用比较

空mysqll表内容常见的有两种方法:一种delete,一种是truncate 。 不带where参数的delete语句可以删除mysql表中所有内容,使用truncate table也可以清空mysql表中所有内容。

1)效率上truncate比delete快,但truncate删除后不记录mysql日志,不可以恢复数据。 
2)delete的效果有点像将mysql表中所有记录一条一条删除到删完

3)truncate相当于保留mysql表的结构,重新创建了这个表,所有的状态都相当于新表。

 

 

 

 

 

4. 常用sql

表:
 
1、学生s、课程c、选课sc,创建表,插入数据 
DROP TABLE IF EXISTS `c`;  
  
CREATE TABLE `c` (  
  `cid` char(10) NOT NULL,  
  `cname` char(20) DEFAULT NULL,  
  PRIMARY KEY (`cid`)  
) ENGINE=InnoDB DEFAULT CHARSET=gb2312;  
 
DROP TABLE IF EXISTS `s`;  
  
CREATE TABLE `s` (  
  `sid` char(10) NOT NULL,  
  `sname` char(20) DEFAULT NULL,  
  PRIMARY KEY (`sid`)  
) ENGINE=InnoDB DEFAULT CHARSET=gb2312;  
DROP TABLE IF EXISTS `sc`;  
  
CREATE TABLE `sc` (  
  `sid` char(10) NOT NULL,  
  `cid` char(10) NOT NULL,  
  KEY `sid` (`sid`),  
  KEY `cid` (`cid`),  
  CONSTRAINT `sc_ibfk_1` FOREIGN KEY (`sid`) REFERENCES `s` (`sid`),  
  CONSTRAINT `sc_ibfk_2` FOREIGN KEY (`cid`) REFERENCES `c` (`cid`)  
) ENGINE=InnoDB DEFAULT CHARSET=gb2312;  
一、查询选择所有课程的学生 
Sql代码  
#查询选择了所有课程的学生(一)  
SELECT s.sid,s.sname   
FROM s,   
     (SELECT sc.sid FROM sc GROUP BY sid HAVING COUNT(*)=(SELECT COUNT(*) FROM c))   
      AS tmp  
WHERE s.sid=tmp.sid;  
  
#查询选择了所有课程的学生(二)  
SELECT s.`sid`,s.`sname` FROM s WHERE s.`sid` IN (  
SELECT sc.`cid` FROM sc GROUP BY sc.sid HAVING COUNT(cid) = (SELECT COUNT(*) FROM c)  
);  
 
二 、查询选择3门以上课程的学生 
Sql代码  
#查询选择了超过3门以上课程的学生(一)  
SELECT s.sid,s.sname   
FROM s,   
     (SELECT sc.sid FROM sc GROUP BY sid HAVING COUNT(*)>3)   
      AS tmp  
WHERE s.sid=tmp.sid;  
#查询选择了超过3门以上课程的学生(二)  
SELECT s.`sid`,s.`sname` FROM s WHERE s.`sid` IN (  
SELECT sc.`sid` FROM sc GROUP BY sc.sid HAVING COUNT(cid) >3  
);  
更多:
2. 学生  成绩
小王  65
小张  80
小李  72
小赵  93

排名在第3名的成绩是72,如何用1条语句把它找出来?
 
CREATE TABLE `t2` (                     
          `s1` char(30) NOT NULL,               
          `s2` decimal(6,2) default NULL,       
          PRIMARY KEY  (`s1`),                  
          KEY `s2` (`s2`)                     
        )engine=innodb default charset=utf8 ;
        
insert into t2 values
('小王' ,65),
('小张'  ,80),
('小李'  ,72),
('小赵'  ,93);
 
方法一: 
select * from t2 where s2 = (select min(s2) from (select s2 from t2 order by s2 desc limit 3) tmp);
 
方法二:

select s2 from t2 order by s2 desc limit 2,1;

 

或者:

 select s2 from t2 order by s2 desc limit 1 offset 2;

limit后面跟的是1条数据,offset后面是从第3条开始读取
 

 

注: limit m,n
select * from table limit m,n
其中m是指记录开始的index,从0开始,表示第一条记录
n是指从第m+1条开始,取n条。
select * from tablename limit 2,4
即取出第3条至第6条,4条记录从0开始,表示第一条记录
n是指从第m+1条开始,取n条。
select * from tablename limit 2,4
即取出第3条至第6条,4条记录

select * from tablename <条件语句> limit 100,-1

从第100条后开始-最后一条的记录

mysql低版本不支持limit offset

limit offset 在mysql 4.0以上的版本中都可以正常运行,在旧版本的mysql 3.23中无效

limit m offset n 等价于 limit m,n

类似,取出第1名:

select s2 from t2 order by s2 desc limit 0,1;

1、offset比较小的时候。 

select * from yanxue8_visit limit 10,10 

多次运行,时间保持在0.0004-0.0005之间 

Select * From yanxue8_visit Where vid >=( 

Select vid From yanxue8_visit Order By vid limit 10,1 

) limit 10 

多次运行,时间保持在0.0005-0.0006之间,主要是0.0006 

结论:偏移offset较小的时候,直接使用limit较优。这个显然是子查询的原因。 

2、offset大的时候。 

select * from yanxue8_visit limit 10000,10 

多次运行,时间保持在0.0187左右 

Select * From yanxue8_visit Where vid >=( 

Select vid From yanxue8_visit Order By vid limit 10000,1 

) limit 10 

多次运行,时间保持在0.0061左右,只有前者的1/3。可以预计offset越大,后者越优。

当偏移1000以上使用子查询法可以有效的提高性能:
优化前:
select * from Member limit 100000, 100;
 
子查询优化后:
select * from Member where MemberID >= (select MemberID from Member limit 100000,1) limit 100;
 
 
 

数据库进阶

1.  char(8)和varchar(8) 区别
1)
char是固定长度的,而varchar会根据具体的长度来使用存储空间。比如char(255)和varchar(255),在存储字符串"hello world"的时候,char会用一块255的空间放那个11个字符,而varchar就不会用255个,他先计算长度后只用11个再加上计算的到字符串长度信息,一般1-2个byte来,这样varchar在存储不确定长度的时候会大大减少存储空间.
总之:  char(M)类型的数据列里,每个值都占用M个字节,如果某个长度小于M,MySQL就会在它的右边用空格字符补足.(在检索操作中那些填补出来的空格字符将被去掉)在varchar(M)类型的数据列里,每个值只占用刚好够用的字节再加上一个用来记录其长度的字节(即总长度为L+1字节)
2) char适用场景
一,存储很短的信息,比如门牌号码101,201……这样很短的信息应该用char,因为varchar还要占个byte用于存储信息长度
二,固定长度的
三,十分频繁改变的column。因为varchar每次存储都要有额外的计算,得到长度等工作,如果一个非常频繁改变的,那就要有很多的精力用于计算,而这些对于char来说是不需要的。
2. sql  优化
 
1) SQL本身规范;
  • 尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引;
  • 尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:
select id from t where num is null

最好不要给数据库留NULL,尽可能的使用 NOT NULL填充数据库.

备注、描述、评论之类的可以设置为 NULL,其他的,最好不要使用NULL

  • 应尽量避免在 where 子句中使用 != 或 <> 操作符,否则将引擎放弃使用索引而进行全表扫描。
  • 应尽量避免在 where 子句中使用 or 来连接条件,如果一个字段有索引,一个字段没有索引,将导致引擎放弃使用索引而进行全表扫描(使用union all)
  •  

in 和 not in 也要慎用,否则会导致全表扫描,如:

select id from t where num in(1,2,3)

对于连续的数值,能用 between 就不要用 in 了

select id from t where num between 1 and 3
 
  • 下面的查询也将导致全表扫描:

    select id from t where name like ‘%abc%’

    若要提高效率,可以考虑全文检索。

  • 不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引
  • 索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有 必要。
  • .尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连 接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。
  • 尽可能的使用 varchar/nvarchar 代替 char/nchar ,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。
  • 尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理
  • 拆分大的 DELETE 或INSERT 语句,批量提交SQL语句

    如果你需要在一个在线的网站上去执行一个大的 DELETE 或 INSERT 查询,你需要非常小心,要避免你的操作让你的整个网站停止相应。因为这两个操作是会锁表的,表一锁住了,别的操作都进不来了。

 
2)  EXPLAIN的使用方法

mysql> explain select * from commonfig where id=6;

+----+-------------+-----------+-------+---------------+---------+---------+-------+------+-------+

| id | select_type | table     | type  | possible_keys | key     | key_len | ref   | rows | Extra |

+----+-------------+-----------+-------+---------------+---------+---------+-------+------+-------+

|  1 | SIMPLE      | commonfig | const | PRIMARY       | PRIMARY | 4       | const |    1 | NULL  |

+----+-------------+-----------+-------+---------------+---------+---------+-------+------+-------+

1 row in set (0.01 sec)

EXPLAIN列的解释:

select_type:将select查询分为简单(simple)和复杂两种类型。复杂类型又分为子查询(subquery)和from列表中包含子查询(drived)。

table:显示这一行的数据是关于哪张表的

type:这是重要的列,显示连接使用了何种类型。从最好到最差的连接类型为const、eq_reg、ref、range、 indexhe和ALL。

possible_keys:显示可能应用在这张表中的索引。如果为空,没有可能的索引。可以为相关的域从WHERE语句中选择一个合适的语句

key: 实际使用的索引。如果为NULL,则没有使用索引。很少的情况下,MYSQL会选择优化不足的索引。这种情况下,可以在SELECT语句中使用USE INDEX(indexname)来强制使用一个索引或者用IGNORE INDEX(indexname)来强制MYSQL忽略索引

key_len:使用的索引的长度。在不损失精确性的情况下,长度越短越好

ref:显示索引的哪一列被使用了,如果可能的话,是一个常数

rows:MYSQL认为必须检查的用来返回请求数据的行数

Extra:关于MYSQL如何解析查询的额外信息。坏的例子是Using temporary和Using filesort,意思MYSQL根本不能使用索引,结果是检索会很慢

  • type的解释
System,const,eq_ref,ref,range,index,all
all : 即全表扫描
index : 按索引次序扫描,先读索引,再读实际的行,结果还是全表扫描,主要优点是避免了排序。因为索引是排好的。
range:以范围的形式扫描。
explain select * from a where a_id > 1\G
ref:非唯一索引访问(只有普通索引)
create table a(a_id int not null, key(a_id));
insert into a values(1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
mysql> explain select * from a where a_id=1\G
eq_ref:使用唯一索引查找(主键或唯一索引)
const:常量查询
在整个查询过程中这个表最多只会有一条匹配的行,比如主键 id=1 就肯定只有一行,只需读取一次表数据便能取得所需的结果,且表数据在分解执行计划时读取。
当结果不是一条时,就会变成index或range等其他类型
system:系统查询

type显示的是访问类型,是较为重要的一个指标,结果值从好到坏依次是:

system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL

一般来说,得保证查询至少达到range级别,最好能达到ref

  • Extra

mysql> explain select distinct config_key from commonfig order by id;

+----+-------------+-----------+------+---------------+------+---------+------+------+---------------------------------+

| id | select_type | table     | type | possible_keys | key  | key_len | ref  | rows | Extra                           |

+----+-------------+-----------+------+---------------+------+---------+------+------+---------------------------------+

|  1 | SIMPLE      | commonfig | ALL  | NULL          | NULL | NULL    | NULL |   11 | Using temporary; Using filesort |

+----+-------------+-----------+------+---------------+------+---------+------+------+---------------------------------+

1 row in set (0.00 sec)

Using index
此查询使用了覆盖索引(Covering Index),即通过索引就能返回结果,无需访问表。
若没显示"Using index"表示读取了表数据。
Using where
表示 MySQL 服务器从存储引擎收到行后再进行“后过滤”(Post-filter)。所谓“后过滤”,就是先读取整行数据,再检查此行是否符合 where 句的条件,符合就留下,不符合便丢弃。因为检查是在读取行后才进行的,所以称为“后过滤”。
Using temporary
使用到临时表
建表及插入数据:
create table a(a_id int, b_id int);
insert into a values(1,1),(1,1),(2,1),(2,2),(3,1);
mysql> explain select distinct a_id from a\G
        Extra: Using temporary
MySQL 使用临时表来实现 distinct 操作。
 
Using filesort
若查询所需的排序与使用的索引的排序一致,因为索引是已排序的,因此按索引的顺序读取结果返回,否则,在取得结果后,还需要按查询所需的顺序对结果进行排序,这时就会出现 Using filesort 。
select * from a order by id;
对于没有索引的列进行order by 就会出现filesort
3)

使用慢查询分析

在my.ini中:

long_query_time=1

log-slow-queries=xxx\mysqlslow.log

把超过1秒的记录在慢查询日志中

可以用mysqlsla来分析之。也可以在mysqlreport中,有如

DMS分别分析了select ,update,insert,delete,replace等所占的百份比

4) 增删查索引
 
  • 查看索引
mysql> show index from tblname;
mysql> show keys from tblname;
mysql> show keys from mock;
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| mock  |          0 | PRIMARY  |            1 | url_id      | A         |          13 |     NULL | NULL   |      | BTREE      |         |               |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
1 row in set (0.01 sec)

mysql> show index  from mock;
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| mock  |          0 | PRIMARY  |            1 | url_id      | A         |          13 |     NULL | NULL   |      | BTREE      |         |               |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
1 row in set (0.00 sec)
  • 删除索引
DROP INDEX index_name ON talbe_name
ALTER TABLE table_name DROP INDEX index_name
ALTER TABLE table_name DROP PRIMARY KEY
 
ps: 其中,前两条语句是等价的,删除掉table_name中的索引index_name
  • 添加索引

ALTER TABLE用来创建普通索引、UNIQUE索引或PRIMARY KEY索引。

?
1
2
3
ALTER TABLE table_name ADD INDEX index_name (column_list)
ALTER TABLE table_name ADD UNIQUE (column_list)
ALTER TABLE table_name ADD PRIMARY KEY (column_list)

CREATE INDEX可对表增加普通索引或UNIQUE索引。

?
1
2
CREATE INDEX index_name ON table_name (column_list)
CREATE UNIQUE INDEX index_name ON table_name (column_list)

table_name、index_name和column_list具有与ALTER TABLE语句中相同的含义,索引名不可选。另外,不能用CREATE INDEX语句创建PRIMARY KEY索引。

1)MySQL就普遍使用B+Tree实现其索引结构 :

与B-Tree相比,B+Tree有以下不同点:

  1. 每个结点的指针上限为2d而不是2d+1。
  2. 内结点不存储data,只存储key;叶子结点不存储指针。
2)带有顺序访问指针的B+Tree

一般在数据库系统或文件系统中使用的B+Tree结构都在经典B+Tree的基础上进行了优化,增加了顺序访问指针。

3)MySQL索引实现
在MySQL中,索引属于存储引擎级别的概念,不同存储引擎对索引的实现方式是不同的,本文主要讨论MyISAM和InnoDB两个存储引擎(MySQL数据库MyISAM和InnoDB存储引擎的比较)的索引实现方式。

MyISAM引擎使用B+Tree作为索引结构,叶结点的data域存放的是数据记录的地址;

虽然InnoDB也使用B+Tree作为索引结构,但具体实现方式却与MyISAM截然不同:

 

  • 第一个重大区别是InnoDB的数据文件本身就是索引文件
  • 第二个与MyISAM索引的不同是InnoDB的辅助索引data域存储相应记录主键的值而不是地址

索引使用场景

索引的类型

在MySQL中,索引分为两大类:聚簇索引和非聚簇索引。聚簇索引是按照数据存放的物理位置为顺序的,而非聚簇索引则不同;聚簇索引能够提高多行检索的速度,而非聚簇索引则对单行的检索速度很快。

在这两大类的索引类型下,还可以将索引分成四个小类:

1,普通索引:最基本的索引,没有任何限制,是我们大多数情况下使用到的索引。

2,唯一索引:与普通索引类型,不同的是唯一索引的列值必须唯一,但允许为空值。

3,全文索引:全文索引(FULLTEXT)仅可以适用于MyISAM引擎的数据表;作用于CHAR、VARCHAR、TEXT数据类型的列。

4,组合索引:将几个列作为一条索引进行检索,使用最左匹配原则。

索引设计原则
1, 用整型设计索引
2,尽量选择区分度高的列作为索引
3, 多列索引:
ALTER TABLE people ADD INDEX lname_fname_age (lame,fname,age);
为了提高搜索效率,我们需要考虑运用多列索引,由于索引文件以B-Tree格式保存,所以我们不用扫描任何记录,即可得到最终结果。

注:在mysql中执行查询时,只能使用一个索引,如果我们在lname,fname,age上分别建索引,执行查询时,只能使用一个索引,mysql会选择一个最严格(获得结果集记录数最少)的索引。

3.最左前缀:顾名思义,就是最左优先,上例中我们创建了lname_fname_age多列索引,相当于创建了(lname)单列索引,(lname,fname)组合索引以及(lname,fname,age)组合索引。

注:在创建多列索引时,要根据业务需求,where子句中使用最频繁的一列放在最左边

 

例如:
表结构,有三个字段,分别是id,name,cid
CREATE TABLE `student` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, `cid` int(11) DEFAULT NULL, PRIMARY KEY (`id`), KEY `name_cid_INX` (`name`,`cid`),) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8
索引方面:id是主键,(name,cid)是一个多列索引。
EXPLAIN SELECT * FROM student WHERE cid=1;
EXPLAIN SELECT * FROM student WHERE cid=1 AND name='小红';
都会用到索引的原因:
1)
index:这种类型表示是mysql会对整个该索引进行扫描。要想用到这种类型的索引,对这个索引并无特别要求,只要是索引,或者某个复合索引的一部分,mysql都可能会采用index类型的方式扫描。但是呢,缺点是效率不高,mysql会从索引中的第一个数据一个个的查找到最后一个数据,直到找到符合判断条件的某个索引。
 
所以:对于你的第一条语句:
EXPLAIN SELECT * FROM student WHERE cid=1;
判断条件是cid=1,而cid是(name,cid)复合索引的一部分,没有问题,可以进行index类型的索引扫描方式。explain显示结果使用到了索引,是index类型的方式。
2) 你可能会问 :我建的索引是(name,cid)。而我查询的语句是cid=1 AND name='小红'; 我是先查询cid,再查询name的,不是先从最左面查的呀
mysql查询优化器会判断纠正这条sql语句该以什么样的顺序执行效率最高,最后才生成真正的执行计划。所以,当然是我们能尽量的利用到索引时的查询顺序效率最高咯,所以mysql查询优化器会最终以这种顺序进行查询执行。
 
 
 
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

多则惑少则明

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值