[面试]常考数据库优化

来源:互联网 发布:卡来宝网络培训诈骗 编辑:程序博客网 时间:2024/05/28 18:45
1、分库分表(当数据记录达到百万级,如一年的客户销售表累计200W条记录)

2、添加索引(索引不能直接修改,只能删除后重新建)
create index idxname on table user(id);
drop index idxname;

MySQL单列索引和组合索引(联合索引)的区别详解
一个面试题:怎么加速这个where a=’1′ 和 where a=’1′ and b=’2′,
答案:a加索引,a和b加联合索引
create table users2 select * from users;
添加userName,password单列索引
alter table users add index userName(userName);
alter table users add index password(password);
select * from users where userName like 'username65%' and password like 'password65%'; 执行时间0.06 秒
alter table users2 add index userName_password(userName,password);
select * from users2 where userName like 'username65%' and password like 'password65%’;执行时间0.00秒
原因是在mysql执行查询的时候,只能使用一个索引,mysql会选择一个最严格(获得结果集记录数最少)的索引。最左前缀:顾名思义,就是最左优先,打一比方
alter table users add index lname_fname_age(lname,fname,age);
创建了lname_fname_age多列索引,相当于创建了(lname)单列索引,(lname,fname)联合索引以及(lname,fname,age)联合索引。   
https://www.phpsong.com/586.html  


3、锁定表
尽管事务是维护数据库完整性的一个非常好的方法,但却因为它的独占性,有时会影响数据库的性能,尤其是在很大的应用系统中。由于在事务执行的过程中,数据库将会被锁定,因此其它的用户请求只能暂时等待直到该事务结束。如果一个数据库系统只有少数几个用户来使用,事务造成的影响不会成为一个太大的问题;但假设有成千上万的用户同时访问一个数据库系统,例如访问一个电子商务网站,就会产生比较严重的响应延迟。
其实,有些情况下我们可以通过锁定表的方法来获得更好的性能。下面的例子就用锁定表的方法来完成前面一个例子中事务的功能。
例1、lock table user where select username from user where id=18;
例2、update user set pwd=123 where id=18;unlock tables
这里,我们用一个select语句取出初始数据,通过一些计算,用update语句将新值更新到表中。包含有WRITE关键字的LOCKTABLE语句可以保证在UNLOCKTABLES命令被执行之前,不会有其它的访问来对inventory进行插入、更新或者删除的操作。
尽管事务是维护数据库完整性的一个非常好的方法,但却因为它的独占性,有时会影响数据库的性能,尤其是在很大的应用系统中。由于在事务执行的过程中,数据库将会被锁定,因此其它的用户请求只能暂时等待直到该事务结束。如果一个数据库系统只有少数几个用户来使用,事务造成的影响不会成为一个太大的问题;但假设有成千上万的用户同时访问一个数据库系统,例如访问一个电子商务网站,就会产生比较严重的响应延迟。


4、外键
锁定表的方法可以维护数据的完整性,但是它却不能保证数据的关联性。这个时候我们就可以使用外键。
例如,外键可以保证每一条销售记录都指向某一个存在的客户。在这里,外键可以把customerinfo表中的CustomerID映射到salesinfo表中CustomerID,任何一条没有合法CustomerID的记录都不会被更新或插入到salesinfo中。
create table customerinfo(
customerid int not null,
primarykey(customerid)
) type=innodb;

create table salesinfo(
salesid int not null,
customerid int not null,
primarykey(customerid,salesid),
foreignkey(customerid) references customerinfo(customerid) on deletecascsde
) type=innodb;

注意例子中的参数“on deletecascsde”。该参数保证当customerinfo表中的一条客户记录被删除的时候,salesinfo表中所有与该客户相关的记录也会被自动删除。如果要在MySQL中使用外键,一定要记住在创建表的时候将表的类型定义为事务安全表InnoDB类型。该类型不是MySQL表的默认类型。定义的方法是在CREATETABLE语句中加上TYPE=INNODB。如例中所示。


5、使用join来代替子查询
MySQL从4.1开始支持SQL的子查询。这个技术可以使用SELECT语句来创建一个单列的查询结果,然后把这个结果作为过滤条件用在另一个查询中。例如,我们要将客户基本信息表中没有任何订单的客户删除掉,就可以利用子查询先从销售信息表中将所有发出订单的客户ID取出来,然后将结果传递给主查询,如下所示:
select from customerinfo where customerid not in(select customerid from salesinfo)
子查询可以被更有效率的连接join替代。例如,假设我们要将所有没有订单记录的用户取出来,可以用下面这个查询完成:
select * from customerinfo left join salesinfo on customerinfo.CustomerID=salesinfo.CustomerID where salesinfo.CustomerID is null
如果使用连接join来完成这个查询工作,速度将会快很多。尤其是当salesinfo表中对CustomerID建有索引的话,性能将会更好,查询如下:
连接join之所以更有效率一些,是因为MySQL不需要在内存中创建临时表来完成这个逻辑上的需要两个步骤的查询工作。

join用法详见 http://blog.csdn.net/wuhuagu_wuhuaguo/article/details/72867374

 

参考:http://www.cnblogs.com/zhyunfe/p/6209074.html