博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
数据库性能优化手法
阅读量:5168 次
发布时间:2019-06-13

本文共 3733 字,大约阅读时间需要 12 分钟。

1.创建必要的索引 (在经常检索的字段进行创建索引,比如以图书名称来进行检索,就需要在这个图书名称的字段创建索引)
2.使用预编译查询(
程序中通常是根据用户的输入来动态执行
SQL
语句,这时应该尽量使用参数化
SQL
,这样不仅可以避免
SQL
注入漏洞攻击,最重要数据库会对这些参数化
SQL
执行
预编译,这样第一次执行的时候
DBMS
会为这个
SQL
语句进行查询优化并且执行预编
译,这样以后再执行这个
SQL
的时候就直接使用预编译的结果,这样可以大大提高执
行的速度。)
3.调整 WHERE 子句中的连接顺序
DBMS
一般采用自下而上的顺序解析
WHERE
子句,根据这个原理
,
表连接最好写
在其他
WHERE
条件之前,那些可以过滤掉最大数量记录。
比如下面的
SQL
语句性能较差:
SELECT *FROM T_PersonWHERE FSalary > 50000AND FPosition= ‘MANAGER’AND 25 < (SELECT COUNT(*) FROM T_ManagerWHERE FManagerId=2);
我们将子查询的条件放到最前面,下面的
SQL
语句性能比较好:
SELECT *FROM T_PersonWHERE25 < (SELECT COUNT(*) FROM T_ManagerWHERE FManagerId=2)AND FSalary > 50000AND FPosition= ‘MANAGER’ ;
4.SELECT语句中避免使用'*'
 
5.尽量将多条 SQL语句压缩到一句SQL
6.Where子句替换 HAVING
子句
避免使用
HAVING
子句,因为
HAVING
只会在检索出所有记录之后才对结果集
进行过滤。如果能通过
WHERE
子句限制记录的数目,那就能减少这方面的开销。
HAVING
中的条件一般用于聚合函数的过滤,除此而外,应该将条件写在
WHERE
句中
7. 使用表的别名
当在
SQL
语句中连接多个表时,请使用表的别名并把别名前缀于每个列名上。这
样就可以减少解析的时间并减少那些由列名歧义引起的语法错误。
8.EXISTS替代 IN
在查询中,为了满足一个条件,往往需要对另一个表进行联接,在这种情况下,使
EXISTS
而不是
IN
通常将提高查询的效率,因为
IN
子句将执行一个子查询内部的排
序和合并。下面的语句
2
就比语句
1
效率更加高。
语句
1
SELECT * FROM T_EmployeeWHERE FNumber> 0AND FDEPTNO IN (SELECT FNumberFROM T_DepartmentWHERE FMangerName = 'Tome')语句 2:SELECT * FROM T_EmployeeWHERE FNumber > 0AND EXISTS (SELECT 1FROM T_DepartmentWHERE T_Department. FDEPTNO = EMP.FNumberAND FMangerName = ‘MELB’ )
9.用表连接替换 EXISTS
通常来说,表连接的方式比
EXISTS
更有效率,因此如果可能的话尽量使用表连
接替换
EXISTS
。下面的语句
2
就比语句
1
效率更加高。
语句
1
SELECT FName FROM T_EmployeeWHERE EXISTS(SELECT 1 FROM T_DepartmentWHERE T_Employee.FDepartNo= FNumberAND FKind='A');语句 2:SELECT FName FROM T_Department, T_EmployeeWHERE T_Employee. FDepartNo = T_Departmen. FNumberAND FKind = ‘A ’ ;
10.避免在索引列上使用计算
WHERE
子句中,如果索引列是计算或者函数的一部分,
DBMS
的优化器将不
会使用索引而使用全表扫描。
例如下面的
SQL
语句用于检索月薪的
12
倍大于两万五千元的员工:
SELECT *FROM T_EmployeeWHERE FSalary * 12 >25000;
由于在大于号左边的是
FSalary
12
的成绩表达式,这样
DBMS
的优化器将不会
使用字段
FSalary
的索引,因为
DBMS
必须对
T_Employee
表进行全表扫描,从而计算
FSalary * 12
的值,然后与
25000
进行比较。将上面的
SQL
语句修改为下面的等价写法
DBMS
将会使用索引查找,从而大大提高了效率:
SELECT *FROM T_EmployeeWHERE FSalary >25000/12;
同样的,不能在索引列上使用函数,因为函数也是一种计算,会造成全表扫描。下
面的语句
2
就比语句
1
效率更加高。
语句
1
SELECT * FROM T_ExampleWHERE ABS(FAmount)=300语句 2:SELECT * FROM T_ExampleWHERE FAmount=300 OR FAmount=-300
11.UNION ALL 替换 UNION
SQL
语句需要
UNION
两个查询结果集合时,即使检索结果中不会有重复的记
录,如果使用
UNION
这两个结果集同样会尝试进行合并,然后在输出最终结果前进行
排序。
因此,如果检索结果中不会有重复的记录的话,应该用
UNION ALL
替代
UNION
,这
样效率就会因此得到提高。下面的语句
2
就比语句
1
效率更加高。
语句
1
SELECTACCT_NUM, BALANCE_AMTFROM DEBIT_TRANSACTIONS1WHERE TRAN_DATE = '20010101'UNIONSELECTACCT_NUM, BALANCE_AMTFROM DEBIT_TRANSACTIONS2WHERE TRAN_DATE ='20010102'
语句
2
SELECTACCT_NUM, BALANCE_AMTFROM DEBIT_TRANSACTIONS1WHERE TRAN_DATE ='20010101'UNION ALLSELECTACCT_NUM, BALANCE_AMTFROM DEBIT_TRANSACTIONS2WHERE TRAN_DATE = '20010102'
12.避免隐式类型转换造成的全表扫描
T_Person
表的字符串类型字段
FLevel
为人员的级别,在
FAge
字段上建有索引。
我们执行下面的
SQL
语句用于检索所有级别等于
10
的员工:
SELECT FId,FAge,FNameFROM T_PersonWHERE FAge=10
在这个
SQL
语句中,将字符串类型字段
FLevel
与数值
10
进行比较,由于在大部
分数据库中隐式转换类型中数值类型的优先级高于字符串类型,因此
DBMS
会对
FAge
字段进行隐式类型转换,相当于执行了下面的
SQL
语句:
SELECT FId,FAge,FNameFROM T_PersonWHERE TO_INT(FAge)=10
由于在索引字段上进行了计算,所以造成了索引失效而使用全表扫描。因此应将
SQL
语句做如下修改:
SELECT FId,FAge,FNameFROM T_PersonWHERE FAge='10'
13.防止检索范围过宽
如果
DBMS
优化器认为检索范围过宽,那么它将放弃索引查找而使用全表扫描。
下面是几种可能造成检索范围过宽的情况:
使用
IS NOT NULL
或者不等于判断,可能造成优化器假设匹配的记录数太多。
使用
LIKE
运算符的时候,
"a%"
将会使用索引,而
"a%c"
"%c"
则会使用全表扫描,因
"a%c"
"%c"
不能被有效的评估匹配的数量。
14.事务
如果要执行一系列的操作,而这些操作最终是以整体的原子操作的形式完成的话,
事务就是必须的。关于事务的理论中,银行转账问题是最经典的例子:当把钱从一个银
行帐号转移至另外一个银行帐号的时候,这个操作要由两个步骤来完成,首先要将资金
从一个银行帐号取出,然后再将其存入另一个银行帐号。如果资金已经从一个银行帐号
取出了,在将资金存入另一个银行帐号之前或者进行当中发生异常情况
(
包括程序内部
异常、服务器当机、目标帐号被冻结
)
,如果没有事务保护就会出现源帐号中的资金已
经减少了,但是目标帐号中的资金并没有增加的状况。
事务是关键业务系统开发中非常关键性的服务,对于关键性业务系统如果没有采用事
务,那么这个系统可以说是不可用的。

转载于:https://www.cnblogs.com/byvar/p/4816880.html

你可能感兴趣的文章
三、activiti designer 的安装
查看>>
Python自省
查看>>
How to Choose the Best Way to Pass Multiple Models in ASP.NET MVC
查看>>
【算法】求二叉树各路径结点之和并找出最大值的路径
查看>>
c 字符串 函数
查看>>
12.5 站立会议
查看>>
SQLServer数据库的一些全局变量
查看>>
Centos-本机网络连接、运行端口和路由表等信息-netstat
查看>>
胡适阅读
查看>>
Java中日期的转化
查看>>
小程序弱网环境卡顿怎么办?一招迅速提升小程序运行速度
查看>>
管线【十八】
查看>>
重温设计模式 - 建造者模式
查看>>
Android开发 LevelListDrawable详解
查看>>
数组与字符串相互转换的方法总结
查看>>
Firefly安装说明 与 常见问题
查看>>
WP8:在Unity中使用OpenXLive
查看>>
Unity3d 接入 移动MM支付SDK(2.3) 全攻略
查看>>
ubuntu搭建svn服务器并htpp访问版本库并svn与web同步
查看>>
老系统如何引入更新的编码规范
查看>>