2017-02-10 18 views
2

シンプルなSQLクエリを最適化するのに問題がありますが、タイミングに重大な問題があります。私はそれを3回書いたが、どれも働いていない。最後にINNER JOINクエリ

SELECT RSKADDR.* 
FROM EDW_BASE.RCI_RISK_ADDRESS RSKADDR 
INNER JOIN (
    SELECT DISTINCT COVER_RISK_ID 
    FROM EDW_BASE.RCI_COVER_RISK_MASTER RSKMASTER 
    INNER JOIN 
    (SELECT DISTINCT CONTACT_ID, FOLLOW_UP_DATE 
    FROM EDW_STG.STG_CIM_SVOM03 
    WHERE OUTSTANDING = 1 AND QUEUE = 'CIM Update for Contact Address') ADDR_WF 
    ON RSKMASTER.CONTACT_CODE = ADDR_WF.CONTACT_ID 
    WHERE RSKMASTER.IS_STORNO != 1 
     AND RSKMASTER.PRODUCT_CODE = 'HOME' 
     AND ADDR_WF.FOLLOW_UP_DATE >= RSKMASTER.COVER_EFF_START_DATE 
     AND RSKMASTER.POLICY_STATUS_CODE = 'POLICY' 
     AND ADDR_WF.FOLLOW_UP_DATE <= RSKMASTER.COVER_EFF_END_DATE 
) ACTVRSK 
ON ACTVRSK.COVER_RISK_ID = RSKADDR.RISK_ID 

第一内のコードが参加した作品速いすべての方法:ここで私が動作するように期待していたオリジナルのものです。つまり、2番目のSELECTクエリ(最初とメインのSELECTクエリのINNER JOINクエリ内)は問題なく高速に動作します。問題は、メインのSELECTクエリのINNER JOIN内に2番目のSELECTクエリを統合するときに発生します(RSKADDR。*を選択します)。

実行が終了しないようです。

私は他の方法と同じ結果を試みた:

SELECT RSKADDR.* 
FROM EDW_BASE.RCI_RISK_ADDRESS RSKADDR 

INNER JOIN EDW_BASE.RCI_COVER_RISK_MASTER RSKMASTER 
ON RSKMASTER.COVER_RISK_ID = RSKADDR.RISK_ID 
    AND RSKMASTER.IS_STORNO != 1 
    AND RSKMASTER.PRODUCT_CODE = 'HOME' 
    AND RSKMASTER.POLICY_STATUS_CODE = 'POLICY' 

INNER JOIN EDW_STG.STG_CIM_SVOM03 ADDR_WF 
ON OUTSTANDING = 1 AND QUEUE = 'CIM Update for Contact Address' 
    AND RSKMASTER.CONTACT_CODE = ADDR_WF.CONTACT_ID 
    AND ADDR_WF.FOLLOW_UP_DATE >= RSKMASTER.COVER_EFF_START_DATE 
    AND ADDR_WF.FOLLOW_UP_DATE <= RSKMASTER.COVER_EFF_END_DATE 

それは不合理です。そのような簡単なクエリで、それを動作させることはできません。どんな助けでも大歓迎です。

+1

あなたのスキーマとデータを共有することができます –

+0

こんにちは、お返事ありがとうございます。残念ながら、個人情報が含まれるため、データを共有することはできません。あなたはそのスキームについて何を知りたいですか?スキーマ全体を共有することなく説明することができますか? – Ankhnesmerira

+0

サンプルデータとスキーマを正確には共有できません –

答えて

2

DISTINCTは、コストのかかる操作で、めったに必要ありません。多くの場合、データベースの設計が不良であるか、クエリが不適切であることを示します。あなたの質問では、これを繰り返しています。それは良く見えません。

2番目のクエリの方がはるかに優れています。同じ結果が得られたとすると、最初のクエリDISTINCTは明らかに余計なでした。

私はあなたがジョインをしているのを見ていますが、あなたが選択するものはすべて1つのテーブルのデータです。だからなぜそれに参加するのですか?あなたがデータを取得するテーブルから選択し、あなたの条件をWHEREに入れます。

次のクエリは、他のテーブルで一致するものが見つかったかどうかを単純に確認していることを明示的に示しているため、高速になる場合があります。しかし、その後、MySQLはIN句ではあまりうまく機能しないことで知られていました。そのため、使用しているバージョンによって異なる場合があります。 2番目のクエリまたは鉱山で、私は以下のインデックスが役立つだろうと仮定し

とにかく
select * 
from edw_base.rci_risk_address 
where risk_id in 
(
    select rm.cover_risk_id 
    from edw_base.rci_cover_risk_master rm 
    where rm.is_storno <> 1 
    and rm.product_code = 'HOME' 
    and rm.policy_status_code = 'POLICY' 
    and exists 
    (
     select * 
     from edw_stg.stg_cim_svom03 adr 
     where adr.contact_id  = rm.contact_code 
     and adr.follow_up_date >= rm.cover_eff_start_date 
     and adr.follow_up_date <= rm.cover_eff_end_date 
     and adr.outstanding = 1 
     and adr.queue = 'CIM Update for Contact Address' 
    ) 
); 

、:

create index idx1 on rci_cover_risk_master 
(
    product_code, 
    policy_status_code, 
    is_storno, 
    contact_code, 
    cover_eff_start_date, 
    cover_eff_end_date, 
    cover_risk_id 
); 

create index idx2 on stg_cim_svom03 
(
    contact_id, 
    follow_up_date, 
    outstanding, 
    queue 
); 

create index idx3 on rci_risk_address(risk_id); 
+0

ありがとうございました。あなたのコードははるかに理にかなっており、とても洗練されています。クエリが実行されるまでにはまだ時間がかかりますが、これはひどく設計されたスキーマによるものだと思います。私は一時的なテーブルを使用する必要があり、それを選択するのだろうか? – Ankhnesmerira

+0

インデックスが役に立たない? –

+0

残念ながら。 : – Ankhnesmerira

0

クエリから、あなただけのRSKADDRデータ、INNER JOINをのためにとても必要はありませんが必要です。 EXISTSというキーワードでも同じことができます。以下のクエリを試してください

SELECT RSKADDR.* 
FROM EDW_BASE.RCI_RISK_ADDRESS RSKADDR 
WHERE EXISTS (
    SELECT 1 
    FROM EDW_BASE.RCI_COVER_RISK_MASTER RSKMASTER 
    WHERE EXISTS 
    (SELECT 1 
    FROM EDW_STG.STG_CIM_SVOM03 
    WHERE OUTSTANDING = 1 AND QUEUE = 'CIM Update for Contact Address') ADDR_WF 
    AND RSKMASTER.CONTACT_CODE = ADDR_WF.CONTACT_ID 
    AND RSKMASTER.IS_STORNO != 1 
     AND RSKMASTER.PRODUCT_CODE = 'HOME' 
     AND ADDR_WF.FOLLOW_UP_DATE >= RSKMASTER.COVER_EFF_START_DATE 
     AND RSKMASTER.POLICY_STATUS_CODE = 'POLICY' 
     AND ADDR_WF.FOLLOW_UP_DATE <= RSKMASTER.COVER_EFF_END_DATE 
) 
AND RSKMASTER.COVER_RISK_ID = RSKADDR.RISK_ID 
) 

注:私はスキーマが利用できないため、クエリをテストしていません。

+0

構文ミスにはスキーマは必要ありません – Strawberry