Oracle11g 如何提高Oracle select性能?
下面的查询耗时超过1分钟,如何提高性能。两个表都在进行完全扫描。如何避免 查询计划:Oracle11g 如何提高Oracle select性能?,oracle11g,Oracle11g,下面的查询耗时超过1分钟,如何提高性能。两个表都在进行完全扫描。如何避免 查询计划: SELECT STATEMENT ALL_ROWSCost: 62 Bytes: 14,355 Cardinality: 45 3 HASH JOIN Cost: 62 Bytes: 14,355 Cardinality: 45 1 TABLE ACCESS FULL TABLE SYSADM.POSITIONS Cost: 9 Bytes: 52
SELECT STATEMENT ALL_ROWSCost: 62 Bytes: 14,355 Cardinality: 45
3 HASH JOIN Cost: 62 Bytes: 14,355 Cardinality: 45
1 TABLE ACCESS FULL TABLE SYSADM.POSITIONS Cost: 9 Bytes: 520 Cardinality: 4
2 TABLE ACCESS FULL TABLE SYSADM.PORTCONSUMPTION Cost: 52 Bytes: 797,202 Cardinality: 4,218
SELECT
a.Consumption AS Consumption ,
a.Cost AS Cost ,
a.CreatedBy AS CreatedBy ,
a.CreatedDate AS CreatedDate ,
a.UpdatedBy AS UpdatedBy ,
a.UpdatedDate AS UpdatedDate
FROM PortConsumption a
JOIN Positions b
ON a.PortRotationId = b.Id
WHERE b.VoyageId ='82A042031E1B4C38A9832A6678A695A4';
位置(*115970记录)*
端口消耗(*1291000记录)*
执行后
dbms_stats.gather_table_stats('SYSADM','POSITIONS')dbms_stats.gather_table_stats('SYSADM','PORTCONSUMPTION') 未进行完全扫描,但性能仍然相同,需要50秒 计划
您需要收集表上的统计数据,因为Oracle目前认为POSITIONS有4行,而不是115970行,PORTCONSUMPTION有4218行,而不是120万行,因此对这两行进行完整扫描是回答查询的最佳方式 此代码将使用默认设置收集2个表的统计信息:
begin
dbms_stats.gather_table_stats ('SYSADM', POSITIONS');
dbms_stats.gather_table_stats ('SYSADM', PORTCONSUMPTION ');
end;
有关如何收集统计信息的更多详细信息,请参阅。运行统计信息后,现在不会进行完全扫描,但仍需要相同的时间。好的,Oracle似乎认为VoyageId='82A042031E1B4C38A9832A6678A695A4'所在的位置行数大约为4。这是真实的还是遥远的?是的,你是对的,positions有5条记录用于VoyageId='82A042031E1B4C38A9832A6678A695A4'端口消耗表返回45条记录。那么统计数据似乎合理。我不知道为什么还需要50秒。谢谢tony,在关闭并重新连接到db后,现在速度很快。需要50毫秒。
Id - Primary key (indexed)
PortRotationId - indexed
SELECT STATEMENT ALL_ROWSCost: 20 Bytes: 16,536 Cardinality: 52
6 NESTED LOOPS
4 NESTED LOOPS Cost: 20 Bytes: 16,536 Cardinality: 52
2 TABLE ACCESS BY INDEX ROWID TABLE SYSADM.POSITIONS Cost: 5 Bytes: 520 Cardinality: 4
1 INDEX RANGE SCAN INDEX SYSADM.INX_POSITIONS_VOYAGEID Cost: 3 Cardinality: 4
3 INDEX RANGE SCAN INDEX SYSADM.INX_PORTCONS_PORTROTID Cost: 2 Cardinality: 12
5 TABLE ACCESS BY INDEX ROWID TABLE SYSADM.PORTCONSUMPTION Cost: 4 Bytes: 2,256 Cardinality: 12
begin
dbms_stats.gather_table_stats ('SYSADM', POSITIONS');
dbms_stats.gather_table_stats ('SYSADM', PORTCONSUMPTION ');
end;