码迷,mamicode.com
首页 > 数据库 > 详细

数据库 - 性能优化

时间:2020-02-18 16:32:30      阅读:153      评论:0      收藏:0      [点我收藏+]

标签:注入   innodb   scores   运行   sql语句   表单   存储   集群   order by   

数据库

实现数据持久化,使用完整的管理系统统一管理,易于查询;

数据库概念:

²  DB(数据库Database):存储数据的仓库,保存了一系列有组织的数据;

²  DBMS(数据库管理系统Database Management System):数据库是DBMS创建和操作的容器;

²  SQL(结构化查询语言(StructureQueryLanguage):专门用来和数据库通信的语言;

事务(Database Transaction):是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行;特性:事务是恢复和并发控制的基本单位;在关系型数据库中,一个事务可以是一条SQL语句,一组SQL语句或整个程序;

数据库分类

当今的互联网中,最常见的数据库模型:关系型数据库(SQL)和非关系型数据库(NoSQL)

关系型数据库

关系就是二维表。并满足如下性质:

行row:表中的每一行,又称为一条记录

列column:表中的每一列,称为属性

主键PK(Primary key):用于惟一确定一条记录的字段,外键FK

域domain:属性的取值范围,如,性别只能是‘男’和‘女’两个值

缺点:性能没有非关系性数据库好;              优点:数据统计有严谨性

非关系型数据库

NoSQL数据存储不需要固定的表结构,通常也不存在连接操作。在大数据存取上具备关系型数据库无法比拟的性能优势。NoSQL目前的四种大的分类:

键值对存储(key-value):代表软件Redis,它的优点是能够进行数据的快速查询,缺点是需要存储数据间之间的关系;

文档数据库存储:代表软件MongoDB,它的优点是对数据结构要求不特别的严格。而缺点是查询的性能不好,同时缺少一种统一的查询语句;

图形数据库存储:代表软件InfoGrid,它的优点是可以方便的利用图结构相关算法进行计算。而缺点是要想得到结果必须进行整个图的计算,而且遇到不适合的数据模型时,图形数据库很难使用;

列存储:代表软件是Hbase,它的优点是对数据能快速查询,数据存储的扩展性强。而缺点是数据库的功能的局限性;

优点:

  • 高并发,大数据下读写能力较强。(基于键值对的,可以想象成表中的主键和值的对应关系,而且不需要经过SQL层的解析,所以性能非常高)
  • 基本支持分布式,易于扩展,可伸缩。(因为基于键值对,数据之间没有耦合性,所以非常容易水平扩展。)
  • 简单,弱结构化存储。

缺点:

  • 事务支持较弱。
  • 通用性差。
  • 无完整约束复杂业务场景支持较差。

关系型数据库和非关系型数据库比较:

关系型数据库,是指采用了关系模型来组织数据的数据库。简单来说,关系模型指的就是二维表格模型,而一个关系型数据库就是由二维表及其之间的联系所组成的一个数据组织。关系型数据库的最大特点就是事务的一致性:传统的关系型数据库读写操作都是事务的,具有ACID的特点,这个特性使得关系型数据库可以用于几乎所有对一致性有要求的系统中,如典型的银行系统。

优点:

²  容易理解:二维表结构是非常贴近逻辑世界的一个概念,关系模型相对网状、层次等其他模型来说更容易理解

²  使用方便:通用的SQL语言使得操作关系型数据库非常方便

²  易于维护:丰富的完整性(实体完整性、参照完整性和用户定义的完整性)大大减低了数据冗余和数据不一致的概率

缺点:

²  数据读写必须经过sql解析,大量数据、高并发下读写性能不足。对于传统关系型数据库来说,硬盘I/O是一个很大的瓶颈。

²  具有固定的表结构,因此扩展困难。

²  多表的关联查询导致性能欠佳

索引

1.数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中数据

2.索引的实现通常使用B树及其变种B+树。

优点:创建索引可以大大提高系统的性能。创建唯一索引,保证数据库表中每一行数据的唯一性;加快数据检索速度(创建索引的主要目的);加速表于表之间的连接,特别是在是实现数据的参考完整性方面特别有意义;

缺点:一是增加了数据库的存储空间;二是在插入和修改数据时要花费较多额时间(因为索引也要随之变动)

三范式

第一范式(1NF):强调的是列的原子性,即列不能够再分成其他几列;

第二范式(2NF):首先是1NF,另外包含两部分内容,一是表必须有一个主键;二是没有包含在主键中的列必须完全依赖于主键,而不能只依赖于主键的一部分。

第三范式(3NF):首先是2NF,另外非主键列必须直接依赖于主键,不能存在传递依赖。即不能存在:非主键列A依赖于非主键列B,非主键列B依赖于主键的情况。

缓存三大坑(穿透、击穿、雪崩)

缓存穿透:一般的缓存系统,都是按照key去缓存查询,如果不存在对应的value,就应该去后端系统查找(比如DB)。一些恶意的请求会故意查询不存在的key,请求量很大,就会对后端系统造成很大的压力。这就叫做缓存穿透。

如何避免:1:对查询结果为空的情况也进行缓存,缓存时间设置短一点,或者该key对应的数据insert了之后清理缓存。2:对一定不存在的key进行过滤。可以把所有的可能存在的key放到一个大的Bitmap中,查询时通过该bitmap过滤。

缓存雪崩:当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,会给后端系统带来很大压力。导致系统崩溃。

如何避免?1:在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待。2:做二级缓存,A1为原始缓存,A2为拷贝缓存,A1失效时,可以访问A2,A1缓存失效时间设置为短期,A2设置为长期。3:不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀。

缓存穿透:指查询的数据在数据库中是没有的,那么在缓存中自然也是没有的,所以在缓存中查不到就去数据库查询,这样的请求一多,我们数据库的压力自然会增大;

解决:1。对于返回为NULl的依然缓存,对于抛出异常的返回不进行缓存,但不要把抛出异常的页缓存了;2。制定一些规则过滤一些不太可能存在的数据,小数据用BitMap,大数据可以用布隆过滤器;

缓存击穿:对于某些Key设置了国企时间,但是它是热点数据,如果某个Key失效,可能大量的请求打过来,缓存未命中,然后去数据库访问,此时数据库访问量会急剧增加;

解决:1。加分布式锁;2。异步加载,对这部分热点数据采取到期自动刷新的策略;

缓存雪崩:指缓存不可用或者大量缓存由于超时时间相同在同一时间段失效,大量请求直接访问数据库,数据库压力过大导致系统雪崩;

解决:1。增加缓存系统可用性,通过监控关注缓存的健康程度,根据业务量适当的扩容缓存。2。采用多级缓存,不同级别缓存设置的超时时间不同,即使某个级别缓存都过期,也有其它级别缓存兜底;3。缓存的Key值可以取个随机值,比如以前是设置10分钟的超时时间,那每个Key都可以随机8-13分钟过期,尽量让不同的Key的过期时间不同;

ACDI事物的四大特性

原子性(Atomicity):是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生,不可能滞留在中间某个环节。比如:转账转过去的加和转时候的减必须一次发生,若事务在执行过程中发生错误,会被回滚(Rollback)到事物开始前的状态,就像这个事务从来没有执行过;

一致性(Consistency):如果事务是并发多个,系统也必须如同串行事务一样操作;主要特征是保护性和不变性(PreservinganInvariant);比如,多个账户之间任意转账,但是账户总额会保持不变;

隔离性(Isolation):事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。为了防止事务操作间的混淆,必须串行化或序列化请求,使得在同一时间仅有一个请求用于数据;

持久性(Durability):在事务完成之后,该事务对数据库所作的更改便永久的保存在数据库之中,并不会被回滚;一个支持事务(Transaction)的数据库,必须要具有这四种特性,否则在事务过程(Transactionprocessing)当中无法保证数据的正确性,交易过程极可能达不到交易方的要求;

关系型数据库强调ACID原则,而NoSQL数据库强调BASE原则:基本可用(BasicallyAvailble)、软状态(Soft-state)、最终一致性(EventualConsistency);它减少的对数据一致性支持,从而获得了基本一致性和柔和可靠性,并且利用以上的特性达到了高可靠性和高性能,最终达到了数据的最终一致性;

数据库开启事务命令:

1、  start transaction开启事务

2、  Roll back回滚事务

3、  Commit提交事务

当Jdbc程序向数据库获得一个Connection对象时,默认情况下这个Connection对象会自动向数据库提交在它上面发送的SQL语句。若想关闭这种默认提交方式,让多条SQL在一个事务中执行,可使用下列语句:

JDBC控制事务语句

Connection.setAutoCommit(false);如同数据库开启命令的starttransaction

Connection.rollback();==rollback

Connection.commit();==commit

设置事务回滚点

Savepointsp=conn。setSavepoint();

Conn.rollback(sp);

Conn。commit();//回滚后必须要提交

使用最多的数据库(mysqlmongodbredis等),对他的理解?

答:MySQL数据库:开源免费的关系型数据库,需要实现创建数据库、数据表和表的字段,表与表之间可以进行关联(一对多、多对多),是持久化存储。

mongodb数据库:是非关系型数据库,数据库的三元素是,数据库、集合、文档,可以进行持久化存储,也可作为内存数据库,存储数据不需要事先设定格式,数据以键值对的形式存储。

redis数据库:非关系型数据库,使用前可以不用设置格式,以键值对的方式保存,文件格式相对自由,主要用与缓存数据库,也可以进行持久化存储。

数据库优化技术:分表分库、读写分离、索引优化;

MySQL数据库的调优

1、选择合适的存储引擎:

查询多—>myisam

写操作多—>innodb

2、SQL语句的调优(尽量避免全表扫描,加快数据的检索速度)

1。在select、where、orderby常涉及到的字段上建立索引

2。where子句中不适用!=,否则导致全表扫描

3、尽量避免空值(NULL)判断,否则导致全表扫描

优化前:select id from t1 where number is null;

优化后:可以在number设置默认值为0,确保number无NULL,查询如下

selecrt id from t1 where number = 0;

4、尽量避免用or来连接条件,否则全表扫描

优化前:select id from t1 where id = 10 or id=20;

优化后:select id from t1 whereid = 10

union all

select id from t1 where id = 20;

5、模糊查询尽量避免前置%、否则全表扫描

select id from t1 where name like“c%”;

6、尽量避免in和not in的使用,否则导致全表扫描

select id from t1 where number in(1,2,3);

对于连续的值,尽量用between and

7、尽量避免使用select*fromt1;要用具体的字段名代替*,不用返回用不到的任何字段

数据库四种隔离级别:

脏读:事务A对数据修改以后没有提交,之前事务B对数据进行查询,查询到事务A修改的那一条数据,那条数据即为脏数据,B读取极为脏读;

不可重复读:事务A在查询一条数据后没有提交,事务B对数据进行update或者delete操作,然后事务A再一次查询的时候发现数据发生了变化;

幻读:事务A在查询一条数据后没有提交,事务B对数据进行了insert操作,然后事务A再一次查询的时候发现数据发生了变化;

不可重复读是针对有数据库表中的行,而幻读是针对整个数据库,而实际数据库操作的时候为了解决不可重复读和幻读,需要在读数据时加上读锁(共享锁),在写数据时加上(排它锁),隔离事务。

l  数据库在执行delete,insert,update的时候会默认自动加上排它锁;

l  共享锁和排它锁都是数据悲观锁范畴,都是悲观锁不同的实现;

l  锁是目前解决多用户并发访问的有效手段;

Serializable可避免脏读、不可重复度、虚读情况的发生;(串行化)

Repeatableread可避免脏读、不可重复读情况的发生;(可重复度)

Readcommitted可避免脏读情况发生;(读已提交)

Readuncommitted最低级别,以上情况均无法保证;(读未提交)

设置事务隔离级别:settransactionisolationlevel;

查询当前事务隔离级别:select@@tx_isolation;

1、当把事务的隔离级别设置为readuncommitted时,会引发脏读、不可重复读和虚读

A窗口

settransactionisolationlevelreaduncommitted;

starttransaction;

select*fromaccount;

-----发现a帐户是1000元,转到b窗口

select*fromaccount

-----发现a多了100元,这时候a读到了b未提交的数据(脏读)

B窗口

starttransaction;

updateaccountsetmoney=money+100wherename=‘aaa‘;

-----不要提交,转到a窗口查询

2、当把事务的隔离级别设置为readcommitted时,会引发不可重复读和虚读,但避免了脏读

A窗口

settransactionisolationlevelreadcommitted;

starttransaction;

select*fromaccount;

-----发现a帐户是1000元,转到b窗口

select*fromaccount;

-----发现a帐户多了100,这时候,a读到了别的事务提交的数据,两次读取a帐户读到的是不同的结果(不可重复读)

B窗口

starttransaction;

updateaccountsetmoney=money+100wherename=‘aaa‘;

commit;

-----转到a窗口

3、当把事务的隔离级别设置为repeatablereadmysql默认级别)时,会引发虚读,但避免了脏读、不可重复读

A窗口

settransactionisolationlevelrepeatableread;

starttransaction;

select*fromaccount;

----发现表有4个记录,转到b窗口

select*fromaccount;

----可能发现表有5条记如,这时候发生了a读取到另外一个事务插入的数据(虚读)

B窗口

starttransaction;

insertintoaccount(name,money)values(‘ggg‘,1000);

commit;

-----转到a窗口

4、当把事务的隔离级别设置为Serializable时,会避免所有问题

A窗口

settransactionisolationlevelSerializable;

starttransaction;

select*fromaccount;

-----转到b窗口

B窗口

starttransaction;

insertintoaccount(name,money)values(‘ggg‘,1000);

-----发现不能插入,只能等待a结束事务才能插入

什么是约束,有哪些?

为保证插入表的数据的完整性和正确性,在创建表时,对表进行限定;

约束种类

primary key 主键    非空且唯一

no null  非空

unique  唯一

autoincrement  主键自增长    当主键为interger型,可以自增长

foreign key  外键    一张表的外键可以关联另一张表的主键,而保证数据完整性

例子:create table orders
(
o_id int not null primary key,
orderno int not null,
p_id int foreign key references persons(p_id)
);
“persons”表中的”P_id”列是”Person”表中的PRIMARY KEY。
“Order”表中的”P_id”列是”Orders”表中的FOREIGN KEY。
check 约束用于限制列中的值的范围    如:  check(age>0)
DEFAULT 约束用于向列中插入默认值。  
    如:
    OrderData date DEFAULT GETDATE()
    City varchar(255)DEFAULT”SANdnes”
    City 字段 默认值设置为sandnes
创建表实例:creat table student(
id interger primary key autoincrement. -- 主键自增长
name text not null,  -- 非空
age interger,
gender text,
emall text unique,  -- 唯一
check(age>0)
);

表操作:

show table:查询当前的数据库下的所有表名称

desc表名:查询表的详细信息

drop table:删除表

查询数据:

语法:SELECT selection_list  /*要查询的列名称*/

FROM table_list  /*要查询的表名称*/

WHERE condition  /*行条件*/

GROUP BY grouping_columns  /*对结果分组*/

HAVING condition  /*分组后的条件*/

ORDER BY sorting_columns  /*对结果分组*/

LIMIT offset_start, row_count  /*结果限定*/

通配符* : select * from table

别名as: SELECT column_name FROM table_name AS name;

计算字段 拼接:+, ||, concat()

去除重复记录 distinct: SELECT DISTINCT column,

目标from:

过滤where:

分组group by:

排序order by:

组合查询union:

操作表中数据:

增:insert into 表明(列名1,列名2…)value(值1,值2,…);

如果是所有的列添加数据,则列名可以忽略

insert into student (id, name, age, email) values( 3, ’male’, ‘23’, ‘cch@test.cn’);

删:delete from 表名 [where 条件];

如果不添加条件,则将表中的数据全部删除;

删除所有行truncate table

改:update 表名 set 列名=值,列2=值2,…[where 条件];

UPDATE Scores SET Scores = Scores + 5 WHERE Score <= 95

事务:

索引:索引是对数据库表中一列或多列的值进行排序的一种结构,如字典目录

优点:提高检索性能,加强行的唯一性;

缺点:降低了插入、修改、删除性能,占用空间;

创建索引的知道原则:

1.经常访问的列;

2.在一个经常做插入的表中建立索引,应该使用fillfactor(填充因子)来减少页分裂;

视图:一个包含某个查询的虚拟表

对视图进行的操作,依托于真实的表:

1.主要的目的是简化语句

2.对性能没有改善

用途:

筛选表中的行;

降低数据的复杂程度;

防止未经许可访问敏感数据,提高安全性能;

将多个物理数据库抽象为一个逻辑数据库;

视图的基本操作和语法:

创建视图:CREATE VIEW view_name AS

SELECT column_name(s)

FROM table_name

WHERE condition

更新视图:CREATE OR REPLACE VIEW view_name AS

SELECT column_name(s)

FROM table_name

WHERE condition

撤销视图:DROP VIEW view_name

使用试图:SELETC * FROM view_name

SQL注入和解决办法

简介:SQL注入是比较常见的网络攻击方式之一,它不是利用操作系统的BUG来实现攻击,而是针对程序员编程时的疏忽,通过SQL语句,实现无账号登录,甚至篡改数据库。

注入攻击的总体思路:

1.寻找到SQL注入的位置

2.判断服务器类型和后台数据库类型

3.针对不同的服务器和数据库特点进行SQL注入攻击

预防的总体思路:总的来说,防范一般的SQL注入只要在代码规范上下点功夫就可以了。凡涉及到执行的SQL中有变量时,用JDBC(或者其它数据持久层)提供的如:PreparedStatement就可以,切记不要用拼接字符串的方法就可以了。

SQL注入就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。对于很多很多网站都有用户提交表单的端口,提交的数据插入MySQL数据库中,就有可能发生SQL注入安全问题。针对SQL注入安全问题的预防,需时刻认定用户输入的数据是不安全的,并对用户输入的数据进行过滤处理,对不同的字段进行条件限制,符合条件的可以写入数据库,不符合条件的进行数据过滤处理!

SQL结构化查询语言,及其优化

SQL【访问和处理数据库的标准计算机语言】

指结构化查询语言,全称是Structured Query Language

是一种ANSI(American National Standards Institute美国国家标准化组织)标准的计算机语言。

RDBMS关系型数据库管理系统,全称Relational Database Management System。是SQL的基础,同样也是所有现代数据库系统的基础,比如MSSQLServer、IBMDB2、Oracle、MySQL以及MicrosoftAccess。

SQL的四个组成部分:

1、数据库模式定义语言DDL:create用来创建数据库中的各种对象——表、视图、索引、同义词、聚簇等;

2、数据查询语言dql:基本结构是由SELECT子句,FROM子句和WHERE子句组成的查询块;

3、数据操纵语言dml:插入INSERT、更新UPDATE和删除DELETE;

4、数据控制语言dcl:用来授予或回收访问数据库的某种特权,并控制数据库操纵事物发生的时间和效果,对数据库实行监视等;

表操作:

  • 创建:Creat table表名(字段名称字段类型约束……);
  • 更新:alter table【增列add、删列drop、改列类型(modify)、改列名(change)、改表明(rename)】;
  • 查询表:show table(查询当前数据库下的所有表名称);desc表名(查询表的详细信息);
  • 删除表:drop

查询数据:

目标from、过滤where、分组groupby、排序orderby;

子查询、组合查询union、聚合函数;

操作表中数据:触发器:事务:索引:试图:

例子:数据表student有id,name,score,city字段,其中name有重复,需要消除重复行写sql语句:

select distinct name from student

 技术图片

 

 技术图片

 

 

SQL优化原因:项目初期,业务数据量相对较少,一些SQL的执行效率对程序运行效率的影响不太明显,开发和运维人员也无法判断SQL对程序的运行效率有多大,故很少针对SQL进行专门的优化,而随着时间的积累,业务数据量的增多,SQL的执行效率对程序的运行效率的影响逐渐增大,此时对SQL的优化就很有必要。

SQL优化的一些方法:

1。对查询进行优化,应尽量避免全表扫描,首先应考虑在where及orde  rby涉及的列上建立索引。
2。应尽量避免在where子句中对字段进行null值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:select id from tuu where num is null
可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:
selectidfromtwherenum=0
3。应尽量避免在where子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。
4。应尽量避免在where子句中使用or来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:
selectidfromtwherenum=10ornum=20
可以这样查询:selectidfromtwherenum=10
unionall
selectidfromtwherenum=20
5。in和notin也要慎用,否则会导致全表扫描,如:selectidfromtwherenumin(1,2,3)
对于连续的数值,能用between就不要用in了:selectidfromtwherenumbetween1and3
6。下面的查询也将导致全表扫描:selectidfromtwherenamelike‘%abc%‘
7。应尽量避免在where子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:selectidfromtwherenum/2=100
应改为:selectidfromtwherenum=100*2
8。应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:
selectidfromtwheresubstring(name,1,3)=‘abc‘--name以abc开头的id
应改为:selectidfromtwherenamelike‘abc%‘
9。不要在where子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。
10。在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。
11。不要写一些没有意义的查询,如需要生成一个空表结构:selectcol1,col2into#tfromtwhere1=0
这类代码不会返回任何结果集,但是会消耗系统资源的,应改成这样:createtable#t(。。。)
12。很多时候用exists代替in是一个好的选择:selectnumfromawherenumin(selectnumfromb)
用下面的语句替换:selectnumfromawhereexists(select1frombwherenum=a。num)
13。并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,如一表中有字段sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。
14。索引并不是越多越好,索引固然可以提高相应的select的效率,但同时也降低了insert及update的效率,
因为insert或update时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。
一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。
15。尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。
16。尽可能的使用varchar代替char,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。
17。任何地方都不要使用select*fromt,用具体的字段列表代替“*”,不要返回用不到的任何字段。
18。避免频繁创建和删除临时表,以减少系统表资源的消耗。

19。临时表并不是不可使用,适当地使用它们可以使某些例程更有效,例如,当需要重复引用大型表或常用表中的某个数据集时。但是,对于一次性事件,最好使用导出表。
20。在新建临时表时,如果一次性插入数据量很大,那么可以使用selectinto代替createtable,避免造成大量log以提高速度;如果数据量不大,为了缓和系统表的资源,应先createtable,然后insert。

21。如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先truncatetable,然后droptable,这样可以避免系统表的较长时间锁定。
22。尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该考虑改写。
23。使用基于游标的方法或临时表方法之前,应先寻找基于集的解决方案来解决问题,基于集的方法通常更有效。

24。与临时表一样,游标并不是不可使用。对小型数据集使用FAST_FORWARD游标通常要优于其他逐行处理方法,尤其是在必须引用几个表才能获得所需的数据时。在结果集中包括“合计”的例程通常要比使用游标执行的速度快。如果开发时间允许,基于游标的方法和基于集的方法都可以尝试一下,看哪一种方法的效果更好。

25。尽量避免大事务操作,提高系统并发能力。

26。尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。

数据库优化方案?

1.避免全表扫描,首先应考虑在where及order by涉及的列上建立索引。

2.避免在where子句中对字段进行null值判断,导致引擎放弃使用索引而进行全表扫描

3.避免在where子句中使用!=或>操作符,引擎将放弃使用索引而进行全表扫描。

4.避免在where子句中使用or来连接条件

5.慎用in和not,可以用exists代替in

6.慎用like‘XXX%‘,要提高效率,可以全文检索。

7.应尽量避免在where子句中对字段进行表达式操作,如:select id fromt where num/2 = 100

应改为select id fromt where num=100*2

8.避免在where子句中对字段进行函数操作

select id fromt where substring(name,1,3)=‘abc‘ 改为:select id fromt where name like‘abc%‘

9.在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。(索引的最左前缀原则)

10.并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,如一表中有字段sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。

11.索引不是越多越好,索引可以提高select的效率,同时也降低insert及update的效率,因为insert或update时有可能会重建索引。

12.任何地方都不要使用select * fromt,用具体的字段列表代替“*”

13.避免频繁创建和删除临时表,以减少系统表资源的消耗。

14.在新建临时表时,如果一次性插入数据量很大,那么可以使用select into代替create table,避免造成大量log,以提高速度;如果数据量不大,为了缓和系统表的资源,应先create table,然后insert。

15.尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。

数据库中的数据在未进行分库分表的情况下,随着时间和业务的发展,库中的表会越来越多,表中的数据量也会越来越大,相应地,数据操作,增删改查的开销也会越来越大

16.读写分离:通过数据库配置设置,mysql复制时,产生了多个数据副本(备库),为减少服务器压力,备库用于处理读操作,主库可同时处理读写。备库的复制是异步的,无法实时同步,读写分离的主要难点也在于备库上的脏数据。通常如果使用备库进行读,一般对数据的实时性要求不能太高。

17.分库、分表。

分库:当数据库中的表太多,可以考虑将表分到不同的数据库

分表:水平分表:将一些列分到另一张表

垂直分表:将历史信息分到另一张表中,很久之前的记录少有查询

18.利用缓存存储经常被查询的数据。利用redis、memcache

数据库优化问题可以从那几个层面入手

1、根据服务层面:配置mysql性能优化参数

2、从系统层面增强mysql的性能:优化数据表结构、字段类型、字段索引、分表、分库、读写分离等等

3、从数据库层面增强性能:优化SQL语句,合理使用字段索引

4、从代码层面增强性能:使用缓存和NoSQL数据库方法存储,如MongoDB/Memcache/Redis来缓存高并发下数据库查询的压力

5、减少数据库操作次数,尽量使用数据库访问驱动的批处理方法

6、不常使用的数据迁移备份,避免每次都在海量数据中去检索

7、提升数据库服务器硬件配置,或者搭建数据库集群

8、编程手段防止SQL注入:使用JDBC PrepareStatement 按位插入和查询;正则表达式过滤(非法字符串过滤);

主键和外键

主键:主键是能确定表中一条记录的唯一标识

外键:在一个表中存在的另一个表的主键称为此表的外键

外键用于与另一张表的关联。是能确定另一张表记录的字段,用于保持数据的一致性。一个表可以有多个外键。

drop、delete、trunca(截短、缩短、删节)

drop直接删掉表、truncate删除表中数据,在插入时自增长id又从1开始

delete删除表中数据,可以加where子句

使用orm和原生sql的优缺点?

ORM框架:

  对象关系映射,通过创建一个类,这个类与数据库的表相对应!类的对象代指数据库中的一行数据。

简述ORM原理:

  让用户不再写SQL语句,而是通过类以及对象的方式,和其内部提供的方法,进行数据库操作!把用户输入的类或对象转换成SQL语句,转换之后通过pymysql执行完成数据库的操作。

ORM的优缺点:

优点: 
  * 提高开发效率,降低开发成本 
  * 使开发更加对象化 
  * 可移植 
  * 可以很方便地引入数据缓存之类的附加功能

缺点: 
  * 在处理多表联查、where条件复杂之类的查询时,ORM的语法会变得复杂。就需要写入原生SQL。

数据库的数据是实时更新的吗?每点击一次,数据库数据修改一次?

答:要做到实时更新,最好是数据库支持通知机制,也就是数据库某表数据发生变化自动通知前台,也就是数据库自动推数据。通常条件比较苛刻;

所以我们用程序定时拉数据,做不到真正的实时,主要看你拉数据的间隔和执行效率。当然也有一些黑科技,自己挖掘吧,比如用程序通知程序而不是去数据库去拉数据;

数据库 - 性能优化

标签:注入   innodb   scores   运行   sql语句   表单   存储   集群   order by   

原文地址:https://www.cnblogs.com/qingaoaoo/p/12326593.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!