2

私は、空間インデックス MY_IDX と約 22000 行を持つテーブル MY_TABLE を oracle に持っています。次のクエリは、約 500 ミリ秒未満で実行され、約 2600 の結果が返されます。

SELECT /*+ INDEX (MY_TABLE MY_IDX) */ ID,GEOM,LABEL FROM MY_TABLE
where (
 (sdo_filter(GEOM, mdsys.sdo_geometry(2003,8307,NULL,
  mdsys.sdo_elem_info_array(1,1003,3),
  mdsys.sdo_ordinate_array(-180.0,-48.0,-67.0,32.0)),
 'querytype=WINDOW')='TRUE')
);

別の空間フィルターを使用して「OR」句を追加すると、クエリの実行に約 30 秒かかり、必要以上に多くの CPU を消費します。

SELECT /*+ INDEX (MY_TABLE MY_IDX) */ ID,GEOM,LABEL FROM MY_TABLE
where (
 (sdo_filter(GEOM, mdsys.sdo_geometry(2003,8307,NULL,
  mdsys.sdo_elem_info_array(1,1003,3),
  mdsys.sdo_ordinate_array(-180.0,-48.0,-67.0,32.0)),
 'querytype=WINDOW')='TRUE')
 OR
 (sdo_filter(GEOM, mdsys.sdo_geometry(2003,8307,NULL,
  mdsys.sdo_elem_info_array(1,1003,3),
  mdsys.sdo_ordinate_array(157.0,-48.0,180.0,32.0)),
 'querytype=WINDOW')='TRUE')
);

クエリの実行計画は非常に異なります。最初のショーのテーブル アクセスは「BY INDEX ROWID」ですが、2 番目のショーは「FULL」です。最初のクエリと同様の方法で 2 番目のクエリを実行する方法はありますか?

v$version の戻り値:

Oracle Database 11g Release 11.2.0.1.0 - 64bit Production
PL/SQL Release 11.2.0.1.0 - Production
"CORE   11.2.0.1.0  Production"
TNS for 64-bit Windows: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production

ちなみに、Oracle Enterprise Edition を実行している別のデータベースは、インデックスが使用され、結果がマージされる計画を生成します。これは通常版でできますか?

4

3 に答える 3

3

内部クエリとユニオンを使用してクエリを屈折させると、オラクルは期待どおりにインデックスを使用するように強制されたようです。

SELECT ID,GEOM,LABEL FROM MY_TABLE
WHERE ID IN (
 (SELECT ID FROM MY_TABLE WHERE sdo_filter(GEOM, mdsys.sdo_geometry(2003,8307,NULL,
  mdsys.sdo_elem_info_array(1,1003,3),
  mdsys.sdo_ordinate_array(-180.0,-48.0,-67.0,32.0)),
 'querytype=WINDOW')='TRUE')
 UNION ALL
 (SELECT ID FROM MY_TABLE WHERE sdo_filter(GEOM, mdsys.sdo_geometry(2003,8307,NULL,
  mdsys.sdo_elem_info_array(1,1003,3),
  mdsys.sdo_ordinate_array(157.0,-48.0,180.0,32.0)),
 'querytype=WINDOW')='TRUE')
);
于 2014-06-25T14:00:17.947 に答える