2012-09-06 12 views
8

Oracle 11g'ye yükseltme yapıldıktan sonra bir Oracle sorgusunu optimize etmede sorun yaşıyorum ve bu sorun beni biraz çıldırtıyor.Dağıtılmış sorgularda bağlantı engelleme devre dışı mı?

Not: Bu soru, basit bir test vakası oluşturduktan sonra daha fazla bilgiye sahip olduğum için artık tamamen düzenlenmiştir. Orijinal soru şu adresten ulaşılabilir: https://stackoverflow.com/revisions/12304320/1.

Bu sorun, biri bir tarih sütununda bir between koşulu olan iki tabloya katıldığında, sorgu bir uzak tabloya katılırsa, bağlama gözetleme gerçekleşmeyeceğidir.

Sorunu yeniden oluşturmaya yardımcı olacak bir test vakası. İlk önce iki kaynak tablosu oluşturun. İlk tarihlerinin listesi, ayın ilk olma otuz yıl sonra

create table mike_temp_etl_control 
as 
select 
    add_months(trunc(sysdate, 'MM'), 1-row_count) as reporting_date 
from (
    select level as row_count 
    from dual 
    connect by level < 360 
); 

dba_objects kaynaklı bazı veriler geri dönüyor geçerli:

create table mike_temp_dba_objects as 
select owner, object_name, subobject_name, object_id, created 
from dba_objects 
union all 
select owner, object_name, subobject_name, object_id, created 
from dba_objects; 

Sonra verileri çalıştırmak için boş bir tablo oluşturmak Daha sonra kodu çalıştırın. Sorguyu yavaşlatmak için daha büyük bir sürüm mike_temp_dba_objects oluşturmanız gerekebilir (veya yürütme planını almak için başka bir yöntem kullanın). Sorgu çalışırken, oturumdan select * from table(dbms_xplan.display_cursor(sql_id => 'xxxxxxxxxxx'))'u farklı bir oturumdan çalıştırarak bir yürütme planı alıyorum. sorguda uzak bir tablo sahip olarak

declare 
    pv_report_start_date date := date '2002-01-01'; 
    v_report_end_date date := date '2012-07-01'; 

begin 

    INSERT /*+ APPEND */ 
    INTO mike_temp_5 
    select 
    a.OWNER, 
    a.OBJECT_NAME, 
    a.SUBOBJECT_NAME, 
    a.OBJECT_ID, 
    a.CREATED, 
    b.REPORTING_DATE 
from 
    mike_temp_dba_objects a 
    join mike_temp_etl_control b on (
    b.reporting_date between add_months(a.created, -24) and a.created) 
    cross join [email protected] -- This line causes problems... 
where 
    b.reporting_date between add_months(pv_report_start_date, -12) and v_report_end_date; 

    rollback; 
end; 

, mike_temp_etl_control tablo için önem tahmini tamamen yanlış ve bağlama Bakmak oluyor be görünmüyor.

yukarıdaki sorgu için yürütme planı aşağıda gösterilmiştir:

------------------------------------------------------------------------------------- 
| Id | Operation    | Name     | Rows | Bytes | Cost (%CPU)| 
------------------------------------------------------------------------------------- 
| 0 | INSERT STATEMENT  |      |  |  | 10682 (100)| 
| 1 | LOAD AS SELECT  |      |  |  |   | 
|* 2 | FILTER    |      |  |  |   | 
| 3 | MERGE JOIN   |      | 152K| 19M| 10682 (3)| 
| 4 |  SORT JOIN   |      | 438K| 51M| 10632 (2)| 
| 5 |  NESTED LOOPS  |      | 438K| 51M| 369 (20)| 
| 6 |  FAST DUAL  |      |  1 |  |  2 (0)| 
|* 7 |  TABLE ACCESS FULL| MIKE_TEMP_DBA_OBJECTS | 438K| 51M| 367 (20)| 
|* 8 |  FILTER    |      |  |  |   | 
|* 9 |  SORT JOIN   |      | 139 | 1251 |  3 (34)| 
|* 10 |  TABLE ACCESS FULL| MIKE_TEMP_ETL_CONTROL | 139 | 1251 |  2 (0)| 
------------------------------------------------------------------------------------- 
: Sonra yerel sürümü ile uzak dual değiştirin

--------------------------------------------------------------------------------------- 
| Id | Operation    | Name     | Rows | Bytes | Cost (%CPU)| 
--------------------------------------------------------------------------------------- 
| 0 | INSERT STATEMENT   |      |  |  | 373 (100)| 
| 1 | LOAD AS SELECT   |      |  |  |   | 
|* 2 | FILTER     |      |  |  |   | 
| 3 | MERGE JOIN   |      |  5 | 655 | 373 (21)| 
| 4 |  SORT JOIN   |      | 1096 | 130K| 370 (20)| 
| 5 |  MERGE JOIN CARTESIAN|      | 1096 | 130K| 369 (20)| 
| 6 |  REMOTE    | DUAL     |  1 |  |  2 (0)| 
| 7 |  BUFFER SORT  |      | 1096 | 130K| 367 (20)| 
|* 8 |  TABLE ACCESS FULL | MIKE_TEMP_DBA_OBJECTS | 1096 | 130K| 367 (20)| 
|* 9 |  FILTER    |      |  |  |   | 
|* 10 |  SORT JOIN   |      |  2 | 18 |  3 (34)| 
|* 11 |  TABLE ACCESS FULL | MIKE_TEMP_ETL_CONTROL |  2 | 18 |  2 (0)| 
--------------------------------------------------------------------------------------- 

I (139 yerine 2) doğru önem düzeyi elde

Öyleyse, sanırım soru tahmin edilebilecek doğru kardinalliği nasıl alabilirim? Bu bir Oracle hatası mı yoksa beklenen davranış mı?

+0

Kolayca kurtulmak için [istatistik] (http://docs.oracle.com/cd/E11882_01/server.112/e25494/general002.htm#ADMIN11525) tablosunda yeniden toplandınız mı? – Ben

+0

Evet, istatistiklerin hepsi taze olmalı. Yarın yine de kontrol edeceğim. Bir veri ambarı ETL yükünün bir parçası, istatistiklerin –

+0

olduğu gibi her şeyde toplanmasıyla birlikte, "_optim_peek_user_binds" parametresini false değerine ayarlayan bir çalışma çemberi olan 11.1 sürümlerinde bir hata olduğunu biliyorum. Bu optimize ediciyi etkileyebilir ama tam olarak nasıl olduğunu bilmiyorum. Bu parametrenin doğru veya yanlış olarak ayarlanıp ayarlanmadığını kontrol edebilirsiniz, maksimum performans için doğru olmalıdır. Bu hata ORA-3137 hatalarına neden olur. – Gisli

cevap

1

Bence dinamik örneklemeyi karıştırmalısın. 11g farklı çalışır, bu yüzden sorunlarınızın sebebi olabilir.