数据库哪种查询效率高?

时间:2021-11-16 07:58:23
数据库多表查询和嵌套查询哪个效率高?
今天老大看我写的SQL,让我不要用嵌套查询。
我认为嵌套查能更高效,老大说这样没效率,而且不好懂。

9 个解决方案

#1


什么事情都是具体问题具体分析的
物竞天择 如果能确定哪一种效率高 另一种方法就该被淘汰了
既然能够并存 就说明 存在的就是合理的

我的理解是 如果两个表是通过某一个主键或索引相关联,那么就可以用多表关联,这样可能比嵌套查询效率高,而且嵌套的话,sql看起来也不简洁明了

#2


子查询一般来说,效率要低一点,尽量少用,因为要不停的遍历结果集!

#3


多表连接,只需要构造一张复合表,嵌套查询的话基本上是遍历N张表,所以嵌套的效率和查询表的数量以及表中记录的数量有关,而多表关联最坏情况也就是输出N张表的笛卡尔乘积的记录.

#4


存在肯定是有存在的意义的,这些都要看应用的场合吧

#5


哦,不好意思,是我的概念错误了,不应该叫嵌套查询

我说的是这种情况,要不要把所有表都放在一个FROM里?
下面两种写法哪种好?


--1
select t1.*, t2.*, t3.*
from t1,t2,t3
where t1.c1 = t2.c1
      and t2.c2 = t3.c2;
--2
select t_a.*, t_3.*      
from     
     (select t1.* t2.*
      from t1, t2
      where t1.c1 = t2.c1) t_a
where t3.c2 = t_a.c2;

#6


第一种比较直观,,
第二种。。貌似写的不对吧。。

#7


--这两种的执行计划是一样的
select t.*,sg.*
from (select emp.empno,emp.sal,dept.deptno,dept.dname
from emp,dept
where emp.deptno=dept.deptno) t, salgrade sg
where t.sal=sg.sal

     EMPNO        SAL     DEPTNO DNAME                 SAL SALLEVEL
---------- ---------- ---------- -------------- ---------- ----------
      7369        800         20 RESEARCH              800 least
      7788       3000         20 RESEARCH             3000 middle
      7839       5000         10 ACCOUNTING           5000 high
      7902       3000         20 RESEARCH             3000 middle


Execution Plan
----------------------------------------------------------
Plan hash value: 802173295

----------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name                           | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                                |     4 |   176 |     8  (13)| 00:00:01 |
|   1 |  NESTED LOOPS                |                                |     4 |   176 |     8  (13)| 00:00:01 |
|*  2 |   HASH JOIN                  |                                |     4 |   124 |     7  (15)| 00:00:01 |
|   3 |    TABLE ACCESS FULL         | SALGRADE                       |     3 |    60 |     3   (0)| 00:00:01 |
|*  4 |    TABLE ACCESS FULL         | EMP                            |    14 |   154 |     3   (0)| 00:00:01 |
|   5 |   TABLE ACCESS BY INDEX ROWID| DEPT                           |     1 |    13 |     1   (0)| 00:00:01 |
|*  6 |    INDEX UNIQUE SCAN         | BIN$8mPMMewIQa6BxCHkeZP6Wg==$0 |     1 |       |     0   (0)| 00:0
----------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("EMP"."SAL"="SALGRADE"."SAL")
   4 - filter("EMP"."SAL" IS NOT NULL)
   6 - access("EMP"."DEPTNO"="DEPT"."DEPTNO")

Note
-----
   - dynamic sampling used for this statement

 select emp.empno,emp.sal,dept.deptno,dept.dname,salgrade.sal,salgrade.sallevel
 from emp,dept,salgrade
 where emp.deptno=dept.deptno and emp.sal=salgrade.sal

     EMPNO        SAL     DEPTNO DNAME                 SAL SALLEVEL
---------- ---------- ---------- -------------- ---------- ----------
      7369        800         20 RESEARCH              800 least
      7788       3000         20 RESEARCH             3000 middle
      7839       5000         10 ACCOUNTING           5000 high
      7902       3000         20 RESEARCH             3000 middle


Execution Plan
----------------------------------------------------------
Plan hash value: 802173295

----------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name                           | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                                |     4 |   176 |     8  (13)| 00:00:01 |
|   1 |  NESTED LOOPS                |                                |     4 |   176 |     8  (13)| 00:00:01 |
|*  2 |   HASH JOIN                  |                                |     4 |   124 |     7  (15)| 00:00:01 |
|   3 |    TABLE ACCESS FULL         | SALGRADE                       |     3 |    60 |     3   (0)| 00:00:01 |
|*  4 |    TABLE ACCESS FULL         | EMP                            |    14 |   154 |     3   (0)| 00:00:01 |
|   5 |   TABLE ACCESS BY INDEX ROWID| DEPT                           |     1 |    13 |     1   (0)| 00:00:01 |
|*  6 |    INDEX UNIQUE SCAN         | BIN$8mPMMewIQa6BxCHkeZP6Wg==$0 |     1 |       |     0   (0)| 00:0
----------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("EMP"."SAL"="SALGRADE"."SAL")
   4 - filter("EMP"."SAL" IS NOT NULL)
   6 - access("EMP"."DEPTNO"="DEPT"."DEPTNO")

Note
-----
   - dynamic sampling used for this statement

#8


看情况吧,如果子查询能够滤除绝大部分记录,仅选出几条数据,效率并不是问题.

#9


引用 6 楼 changhe325 的回复:
第一种比较直观,,
第二种。。貌似写的不对吧。。

少打个t3

#1


什么事情都是具体问题具体分析的
物竞天择 如果能确定哪一种效率高 另一种方法就该被淘汰了
既然能够并存 就说明 存在的就是合理的

我的理解是 如果两个表是通过某一个主键或索引相关联,那么就可以用多表关联,这样可能比嵌套查询效率高,而且嵌套的话,sql看起来也不简洁明了

#2


子查询一般来说,效率要低一点,尽量少用,因为要不停的遍历结果集!

#3


多表连接,只需要构造一张复合表,嵌套查询的话基本上是遍历N张表,所以嵌套的效率和查询表的数量以及表中记录的数量有关,而多表关联最坏情况也就是输出N张表的笛卡尔乘积的记录.

#4


存在肯定是有存在的意义的,这些都要看应用的场合吧

#5


哦,不好意思,是我的概念错误了,不应该叫嵌套查询

我说的是这种情况,要不要把所有表都放在一个FROM里?
下面两种写法哪种好?


--1
select t1.*, t2.*, t3.*
from t1,t2,t3
where t1.c1 = t2.c1
      and t2.c2 = t3.c2;
--2
select t_a.*, t_3.*      
from     
     (select t1.* t2.*
      from t1, t2
      where t1.c1 = t2.c1) t_a
where t3.c2 = t_a.c2;

#6


第一种比较直观,,
第二种。。貌似写的不对吧。。

#7


--这两种的执行计划是一样的
select t.*,sg.*
from (select emp.empno,emp.sal,dept.deptno,dept.dname
from emp,dept
where emp.deptno=dept.deptno) t, salgrade sg
where t.sal=sg.sal

     EMPNO        SAL     DEPTNO DNAME                 SAL SALLEVEL
---------- ---------- ---------- -------------- ---------- ----------
      7369        800         20 RESEARCH              800 least
      7788       3000         20 RESEARCH             3000 middle
      7839       5000         10 ACCOUNTING           5000 high
      7902       3000         20 RESEARCH             3000 middle


Execution Plan
----------------------------------------------------------
Plan hash value: 802173295

----------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name                           | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                                |     4 |   176 |     8  (13)| 00:00:01 |
|   1 |  NESTED LOOPS                |                                |     4 |   176 |     8  (13)| 00:00:01 |
|*  2 |   HASH JOIN                  |                                |     4 |   124 |     7  (15)| 00:00:01 |
|   3 |    TABLE ACCESS FULL         | SALGRADE                       |     3 |    60 |     3   (0)| 00:00:01 |
|*  4 |    TABLE ACCESS FULL         | EMP                            |    14 |   154 |     3   (0)| 00:00:01 |
|   5 |   TABLE ACCESS BY INDEX ROWID| DEPT                           |     1 |    13 |     1   (0)| 00:00:01 |
|*  6 |    INDEX UNIQUE SCAN         | BIN$8mPMMewIQa6BxCHkeZP6Wg==$0 |     1 |       |     0   (0)| 00:0
----------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("EMP"."SAL"="SALGRADE"."SAL")
   4 - filter("EMP"."SAL" IS NOT NULL)
   6 - access("EMP"."DEPTNO"="DEPT"."DEPTNO")

Note
-----
   - dynamic sampling used for this statement

 select emp.empno,emp.sal,dept.deptno,dept.dname,salgrade.sal,salgrade.sallevel
 from emp,dept,salgrade
 where emp.deptno=dept.deptno and emp.sal=salgrade.sal

     EMPNO        SAL     DEPTNO DNAME                 SAL SALLEVEL
---------- ---------- ---------- -------------- ---------- ----------
      7369        800         20 RESEARCH              800 least
      7788       3000         20 RESEARCH             3000 middle
      7839       5000         10 ACCOUNTING           5000 high
      7902       3000         20 RESEARCH             3000 middle


Execution Plan
----------------------------------------------------------
Plan hash value: 802173295

----------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name                           | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                                |     4 |   176 |     8  (13)| 00:00:01 |
|   1 |  NESTED LOOPS                |                                |     4 |   176 |     8  (13)| 00:00:01 |
|*  2 |   HASH JOIN                  |                                |     4 |   124 |     7  (15)| 00:00:01 |
|   3 |    TABLE ACCESS FULL         | SALGRADE                       |     3 |    60 |     3   (0)| 00:00:01 |
|*  4 |    TABLE ACCESS FULL         | EMP                            |    14 |   154 |     3   (0)| 00:00:01 |
|   5 |   TABLE ACCESS BY INDEX ROWID| DEPT                           |     1 |    13 |     1   (0)| 00:00:01 |
|*  6 |    INDEX UNIQUE SCAN         | BIN$8mPMMewIQa6BxCHkeZP6Wg==$0 |     1 |       |     0   (0)| 00:0
----------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("EMP"."SAL"="SALGRADE"."SAL")
   4 - filter("EMP"."SAL" IS NOT NULL)
   6 - access("EMP"."DEPTNO"="DEPT"."DEPTNO")

Note
-----
   - dynamic sampling used for this statement

#8


看情况吧,如果子查询能够滤除绝大部分记录,仅选出几条数据,效率并不是问题.

#9


引用 6 楼 changhe325 的回复:
第一种比较直观,,
第二种。。貌似写的不对吧。。

少打个t3