MYSQL视图 索引 分页查询 SQL语句常见面试题

MYSQL索引类型

按逻辑来分:

1.主键索引
是一种特殊的唯一索引,不允许有空值

创建、删除语句:
alter table [table_name] add primary key (column_name)
create table [table_name](
id int not null,
primary key (id)
)
alter table drop primary key

2.普通索引(单例索引)
对表中一个列进行索引

create index index_name on [table_name] (column_name)
alter table [table_name] add index [index_name] (column_name)
alter table drop index [index_name]

3.复合索引(多列索引)
对表中多个列进行索引

alter table [table_name] add index [index_name]
(column_name1,column_name2)

4.全文索引
可以在char、varchar或text类型的列上创建。

alter table [table_name] add fulltext (column_name)

5.唯一索引
当前列中的数据具有唯一性

alter table [table_name] add unique [index_name] (column_name)

在实际操作过程中,应该选取表中哪些字段作为索引?

1.选择唯一性索引
2.为经常需要排序、分组和联合操作的字段建立索引
3.为常作为查询条件的字段建立索引
4.限制索引的数目
5.尽量使用数据量少的索引
6.尽量使用前缀来索引
7.删除不再使用或者很少使用的索引

视图作用

测试表:user有id,name,age字段
测试表:product有id,name,price字段
测试表:user_product有id,uid,pid字段

提高了重用性,就像一个函数

比如我要获取一张用户表和一张商品表的中用户购买了那个商品的信息
select * from user as u , products as p, user_product as c where u.id=c.u_id and p.id=c.p_id;

创建视图
create view u_p_userage as select u.id as uid,u.name as uname,p.id as pid,p.name as pname from user as u , products as p, user_product as c where u.id=c.u_id and p.id=c.p_id

利用视图进行操作
对数据库重构,却不影响程序的运行

假设我对用户表进行拆分,比如变成 了 id和age为一张表 id和name为一张表 那么这个时候 再去select *from user就不管用了。

那么我可以创建视图 create view user as select....去重新写sql语句这样就能保证不改变脚本程序。

提高了安全性能。可以对不同的用户

设定不同的视图。例如:某用户只能获取user表的name和age数据,不能获取sex数据等其他数据。

create view other as select a.name, a.age from user as a;

sql语句面试题:

表内容:
2005-05-09 胜
2005-05-09 胜
2005-05-09 负
2005-05-09 负
2005-05-10 胜
2005-05-10 负
2005-05-10 负
如果要生成下列结果, 该如何写sql语句?
胜 负
2005-05-09 2 2
2005-05-10 1 2

select rq,sum(case when shengfu='胜' then 1 else 0 end) as '胜',sum(case when shengfu='负' then 1 else 0 end) as'负' from tmp group by rq

表中有A B C三列,用SQL语句实现:当A列大于B列时选择A列否则选择B列,当B列大于C列时选择B列否则选择C列。

select (case when a>b then a else b end),(case when b>c then b else c end) from table_name

请取出tb_send表中日期(SendTime字段)为当天的所有记录?(SendTime字段为datetime型,包含日期与时间)

select * from table_name where datediff(curdate(),SendTime)=0

有一张表,里面有3个字段:语文,数学,英语。其中有3条记录分别表示语文70分,数学80分,英语58分,请用一条sql语句查询出这三条记录并按以下条件显示出来(并写出您的思路):
大于或等于80表示优秀,大于或等于60表示及格,小于60分表示不及格。
显示格式:
语文 数学 英语
及格 优秀 不及格

select (case when '语文'>=80 then '优秀' case when '语文'>=60 then ’及格‘ else '不及格' end) as '语文' , (case when '数学'>=80 then '优秀' case when '数学'>=60 then ’及格‘ else '不及格' end) as '数学' ,(case when '英语'>=80 then '优秀' case when '英语'>=60 then ’及格‘ else '不及格' end) as '英语' from table_name

下面附上一个习题集,大家可以去上面练习一下:
sql语句练习题及答案

MYSQL分页查询优化

从性能最差的开始:

select * from table_name ordered by id limit 1000,10;

但是到百万级数据时会变得很慢

优化一点的语句:
SELECT * FROM table WHERE id >= (SELECT id FROM table LIMIT 1000000, 1) LIMIT 10;

因为id直接定位到1000000位置开始,而不用全表扫描过去。

下面这句可能更好一些:
SELECT * FROM table WHERE id BETWEEN 1000000 AND 1000010;

估计是因为没有用子查询,不会将结果存放在临时表中再执行第二步操作。between直接一步定位到1000000位置。

若查询id并不连续,使用IN的
SELECT * FROM table WHERE id IN(10000, 100000, 1000000...);

参考链接:
mysql视图的作用(详细)
SQL经典面试题及答案
MySQL 百万级分页优化(Mysql千万级快速分页)

推荐阅读更多精彩内容