按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
在查询中各个元素的布局
在你的查询中最好的元素布局 尤其是在 WHERE 子句中 是根据解释器处理 SQL 语
句的步骤和次序而定的 在条件中安排被索引过的列 这样的条件将会查找最少的记录
你不一定非要在 WHERE 子句中使用已经被索引过的列 但是显然这样做会更有效
试着调整 SQL 语句以使它返回的记录数最少 在一个表中返回记录数最少的条件就是最大
的限制条件 在通常的语句中 你应该把最大的条件限制语句放在 WHERE 子句的最后
ORACLE 查询优化会对 WHERE 子句从后向前读 所以它会最先处理我们放置的条件语
句
当优化器首先读到最大条件限制语句以后 它就将为以后的条件所提供的结果集缩减
至最小了 下一个条件将不再搜索整个表 而是搜索经过最大条件限制过的子集 所以
数据的返回就会更快 在复杂查询中的多个查询 子查询 计算以及使用逻辑条件 AND
OR NOT 中最大限制条件可能并不清晰
311
…………………………………………………………Page 312……………………………………………………………
SQL 21 日自学通(V1。0) 翻译人 笨猪
技巧 请查看你的数据库文档资料 看一看解释器是如何处理你的 SQL 语句的
下边的测试是我们对用两种不同的方法来查询相同的内容所耗用时间的差异 该例子
使用 ORACLE 7 关系数据库系统 切记 在解释器中的优化是从后向前进行的
在创造一个 SELECT 语句之前 对于每一个条件我们都选择了独立的行 下边是不同
的条件给出的数值
Condition Distinct Values
calc_ytd = '…2109490。8' 13;000 +
dt_stmp = '01…SEP…96' 15
output_cd = '001' 13
activity_cd = 'IN' 10
status_cd = 'A' 4
function_cd = '060' 6
注 最大限制条件就是最显著的值
下边的例子中在 WHERE 子句中使用了最大限制条件放在最前
INPUT
SQL》 SET TIMING ON
2 SELECT COUNT(*)
3 FROM FACT_TABLE
4 WHERE CALC_YTD = '…2109490。8'
5 AND DT_STMP = '01…SEP…96'
6 AND OUTPUT_CD = '001'
7 AND ACTIVITY_CD = 'IN'
8 AND STATUS_CD = 'A'
9 AND FUNCTION_CD = '060';
OUTPUT
COUNT(*)
8
1 row selected。
Elapsed: 00:00:15。37
INPUT/OUTPUT
312
…………………………………………………………Page 313……………………………………………………………
SQL 21 日自学通(V1。0) 翻译人 笨猪
SQL》 SET TIMING ON
2 SELECT COUNT(*)
3 FROM FACT_TABLE
4 WHERE FUNCTION_CD = '060'
5 AND STATUS_CD = 'A'
6 AND ACTIVITY_CD = 'IN'
7 AND OUTPUT_CD = '001'
8 AND DT_STMP = '01…SEP…96'
9 AND CALC_YTD = '…2109490。8';
OUTPUT
COUNT(*)
8
1 row selected。
Elapsed: 00:00:01。80
分析
注意所使用的时间的不同 只要简单地改变所给出的统计的次序 第二个查询比第一
个查询快了 14 秒 那么可以设想一下当查询的结构设计不好的时候耗用几个小时的情形
过程
如果所使用的查询有规律可循 那么你可以试着使用过程 过程可以调用很大的一组
SQL 的语句 参见第 13 天 高级 SQL 主题
过程是被数据库的引擎编译后运行的 与 SQL 语句不同 数据库引擎在执行过程的时
候不需要进行优化 过程相对于独立的多个 SQL 语句 它对于用户来说更容易使用而对于
数据库来说更为有效
避免使用 OR
如果可能的话应该在查询尽量避免使用逻辑操作符 OR OR 会不可避免的根据表的大
小降低查询的速度 我们发现 IN 通常比 OR 要快 当然 优化器的文档中并不是这样说的
可是 下边的例子中使用了多个 OR
313
…………………………………………………………Page 314……………………………………………………………
SQL 21 日自学通(V1。0) 翻译人 笨猪
INPUT
SQL》 SELECT *
2 FROM FACT_TABLE
3 WHERE STATUS_CD = 'A'
4 OR STATUS_CD = 'B'
5 OR STATUS_CD = 'C'
6 OR STATUS_CD = 'D'
7 OR STATUS_CD = 'E'
8 OR STATUS_CD = 'F'
9 ORDER BY STATUS_CD;
下边是使用子串和 IN 写成的相同的查询
INPUT
SQL》 SELECT *
2 FROM FACT_TABLE
3 WHERE STATUS_CD IN ('A';'B';'C';'D';'E';'F')
4 ORDER BY STATUS_CD;
分析
你可以自己进行一些类似的测试 尽管书中的代码是最为标准和直接的 但是你会发
现你经常可以得到你自己的结论 特别是在性能方面
下边是使用子串和 IN 的又一个例子 注意 第一个查询结合使用了 LIKE 和 OR
INPUT
SQL》 SELECT *
2 FROM FACT_TABLE
3 WHERE PROD_CD LIKE 'AB%'
4 OR PROD_CD LIKE 'AC%'
5 OR PROD_CD LIKE 'BB%'
6 OR PROD_CD LIKE 'BC%'
7 OR PROD_CD LIKE 'CC%'
8 ORDER BY PROD_CD;
314
…………………………………………………………Page 315……………………………………………………………
SQL 21 日自学通(V1。0) 翻译人 笨猪
SQL》 SELECT *
2 FROM FACT_TABLE
3 WHERE SUBSTR(PROD_CD;1;2) IN ('AB';'AC';'BB';'BC';'CC')
4 ORDER BY PROD_CD;
第二个例子不仅避免的使用 OR 而且也避免了使用 LIKE 与 OR 的联合操作 你可以
试一下这个例子 你会看到对于你的数据它们在实际运行时性能上的不同
OLAP 与 OLTP 的比较
当你在调试一个数据库的时候 你首先要决定的是它应该经常由谁来使用 在线的分
析处理 OLAP 的数据库是一个对最终用户的查询进行统计和汇总的系统 在这种环境
下返回的数据经常用与统计报告给决策管理过程提供帮助 而在线事务过程 OLTP 的数
据库则是一个将主要的功能提供给为最终用户输入服务的环境的系统 包括用户日复一日
的查询 OLTP 系统经常用在以日为基本单位在数据库中操作数据的使用场合 数据仓库
与 DSS 可以从在线的事务处理数据库中得到它们所需的数据 有时也可以从其它的 OLAP
数据库中得到数据
OLTP 的调试
一个事务处理数据库是一个精密的系统 它的访问任务是由繁重的按日而定的大量的
事务与查询组成 但是 OLTP 通常不需要巨大的分类区域 至少它的需要没有 OLAP 的
那么大 大多数 OLTP 的反应很迅速但是不会进行分类
在事务处理数据库中最明显的例子就是 ROLLBACK 语句 需要撤消的内容的量与尺
寸是与当前有多少用户在访问数据库相关的 与在每一个事务中进行的工作一样 最好的
办法是在一个事务处理的环境中有多个 ROLLBACK 命令
在事务处理环境中另一个涉及的问题是事务历史记录的完整性 它在每一个事务结束
后都会写出 LOGS 是为恢复的目的而存在的 所以 每一种 SQL 解释器都需要有一种方
法来对 LOGS 进行备份以用于 恢复点 SQL SERVER 使用的是 DUMP DEVICE ORACLE
则使用一种被称为 ARCHIVELOG 模式的数据库 事务记录也会涉及到性能 因为对记录
的备份是额外的负荷