Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql CTE与子查询,哪一个是有效的?_Sql_Database_Oracle - Fatal编程技术网

Sql CTE与子查询,哪一个是有效的?

Sql CTE与子查询,哪一个是有效的?,sql,database,oracle,Sql,Database,Oracle,这个查询对每一行执行子查询,对吗 现在如果我们有 SELECT col, (SELECT COUNT(*) FROM table) as total_count FROM table 第二种方法会更有效吗?CTE是否只执行一次COUNT(*),然后选择将其用作准备值?或者在第二种情况下,也为每一行执行COUNT(*)?我相信Oracle和SQL Server中的查询优化器都会识别出COUNT查询不相关,计算一次,然后在执行外部查询的整个过程中使用缓存的结果 而且,据我所知,CTE不会改变任何东

这个查询对每一行执行子查询,对吗

现在如果我们有

SELECT col, (SELECT COUNT(*) FROM table) as total_count FROM table

第二种方法会更有效吗?CTE是否只执行一次
COUNT(*)
,然后选择将其用作准备值?或者在第二种情况下,也为每一行执行
COUNT(*)

我相信Oracle和SQL Server中的查询优化器都会识别出COUNT查询不相关,计算一次,然后在执行外部查询的整个过程中使用缓存的结果

而且,据我所知,CTE不会改变任何东西,因为在执行时,它内部的代码基本上只是内联到实际的外部查询中


下面是一个针对Oracle的示例,其中提到非相关子查询将执行一次并缓存,除非外部查询只有几行。在这种情况下,它可能不会被缓存,因为多次执行count子查询不会造成太大的损失。

对于Oracle来说,最可靠的方法是使用扩展的统计信息观察语句的行为

首先将统计级别提高到
ALL

;WITH CTE(total_count) AS (
    SELECT COUNT(*) FROM table
)
SELECT col, (SELECT total_count FROM CTE) FROM table;
然后运行两条语句(获取所有行)和

最后使用以下语句显示统计信息(传递正确的SQL\u ID):

这是我的测试表

select * from table(dbms_xplan.display_cursor('your SQL_ID here',null,'ALLSTATS LAST'));

因此,计划略有不同,但在这两种情况下,
全表扫描
只启动一次(列开始=1)。这没什么区别

为了camparison的目的,我还运行了一个相关子查询,它提供了一个完全不同的图片,具有大量的启动(FTS)


您应该自己在数据上尝试,并告诉我们=)标记您正在使用的dbms。(不同的产品可能以不同的方式对此进行优化。)我基本上使用SQL Server或OracleSQL Server,Oracle以非常不同的方式优化CTE。答案可能因数据库而异。Gordon Linoff然后我选择Oracle)
select * from table(dbms_xplan.display_cursor('your SQL_ID here',null,'ALLSTATS LAST'));
SQL_ID  5n0sdcu8347j9, child number 0
-------------------------------------
SELECT    col, (SELECT COUNT(*) FROM t1) as total_count FROM t1

Plan hash value: 1306093980

-------------------------------------------------------------------------------------
| Id  | Operation          | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |      1 |        |   1000 |00:00:00.01 |     351 |
|   1 |  SORT AGGREGATE    |      |      1 |      1 |      1 |00:00:00.01 |     338 |
|   2 |   TABLE ACCESS FULL| T1   |      1 |   1061 |   1000 |00:00:00.01 |     338 |
|   3 |  TABLE ACCESS FULL | T1   |      1 |   1061 |   1000 |00:00:00.01 |     351 |
------------------------------------------------------------------------------------- 
SQL_ID  fs0h660f08bj6, child number 0
-------------------------------------
WITH CTE(total_count) AS (     SELECT   COUNT(*) FROM t1 ) SELECT col, 
(SELECT total_count FROM CTE) FROM t1

Plan hash value: 1223456497

--------------------------------------------------------------------------------------
| Id  | Operation           | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |      |      1 |        |   1000 |00:00:00.01 |     351 |
|   1 |  VIEW               |      |      1 |      1 |      1 |00:00:00.01 |     338 |
|   2 |   SORT AGGREGATE    |      |      1 |      1 |      1 |00:00:00.01 |     338 |
|   3 |    TABLE ACCESS FULL| T1   |      1 |   1061 |   1000 |00:00:00.01 |     338 |
|   4 |  TABLE ACCESS FULL  | T1   |      1 |   1061 |   1000 |00:00:00.01 |     351 |
--------------------------------------------------------------------------------------
SQL_ID  cbvwd6pm6699m, child number 0
-------------------------------------
SELECT col, (SELECT COUNT(*) FROM t1 where col = a.col) as total_count 
FROM t1 a

Plan hash value: 1306093980

-------------------------------------------------------------------------------------
| Id  | Operation          | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |      1 |        |   1000 |00:00:00.01 |     351 |
|   1 |  SORT AGGREGATE    |      |   1000 |      1 |   1000 |00:00:00.31 |     338K|
|*  2 |   TABLE ACCESS FULL| T1   |   1000 |     11 |   1000 |00:00:00.31 |     338K|
|   3 |  TABLE ACCESS FULL | T1   |      1 |   1061 |   1000 |00:00:00.01 |     351 |
-------------------------------------------------------------------------------------

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

   2 - filter("COL"=:B1)