Sql 为什么这个SELECT语句需要两个多小时?
我有两个表A和B。A有6760636条记录,B有452175960条记录。下面是我正在使用的SELECT语句:Sql 为什么这个SELECT语句需要两个多小时?,sql,oracle,performance,oracle11g,query-optimization,Sql,Oracle,Performance,Oracle11g,Query Optimization,我有两个表A和B。A有6760636条记录,B有452175960条记录。下面是我正在使用的SELECT语句: SELECT /*+ parallel (T,1) */ T.* FROM TABLE_A T, TABLE_B P WHERE T.DESTINATION = P.DESTINATION AND T.SAIL_DATE = P.SAIL_DATE AND T
SELECT /*+ parallel (T,1) */
T.*
FROM TABLE_A T,
TABLE_B P
WHERE T.DESTINATION = P.DESTINATION
AND T.SAIL_DATE = P.SAIL_DATE
AND T.PACKAGE_TYPE = P.PACKAGE_TYPE
AND T.CABIN_CATEGORY = P.CABIN_CATEGORY
AND T.BOOKING_SOURCE = P.BOOKING_SOURCE
AND T.FARE_TYPE = P.FARE_TYPE
AND T.POST_DATE = P.POST_DATE;
我尝试在表_A上创建索引,但它仍然没有考虑索引并进行完整的表扫描
上面的解释计划是
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| TQ |IN-OUT| PQ Distrib |
----------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 6760K| 1805M| 747K (1)| | | |
| 1 | SORT AGGREGATE | | 1 | 48 | | | | |
| 2 | TABLE ACCESS BY INDEX ROWID| CL_PRICING_CONTROLS | 1 | 48 | 2 (0)| | | |
| 3 | INDEX RANGE SCAN | CL_PRICING_CONTROLS_IX3 | 1 | | 1 (0)| | | |
| 4 | PX COORDINATOR | | | | | | | |
| 5 | PX SEND QC (RANDOM) | :TQ10002 | 6760K| 1805M| 747K (1)| Q1,02 | P->S | QC (RAND) |
| 6 | HASH JOIN | | 6760K| 1805M| 747K (1)| Q1,02 | PCWP | |
| 7 | PX RECEIVE | | 6760K| 1437M| 1443 (1)| Q1,02 | PCWP | |
| 8 | PX SEND HASH | :TQ10001 | 6760K| 1437M| 1443 (1)| Q1,01 | P->P | HASH |
| 9 | PX BLOCK ITERATOR | | 6760K| 1437M| 1443 (1)| Q1,01 | PCWC | |
| 10 | TABLE ACCESS FULL | TMP_RES_PRICE_CONTROL_111 | 6760K| 1437M| 1443 (1)| Q1,01 | PCWP | |
| 11 | BUFFER SORT | | | | | Q1,02 | PCWC | |
| 12 | PX RECEIVE | | 450M| 23G| 746K (1)| Q1,02 | PCWP | |
| 13 | PX SEND HASH | :TQ10000 | 450M| 23G| 746K (1)| | S->P | HASH |
| 14 | INDEX FULL SCAN | CL_PRICING_CONTROLS_IX1 | 450M| 23G| 746K (1)| | | |
我在两个表上尝试了并行查询,如下所示
SELECT /*+ PARALLEL(T, 32) PARALLEL(P, 32)*/
T.*
FROM TABLE_A T,
TABLE_B P
WHERE T.DESTINATION = P.DESTINATION
AND T.SAIL_DATE = P.SAIL_DATE
AND T.PACKAGE_TYPE = P.PACKAGE_TYPE
AND T.CABIN_CATEGORY = P.CABIN_CATEGORY
AND T.BOOKING_SOURCE = P.BOOKING_SOURCE
AND T.FARE_TYPE = P.FARE_TYPE
AND T.POST_DATE = P.POST_DATE;
但这导致了下面的解释计划,我看到CPU的成本较低,但仍然需要两个小时
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| TQ |IN-OUT| PQ Distrib |
----------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 6760K| 1805M| 59345 (1)| | | |
| 1 | SORT AGGREGATE | | 1 | 48 | | | | |
| 2 | TABLE ACCESS BY INDEX ROWID| CL_PRICING_CONTROLS | 1 | 48 | 2 (0)| | | |
| 3 | INDEX RANGE SCAN | CL_PRICING_CONTROLS_IX3 | 1 | | 1 (0)| | | |
| 4 | PX COORDINATOR | | | | | | | |
| 5 | PX SEND QC (RANDOM) | :TQ10002 | 6760K| 1805M| 59345 (1)| Q1,02 | P->S | QC (RAND) |
| 6 | HASH JOIN BUFFERED | | 6760K| 1805M| 59345 (1)| Q1,02 | PCWP | |
| 7 | PX RECEIVE | | 6760K| 1437M| 1443 (1)| Q1,02 | PCWP | |
| 8 | PX SEND HASH | :TQ10000 | 6760K| 1437M| 1443 (1)| Q1,00 | P->P | HASH |
| 9 | PX BLOCK ITERATOR | | 6760K| 1437M| 1443 (1)| Q1,00 | PCWC | |
| 10 | TABLE ACCESS FULL | TMP_RES_PRICE_CONTROL_111 | 6760K| 1437M| 1443 (1)| Q1,00 | PCWP | |
| 11 | PX RECEIVE | | 450M| 23G| 57858 (1)| Q1,02 | PCWP | |
| 12 | PX SEND HASH | :TQ10001 | 450M| 23G| 57858 (1)| Q1,01 | P->P | HASH |
| 13 | PX BLOCK ITERATOR | | 450M| 23G| 57858 (1)| Q1,01 | PCWC | |
| 14 | TABLE ACCESS FULL | CL_PRICING_CONTROLS | 450M| 23G| 57858 (1)| Q1,01 | PCWP | |
请查看您的查询,特别是其中的WHERE子句。它完全由连接条件组成。可以使用ANSI-92语法将其改写为:
SELECT /*+ parallel (T,1) */
T.*
FROM TABLE_A T
inner join TABLE_B P
on T.DESTINATION = P.DESTINATION
AND T.SAIL_DATE = P.SAIL_DATE
AND T.PACKAGE_TYPE = P.PACKAGE_TYPE
AND T.CABIN_CATEGORY = P.CABIN_CATEGORY
AND T.BOOKING_SOURCE = P.BOOKING_SOURCE
AND T.FARE_TYPE = P.FARE_TYPE
AND T.POST_DATE = P.POST_DATE;
因此,必须考虑每个表中的每一行。显然,全表扫描是唯一可行的访问路径
在JOIN子句中的所有列上构建复合索引不太可能改变这一点。您正在选择表_A中的所有列,因此数据库仍需要访问该表
除非两个表之间的交集中的记录数量非常少,否则在多块读取中读取表将比使用表行查找进行索引扫描更有效。事实上,在一个5亿行的表中,几乎每六行选择一行。一个索引如何使其更快
顺便问一下,您是如何决定并行度的?您的服务器有多少个CPU?还有哪些进程同时运行?最大并行服务器的价值是什么 你的问题是什么?当你问你的问题时,在文本区域右侧有一个大的橙色“如何设置格式”框,其中包含有用的信息。还有一个完整的格式化工具条。还有一个[?]按钮提供格式化帮助。还有一个预览区,位于文本区和“发布你的问题”按钮之间(这样你就必须扫描过去才能找到按钮),显示你的帖子发布时的样子。让你的帖子清晰明了,并证明你花了时间这样做,可以提高你获得好答案的机会。这些是
表格
还是视图
?尝试在表1(目的地、航行日期、包裹类型、客舱类别、预订来源、票价类型、邮寄日期)上创建综合索引在这两个表上,都有一个可能返回数十亿行的查询。对于这样一个查询,几个小时并不是一个过多的时间。我已经为表A添加了索引,并尝试了相同的方法,当观察到解释计划时,我可以看到索引没有被使用,我还为表A做了DBMS_STATS.GATHER_TABLE_STATS。但是除了@APC answer之外没有任何用处:解释计划估计查询将返回600万行。您只是在sqlplus中将这些行假脱机到屏幕上吗?如果是这样的话,这可能会主宰你的运行时间!否则,您将如何处理这些行。