oracle数据库sql优化
mysql相关sql优化
oracle执行顺序是自右向左 的,区别于mysql(自左向右)
1、选择最有效率的表名顺序
ORACLE的解析器按照从右到左 的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表 driving table)将被最先处理,在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表,即基础表在from最右边 。
如果有3个以上的表连接查询,那就需要选择交叉表(intersection table)作为基础表,交叉表是指那个被其他表所引用的表。
比如:
a_table 十万条数据
b_table 一条数据
c_table 交叉表
select x from a_table ,b_table;(高效)
select x from b_table ,a_table;(低效)
select x frin a_table,b_table,c_table(高效)
2、Where子句中的连接顺序
同样根据自右向左 执行原理where条件过滤数据最大的条件应写在where语句最右边。
3、**SELECT子句中避免使用 select * **
4、减少访问数据库的次数
当执行每条SQL语句时, ORACLE在内部执行了许多工作:解析SQL语句 > 估算索引的利用率 > 绑定变量 > 读数据块等等
由此可见, 减少访问数据库的次数 , 就能实际上减少ORACLE的工作量,如将数据放到redis缓存中。
5、通过内部函数提高SQL效率。
复杂的SQL往往牺牲了执行效率。能够掌握上面的运用函数解决问题的方法在实际工作中是非常有意义的。
6、计算记录条数
column是索引字段,若无索引,则count(1) 效率较高。
select count(column) from tablename;(高效)
select count(1) from tablename(低效)
7、用Where子句替换Having子句
where 和 having 的区别:where 后面不能使用组函数。
8、减少对表的查询操作
SELECT TAB_NAME FROM TABLES
WHERE (TAB_NAME,DB_VER)=(
SELECT TAB_NAME,DB_VER
FROM TAB_COLUMNS
WHERE VERSION = 604)
SELECT TAB_NAME FROM TABLES
WHERE TAB_NAME =(
SELECT TAB_NAME FROM TAB_COLUMNS
WHERE VERSION = 604)
AND DB_VER =(
SELECT DB_VER FROM TAB_COLUMNS
WHERE VERSION = 604)
9、使用表的别名(Alias)
10、用EXISTS替代IN,NOT EXISTS 代替 IN
select * from emp where aa in (1,2,3);
select * from emp where aa in (select aa from tableName)
优化方式:
11、用EXISTS替换DISTINCT
当提交一个包含对多表信息(比如部门表和雇员表)的查询时,避免在SELECT子句中使用DISTINCT。一般可以考虑用EXIST替换。
EXISTS 使查询更为迅速,因为RDBMS核心模块将在子查询的条件一旦满足后,立刻返回结果。
12、通过内部函数提高SQL效率。 复杂的SQL往往牺牲了执行效率。能够掌握上面的运用函数解决问题的方法在实际工作中是非常有意义的。
13、用索引提高效率。 索引是表的一个概念部分,用来提高检索数据的效率,ORACLE使用了一个复杂的自平衡B-tree结构。通常,通过索引查询数据比全表扫描要快。当ORACLE找出执行查询和Update语句的最佳路径时,ORACLE优化器将使用索引。 同样在联结多个表时使用索引也可以提高效率。另一个使用索引的好处是,它提供了主键(primarykey)的唯一性验证。那些LONG或LONG RAW数据类型,你可以索引几乎所有的列。通常,在大型表中使用索引特别有效。当然,你也会发现,在扫描小表时,使用索引同样能提高效率。 虽然使用索引能得到查询效率的提高,但是我们也必须注意到它的代价。索引需要空间来存储,也需要定期维护,每当有记录在表中增减或索引列被修改时,索引本身也会被修改。这意味着每条记录的INSERT、DELETE、UPDATE将为此多付出4、5次的磁盘I/O。因为索引需要额外的存储空间和处理,那些不必要的索引反而会使查询反应时间变慢。定期的重构索引是有必要的。
14、避免使用耗费资源的操作。
带有DISTINCT、UNION、MINUS、INTERSECT、ORDER BY 的SQL语句会启动SQL引擎执行耗费资源的排序(SORT)功能。DISTINCT需要一次排序操作,而其他的至少需要执行两次排序。
15、sql语句用大写的。 因为oracle总是先解析sql语句,把小写的字母转换成大写的再执行。
16、避免在索引列上使用NOT。 我们要避免在索引列上使用NOT,NOT会产生和在索引列上使用函数相同的影响。当ORACLE遇到NOT时,会停止使用索引转而执行全表扫描。
17、避免在索引列上使用计算。 WHERE子句中,如果索引列是函数的一部分。优化器将不使用索引而使用全表扫描。
select * from emp where salary > 12 * 5000;(高效)
select * from emp where salary/12 > 5000 (低效)
18、用>=替代>
|