1

添付されているのは、前述の各テーブルの行数を示すために、各テーブルの横にコメントを付けてスキーマをレイアウトするフィドルです。フィドルがブロックされている場合、クエリは次のようになります。

select distinct cat_name,cat_age, co_cat_owners_id,cat_weight,cs_is_alive,os_is_current, cos_is_current,
      sum(cat_age) over(partition by co_cat_owners_id) running_total
from
   (
         select co.cat_owners_id co_cat_owners_id,
               co.cat_id co_cat_id,
               co.owner_id co_owner_id,
               co.vet_id co_vet_id, 
               cos.is_current cos_is_current,
               os.is_current os_is_current,
               cs.is_alive cs_is_alive,
               cat.name cat_name,
               cat.age cat_age,
               cat.weight cat_weight
         from cat_owners co,
              cat_owner_statuses cos,
              cat_statuses cs,
              cats cat,
              owners o,
              owner_statuses os
         where o.owner_id = co.owner_id
         and cat.cat_id = co.cat_id
         and cos.last_visit >= sysdate - 4/24
    )
where cs_is_alive = '1' 
and (cos_is_current = '1' OR os_is_current='1')
group by cat_name,cat_age,cat_weight,cs_is_alive,os_is_current,co_cat_owners_id,cos_is_current;

私の開発環境では、Explainプランは、ステップの観点から、フィドルの内部に非常に近いレイアウトになっていますが、メモリサイズが15E(exabytes)、行数が4000P(petabytes)のいくつかのステップがあります。私の質問は、インデックスの作成/ SQLの不良に沿って、はるかに少ないスペースと時間で解決できるはずの問題に対して、15エクサバイトのソリューションをどこで生成できたかということです。複合インデックスの作成手順の一部を微調整すると、わずかに異なる結果が得られることに気付きましたが、それでもエクサバイトのスペース要件によってブロックされています。

ノート

将来誰かがすべてのコメントを読まない場合は、次の関数を正しい結合と組み合わせて実行すると役立ちます。

analyze table table_name_here compute statistics;
4

3 に答える 3

3

クエリのFROM句には6つのテーブルがありますが、指定した結合条件は2つだけです。 OWNERS1000万行、CAT_OWNERS1億2000万行あるので、結合によって1億2000万行が生成されると思います。次に、CATS100万行あるに参加するので、この時点で1億2000万行あると仮定します。ただし、そこからは、参加条件はなくなります。したがって、1億2000万行の中間結果は、デカルト座標が5億行CAT_OWNER_STATUSESのテーブルに結合され、1億2000万* 5億行、つまり60兆行が生成されます。デカルト座標を1,000万行のテーブルに結合すると、CAT_STATUSES最終的に60兆* 1,000万行になり、最大6 * 10^23行になります。そして、デカルトは再びそれに参加しますOWNER_STATUSESこれには9千万行あり、5.4 * 10^31行になります。妥当な数の結果が必要な場合は、デカルト積を回避するために追加の結合条件を指定する必要があります。

残念ながら、テーブルを結合するための潜在的に矛盾する方法がいくつかあるように見えるため、フィドルのデータモデルを追跡するのは少し難しいです。 CAT_VETS猫を獣医にマッピングしますがCAT_OWNERS、たとえば、そうします。データと期待される結果がなければ、テーブルをどのように結合するかを推測するのは非常に困難です。私の推測では、あなたはこの修正されたフィドルのようなものが欲しいと思います

select distinct cat_name,cat_age, co_cat_owners_id,cat_weight,cs_is_alive,os_is_current, cos_is_current,
      sum(cat_age) over(partition by co_cat_owners_id) running_total
from
   (
         select co.cat_owners_id co_cat_owners_id,
               co.cat_id co_cat_id,
               co.owner_id co_owner_id,
               co.vet_id co_vet_id, 
               cos.is_current cos_is_current,
               os.is_current os_is_current,
               cs.is_alive cs_is_alive,
               cat.name cat_name,
               cat.age cat_age,
               cat.weight cat_weight
         from cat_owners co,
              cat_owner_statuses cos,
              cat_statuses cs,
              cats cat,
              owners o,
              owner_statuses os,
              cat_vets cv,
              owner_vets ov
         where o.owner_id = co.owner_id
         and cat.cat_id = co.cat_id
         and cos.cat_owners_id = co.cat_owners_id
         and cs.cat_vets_id = cv.cat_vets_id
         and os.owner_vets_id = ov.owner_vets_id
         and ov.owner_id = o.owner_id
         and co.vet_id = ov.vet_id
         and co.vet_id = cv.vet_id
         and cos.last_visit >= sysdate - 4/24
    )
where cs_is_alive = '1' 
and (cos_is_current = '1' OR os_is_current='1')
group by cat_name,cat_age,cat_weight,cs_is_alive,os_is_current,co_cat_owners_id,cos_is_current;
于 2012-11-20T18:34:41.520 に答える
2

結合構文を使用しないため、cat_statuses、cat_owner_statuses、およびowner_statusesの行を残りのテーブルのいずれかと結合するために見逃しました。これにより、これらの各テーブルと結合されたテーブルの間に相互結合が発生します。2つの「ステータス」テーブルにはいくつの行が含まれていますか?

各テーブルをコンマでリストするのではなく結合してから、whereを使用してフィルターで除外することを検討してください。SQLがコンマ区切りのテーブルをどのように処理するかわかりません(クロス結合の場合もあります)...

     from owners o,
          join cat_owners co on o.owner_id = co.owner_id
          join cats cat on cat.cat_id = co.cat_id
          join cat_owner_statuses cos on XXXXX
          join cat_statuses cs on XXXXX,
          join owner_statuses os on XXXXX
     where cos.last_visit >= sysdate - 4/24
于 2012-11-20T18:32:50.910 に答える
0

いくつかのテーブル(などcat_statuses)との関係がないため、製品結合は無数の行を返します。cat_vetsおそらく、Fiddleの例で指定されたテーブルを介して結合する必要があります。

少なくとも、外部where条件を派生テーブルクエリに移動する必要があります。外に置くのは非効率的です。

于 2012-11-20T18:33:00.497 に答える