数据库优化法则

目录

 

一、减少数据访问

二、返回更少数据

三、减少交互次数

四、减少服务器CPU开销

使用绑定变量

五、利用更多资源


一、减少数据访问

创建索引,利用索引直接查找数据,避免扫描全表。

能利用索引的SQL样本:

INDEX_COLUMN = ?
INDEX_COLUMN > ?
INDEX_COLUMN >= ?
INDEX_COLUMN < ?
INDEX_COLUMN <= ?
INDEX_COLUMN between ? and ?
INDEX_COLUMN in (?,?,...,?)
INDEX_COLUMN like ?||'%'(后导模糊查询)
T1. INDEX_COLUMN=T2. COLUMN1(两个表通过索引字段关联)

不能利用索引的SQL样本:

查询条件 不能使用索引原因

INDEX_COLUMN <> ?

INDEX_COLUMN not in (?,?,...,?)

不等于操作不能使用索引

function(INDEX_COLUMN) = ?

INDEX_COLUMN + 1 = ?

INDEX_COLUMN || 'a' = ?

经过普通运算或函数运算后的索引字段不能使用索引

INDEX_COLUMN like '%'||?

INDEX_COLUMN like '%'||?||'%'

含前导模糊查询的Like语法不能使用索引
INDEX_COLUMN is null B-TREE索引里不保存字段为NULL值记录,因此IS NULL不能使用索引

NUMBER_INDEX_COLUMN='12345'

CHAR_INDEX_COLUMN=12345

Oracle在做数值比较时需要将两边的数据转换成同一种数据类型,如果两边数据类型不同时会对字段值隐式转换,相当于加了一层函数处理,所以不能使用索引。
a.INDEX_COLUMN=a.COLUMN_1 给索引查询的值应是已知数据,不能是未知字段值。

创建索引条件:

1、字段出现在查询条件中,并且查询条件可以使用索引;

2、语句执行频率高,一天会有几千次以上;

3、通过字段条件可筛选的记录集很小,那数据筛选比例是多少才适合?

这个没有固定值,需要根据表数据量来评估,以下是经验公式,可用于快速评估:

小表(记录数小于10000行的表):筛选比例<10%;

大表:(筛选返回记录数)< (表总记录数*单条记录长度)/10000/16

          (单条记录长度≈字段平均内容长度之和+字段数*2)

 建B-TREE索引的经验分类:

  字段类型 常见字段名
需要建索引的字段 主键 ID,PK
外键 PRODUCT_ID,COMPANY_ID,MEMBER_ID,ORDER_ID,TRADE_ID,PAY_ID
有对像或身份标识意义字段 HASH_CODE,USERNAME,IDCARD_NO,EMAIL,TEL_NO,IM_NO
索引慎用字段,需要进行数据分布及使用场景详细评估 日期 GMT_CREATE,GMT_MODIFIED
年月 YEAR,MONTH
状态标志 PRODUCT_STATUS,ORDER_STATUS,IS_DELETE,VIP_FLAG
类型 ORDER_TYPE,IMAGE_TYPE,GENDER,CURRENCY_TYPE
区域 COUNTRY,PROVINCE,CITY
操作人员 CREATOR,AUDITOR
数值 LEVEL,AMOUNT,SCORE
长字符 ADDRESS,COMPANY_NAME,SUMMARY,SUBJECT
不适合建索引的字段 描述备注 DESCRIPTION,REMARK,MEMO,DETAIL
大字段 FILE_CONTENT,EMAIL_CONTENT

二、返回更少数据

1、客户端(应用程序或浏览器)分页

将数据从应用服务器全部下载到本地应用程序或浏览器,在应用程序或浏览器内部通过本地代码进行分页处理

优点:编码简单,减少客户端与应用服务器网络交互次数

缺点:首次交互时间长,占用客户端内存

适应场景:客户端与应用服务器网络延时较大,但要求后续操作流畅,如手机GPRS,超远程访问(跨国)等等。

2、应用服务器分页

将数据从数据库服务器全部下载到应用服务器,在应用服务器内部再进行数据筛选。以下是一个应用服务器端Java程序分页的示例:

List list=executeQuery(“select * from employee order by id”);

Int count= list.size();

List subList= list.subList(10, 20);

优点:编码简单,只需要一次SQL交互,总数据与分页数据差不多时性能较好。

缺点:总数据量较多时性能较差。

适应场景:数据库系统不支持分页处理,数据量较小并且可控。

3、数据库SQL分页

采用数据库SQL分页需要两次SQL完成

一个SQL计算总数量

一个SQL返回分页后的数据

优点:性能好

缺点:编码复杂,各种数据库语法不同,需要两次SQL交互。

4、只返回需要的字段

通过去除不必要的返回字段可以提高性能。

优点:

a、减少数据在网络上传输开销

b、减少服务器数据处理开销

c、减少客户端内存占用

d、字段变更时提前发现问题,减少程序BUG

e、如果访问的所有字段刚好在一个索引里面,则可以使用纯索引访问提高性能。

5、优化业务逻辑

三、减少交互次数

使用数据库访问框架批量提交的接口

四、减少服务器CPU开销

使用绑定变量

绑定变量是指SQL中对变化的值采用变量参数的形式提交,而不是在SQL中直接拼写对应的值。

非绑定变量写法:Select * from employee where id=1234567

绑定变量写法:

Select * from employee where id=?

Preparestatement.setInt(1,1234567)

Java中Preparestatement就是为处理绑定变量提供的对像,绑定变量有以下优点:

1、防止SQL注入

2、提高SQL可读性

3、提高SQL解析性能,不使用绑定变更我们一般称为硬解析,使用绑定变量我们称为软解析。

使用绑定变量提高SQL解析性能原因:

当一条SQL发送给数据库服务器后,系统首先会将SQL字符串进行hash运算,得到hash值后再从服务器内存里的SQL缓存区中进行检索,如果有相同的SQL字符,并且确认是同一逻辑的SQL语句,则从共享池缓存中取出SQL对应的执行计划,根据执行计划读取数据并返回结果给客户端。

如果在共享池中未发现相同的SQL则根据SQL逻辑生成一条新的执行计划并保存在SQL缓存区中,然后根据执行计划读取数据并返回结果给客户端。

为了更快的检索SQL是否在缓存区中,首先进行的是SQL字符串hash值对比,如果未找到则认为没有缓存,如果存在再进行下一步的准确对比,所以要命中SQL缓存区应保证SQL字符是完全一致,中间有大小写或空格都会认为是不同的SQL。

如果我们不采用绑定变量,采用字符串拼接的模式生成SQL,那么每条SQL都会产生执行计划,这样会导致共享池耗尽,缓存命中率也很低。

五、利用更多资源

1、客户端多进程并行访问

2、数据库并行处理

引用

猜你喜欢

转载自blog.csdn.net/u012088516/article/details/82802123