OracleデータベースにUAVT_BINA
というテーブルがあり、28897352行あります。私が書くとき:
select * from UAVT_BINA
dBは0.1秒で応答します。しかし、私が書くとき
select * from UAVT_BINA order by CBSBMKODU
dBは66秒で応答します。 CSBMKODU
にインデックスがあります。アプリケーション標準のためにデータを並べ替える必要があります。パフォーマンスを向上させるにはどうすればよいですか?
これは、ソートされたクエリのプランの説明の結果です
前に、フレームワーク側で動的クエリを使用し、フィルタリングされたデータの単純な結果クエリがここにあると述べました
SELECT
"Project2"."C1" AS "C1",
"Project2"."CRTM" AS "CRTM",
"Project2"."ADANO" AS "ADANO",
"Project2"."BINADURUMSTRING" AS "BINADURUMSTRING",
"Project2"."C2" AS "C2",
"Project2"."BINANUMARATAJTIPISTRING" AS "BINANUMARATAJTIPISTRING",
"Project2"."BINAYAPITIPISTRING" AS "BINAYAPITIPISTRING",
"Project2"."BLOKADI" AS "BLOKADI",
"Project2"."CSBMADI" AS "CSBMADI",
"Project2"."C3" AS "C3",
"Project2"."DISKAPINO" AS "DISKAPINO",
"Project2"."C4" AS "C4",
"Project2"."C5" AS "C5",
"Project2"."C6" AS "C6",
"Project2"."NITELIKSTRING" AS "NITELIKSTRING",
"Project2"."C7" AS "C7",
"Project2"."PAFTANO" AS "PAFTANO",
"Project2"."PARSELNO" AS "PARSELNO",
"Project2"."POSTAKODU" AS "POSTAKODU",
"Project2"."SITEADI" AS "SITEADI",
"Project2"."C8" AS "C8",
"Project2"."C9" AS "C9",
"Project2"."UPTRID" AS "UPTRID",
"Project2"."UPTM" AS "UPTM",
"Project2"."STATESTRING" AS "STATESTRING",
"Project2"."STATEID" AS "STATEID",
"Project2"."CRTRID" AS "CRTRID",
"Project2"."MAHALLEADI" AS "MAHALLEADI",
"Project2"."BINADURUMID" AS "BINADURUMID",
"Project2"."BINANUMARATAJTIPIID" AS "BINANUMARATAJTIPIID",
"Project2"."BINAYAPITIPIID" AS "BINAYAPITIPIID",
"Project2"."MAHALLEID" AS "MAHALLEID"
FROM ( SELECT
"Distinct1"."DISKAPINO" AS "DISKAPINO",
"Distinct1"."SITEADI" AS "SITEADI",
"Distinct1"."BLOKADI" AS "BLOKADI",
"Distinct1"."POSTAKODU" AS "POSTAKODU",
"Distinct1"."CRTM" AS "CRTM",
"Distinct1"."CRTRID" AS "CRTRID",
"Distinct1"."UPTM" AS "UPTM",
"Distinct1"."UPTRID" AS "UPTRID",
"Distinct1"."STATEID" AS "STATEID",
"Distinct1"."STATESTRING" AS "STATESTRING",
"Distinct1"."ADANO" AS "ADANO",
"Distinct1"."PARSELNO" AS "PARSELNO",
"Distinct1"."PAFTANO" AS "PAFTANO",
"Distinct1"."BINADURUMSTRING" AS "BINADURUMSTRING",
"Distinct1"."BINADURUMID" AS "BINADURUMID",
"Distinct1"."BINAYAPITIPIID" AS "BINAYAPITIPIID",
"Distinct1"."BINAYAPITIPISTRING" AS "BINAYAPITIPISTRING",
"Distinct1"."BINANUMARATAJTIPIID" AS "BINANUMARATAJTIPIID",
"Distinct1"."BINANUMARATAJTIPISTRING" AS "BINANUMARATAJTIPISTRING",
"Distinct1"."NITELIKSTRING" AS "NITELIKSTRING",
"Distinct1"."CSBMADI" AS "CSBMADI",
"Distinct1"."MAHALLEID" AS "MAHALLEID",
"Distinct1"."MAHALLEADI" AS "MAHALLEADI",
1 AS "C1",
CAST( "Distinct1"."BINANO" AS number(19,0)) AS "C2",
CAST( "Distinct1"."CSBMID" AS number(19,0)) AS "C3",
CAST( "Distinct1"."ESKIBINAKIMLIKNO" AS number(19,0)) AS "C4",
CAST( "Distinct1"."ESKIBINAKODU" AS number(19,0)) AS "C5",
CAST( "Distinct1"."ID" AS number(19,0)) AS "C6",
CAST( "Distinct1"."NITELIKID" AS number(19,0)) AS "C7",
CAST( "Distinct1"."YOLALTIKATSAYISI" AS number(19,0)) AS "C8",
CAST( "Distinct1"."YOLUSTUKATSAYISI" AS number(19,0)) AS "C9"
FROM ( SELECT DISTINCT
"Extent1"."ID" AS "ID",
"Extent1"."DISKAPINO" AS "DISKAPINO",
"Extent1"."SITEADI" AS "SITEADI",
"Extent1"."BLOKADI" AS "BLOKADI",
"Extent1"."POSTAKODU" AS "POSTAKODU",
"Extent1"."ESKIBINAKODU" AS "ESKIBINAKODU",
"Extent1"."CRTM" AS "CRTM",
"Extent1"."CRTRID" AS "CRTRID",
"Extent1"."UPTM" AS "UPTM",
"Extent1"."UPTRID" AS "UPTRID",
"Extent1"."STATEID" AS "STATEID",
"Extent1"."NITELIKID" AS "NITELIKID",
"Extent1"."STATESTRING" AS "STATESTRING",
"Extent1"."CSBMID" AS "CSBMID",
"Extent1"."ADANO" AS "ADANO",
"Extent1"."PARSELNO" AS "PARSELNO",
"Extent1"."PAFTANO" AS "PAFTANO",
"Extent1"."BINANO" AS "BINANO",
"Extent1"."YOLALTIKATSAYISI" AS "YOLALTIKATSAYISI",
"Extent1"."YOLUSTUKATSAYISI" AS "YOLUSTUKATSAYISI",
"Extent1"."ESKIBINAKIMLIKNO" AS "ESKIBINAKIMLIKNO",
"Extent1"."BINADURUMSTRING" AS "BINADURUMSTRING",
"Extent1"."BINADURUMID" AS "BINADURUMID",
"Extent1"."BINAYAPITIPIID" AS "BINAYAPITIPIID",
"Extent1"."BINAYAPITIPISTRING" AS "BINAYAPITIPISTRING",
"Extent1"."BINANUMARATAJTIPIID" AS "BINANUMARATAJTIPIID",
"Extent1"."BINANUMARATAJTIPISTRING" AS "BINANUMARATAJTIPISTRING",
"Extent1"."NITELIKSTRING" AS "NITELIKSTRING",
"Extent1"."CSBMADI" AS "CSBMADI",
"Extent1"."MAHALLEID" AS "MAHALLEID",
"Extent1"."MAHALLEADI" AS "MAHALLEADI"
FROM (SELECT
"UAVT_BINA_EVW"."ID" AS "ID",
"UAVT_BINA_EVW"."DISKAPINO" AS "DISKAPINO",
"UAVT_BINA_EVW"."SITEADI" AS "SITEADI",
"UAVT_BINA_EVW"."BLOKADI" AS "BLOKADI",
"UAVT_BINA_EVW"."POSTAKODU" AS "POSTAKODU",
"UAVT_BINA_EVW"."ESKIBINAKODU" AS "ESKIBINAKODU",
"UAVT_BINA_EVW"."CRTM" AS "CRTM",
"UAVT_BINA_EVW"."CRTRID" AS "CRTRID",
"UAVT_BINA_EVW"."UPTM" AS "UPTM",
"UAVT_BINA_EVW"."UPTRID" AS "UPTRID",
"UAVT_BINA_EVW"."STATEID" AS "STATEID",
"UAVT_BINA_EVW"."NITELIKID" AS "NITELIKID",
"UAVT_BINA_EVW"."STATESTRING" AS "STATESTRING",
"UAVT_BINA_EVW"."CSBMID" AS "CSBMID",
"UAVT_BINA_EVW"."ADANO" AS "ADANO",
"UAVT_BINA_EVW"."PARSELNO" AS "PARSELNO",
"UAVT_BINA_EVW"."PAFTANO" AS "PAFTANO",
"UAVT_BINA_EVW"."BINANO" AS "BINANO",
"UAVT_BINA_EVW"."YOLALTIKATSAYISI" AS "YOLALTIKATSAYISI",
"UAVT_BINA_EVW"."YOLUSTUKATSAYISI" AS "YOLUSTUKATSAYISI",
"UAVT_BINA_EVW"."ESKIBINAKIMLIKNO" AS "ESKIBINAKIMLIKNO",
"UAVT_BINA_EVW"."BINADURUMSTRING" AS "BINADURUMSTRING",
"UAVT_BINA_EVW"."BINADURUMID" AS "BINADURUMID",
"UAVT_BINA_EVW"."BINAYAPITIPIID" AS "BINAYAPITIPIID",
"UAVT_BINA_EVW"."BINAYAPITIPISTRING" AS "BINAYAPITIPISTRING",
"UAVT_BINA_EVW"."BINANUMARATAJTIPIID" AS "BINANUMARATAJTIPIID",
"UAVT_BINA_EVW"."BINANUMARATAJTIPISTRING" AS "BINANUMARATAJTIPISTRING",
"UAVT_BINA_EVW"."NITELIKSTRING" AS "NITELIKSTRING",
"UAVT_BINA_EVW"."CSBMADI" AS "CSBMADI",
"UAVT_BINA_EVW"."MAHALLEID" AS "MAHALLEID",
"UAVT_BINA_EVW"."MAHALLEADI" AS "MAHALLEADI"
FROM "ATLAS"."UAVT_BINA_EVW" "UAVT_BINA_EVW") "Extent1"
INNER JOIN (SELECT
"BS_AUTHORIZEDREGION_EVW"."ID" AS "ID",
"BS_AUTHORIZEDREGION_EVW"."MAHALLEID" AS "MAHALLEID",
"BS_AUTHORIZEDREGION_EVW"."KOYID" AS "KOYID",
"BS_AUTHORIZEDREGION_EVW"."BUCAKID" AS "BUCAKID",
"BS_AUTHORIZEDREGION_EVW"."ILCEID" AS "ILCEID",
"BS_AUTHORIZEDREGION_EVW"."ROLEID" AS "ROLEID",
"BS_AUTHORIZEDREGION_EVW"."USERID" AS "USERID",
"BS_AUTHORIZEDREGION_EVW"."ILID" AS "ILID",
"BS_AUTHORIZEDREGION_EVW"."ATUHORIZEDREGIONTYPEID" AS "ATUHORIZEDREGIONTYPEID"
FROM "ATLAS"."BS_AUTHORIZEDREGION_EVW" "BS_AUTHORIZEDREGION_EVW") "Extent2" ON (("Extent1"."MAHALLEID" = "Extent2"."MAHALLEID") OR (("Extent1"."MAHALLEID" IS NULL) AND ("Extent2"."MAHALLEID" IS NULL))) AND ((:p__linq__0 = "Extent2"."USERID") OR ((:p__linq__0 IS NULL) AND ("Extent2"."USERID" IS NULL)))
) "Distinct1"
) "Project2"
ORDER BY "Project2"."CRTM" DESC
クエリはインデックスを使用していないようです。インデックスを使用する場合は、次のことを行う必要があります。
Select句に*
があるため、テーブル内のデータのこのルックアップが必要です。インデックスには行のすべてのデータが含まれていないと思います。したがって、1つの
select *
from BINA
order by CBSBMKODU
ステートメントを使用すると、インデックスを避けたほうが速くなりますが、テーブルからすべてのデータをフェッチして並べ替えることができます。すべてのデータをフェッチして並べ替えるには、66秒かかります。この後、最初のレコードをクライアントに送信できます。
とにかくあなたのデータベースにインデックスを使用するように説得することができます(私はそれらがうまくいくかどうかわかりません)
セッション/システム パラメーターOPTIMIZER_MODE を使用し、FIRST_ROWS
に設定します。次に、データベースは最初の行がフェッチされるまでの時間を最小限にしようとするため、インデックスを使用できます。
オプティマイザをインデックスに導くためのヒント を使用して、クエリを次のように変更します
select /*+ INDEX(BINA CBSBMKODU) */ *
from BINA
order by CBSBMKODU
または、データの構造を変更することもできます。
行のすべてのフィールドが含まれるようにインデックスCBSBMKODUを変更します。次に、データベースは行のすべての値をインデックスから取得でき、テーブルで検索する必要はありません。したがって、インデックスによるアクセスを使用する可能性があり、ダウはテーブルをスキャンしようとしません。このソリューションでは、テーブルの2つの完全なコピーを保存しています。1つはテーブル自体に、もう1つはインデックスCBSBMKODUに保存しています。
または、テーブルの構造を変更して、通常のヒープ構成テーブルの代わりに インデックス構成テーブル にすることもできます。次に、テーブルはすでにインデックスのように編成されており、データを2回保持する必要はありません。
しかし、これらすべてのソリューションはすべて、本当に満足できるものではありません。データベースに関してこれらの「アプリケーション標準」を確認する必要があります。明らかに、事前にソートされたデータの3000万行を返さない方が良いでしょう。
このクエリの本質を抽出しようとすると、次のクエリが得られます。
_SELECT Project2.*
FROM
(SELECT Distinct1.*
FROM
(SELECT DISTINCT Extent1.*
FROM (SELECT UAVT_BINA_EVW.* FROM ATLAS.UAVT_BINA_EVW UAVT_BINA_EVW) Extent1
INNER JOIN (SELECT BS_AUTHORIZEDREGION_EVW.* FROM ATLAS.BS_AUTHORIZEDREGION_EVW BS_AUTHORIZEDREGION_EVW) Extent2 ON
((Extent1.MAHALLEID = Extent2.MAHALLEID)
OR ((Extent1.MAHALLEID IS NULL) AND (Extent2.MAHALLEID IS NULL)))
AND ((:p__linq__0 = Extent2.USERID) OR ((:p__linq__0 IS NULL) AND (Extent2.USERID IS NULL)))
) Distinct1
) Project2
ORDER BY Project2.CRTM DESC;
_
これらすべてのサブクエリの理由はわかりません。私が間違っていなければ、これは
_SELECT DISTINCT ...
FROM ATLAS.UAVT_BINA_EVW UAVT_BINA_EVW Extent1
INNER JOIN ATLAS.BS_AUTHORIZEDREGION_EVW Extent2 ON
((Extent1.MAHALLEID = Extent2.MAHALLEID)
OR ((Extent1.MAHALLEID IS NULL) AND (Extent2.MAHALLEID IS NULL)))
AND ((:p__linq__0 = Extent2.USERID) OR ((:p__linq__0 IS NULL) AND (Extent2.USERID IS NULL)))
ORDER BY CRTM DESC;
_
INNER JOIN ... ON ((Extent1.MAHALLEID = Extent2.MAHALLEID) OR ((Extent1.MAHALLEID IS NULL) AND (Extent2.MAHALLEID IS NULL))
_FULL OUTER JOIN
_のように見えるので、最後にクエリを次のように減らすことができます。
_SELECT DISTINCT ...
FROM ATLAS.UAVT_BINA_EVW UAVT_BINA_EVW Extent1
FULL OUTER JOIN ATLAS.BS_AUTHORIZEDREGION_EVW Extent2 ON Extent1.MAHALLEID = Extent2.MAHALLEID
WHERE :p__linq__0 = Extent2.USERID OR (:p__linq__0 IS NULL AND Extent2.USERID IS NULL)
ORDER BY CRTM DESC;
_
ご覧のとおり、唯一の述語は_:p__linq__0 = Extent2.USERID
_にあります(通常、これは_Extent2.USERID = :p__linq__0
_と記述します-_ATLAS.BS_AUTHORIZEDREGION_EVW.USERID
_にインデックスがありますか?これはOracleが作成する唯一のインデックスですかもしれません使用。
DISTINCT
句のため、CRTMのインデックスは役に立たないと思います。これにより、Oracleは結果全体を読み取ってTEMPセグメントに入れ、ソートするよう強制されますが、ここではわかりません。