Folge dem Video um zu sehen, wie unsere Website als Web-App auf dem Startbildschirm installiert werden kann.
Anmerkung: Diese Funktion ist in einigen Browsern möglicherweise nicht verfügbar.
Die werte in v$ sind alle kumulativ, d.h. Du musst die Gesamtdauer in den V$ Views durch die Anzahl der Ausführungen dividieren.
Ich verwende z.B. so eine Abfrage um die langsamsten Abfragen zu finden:
Code:select * from ( select (elapsed_time / 1000000) as "Total Seconds", (elapsed_time - cpu_time) / 1000000 as "Wait (s)", user_io_wait_time / 1000000 as "IO Waits (s)", (cpu_time / 1000000) as "CPU Seconds", disk_reads "Disk Reads", executions as "Executions", concurrency_wait_time / 1000000 as "Concurrency Wait (s)", buffer_gets as "Total Gets", rows_processed as "Total Rows", round(buffer_gets / nullif(rows_processed,0)) as "Gets/Row", round(buffer_gets / nullif(executions,0)) as "Gets/Exec", (elapsed_time/1000)/ nullif(executions,0) as "ms/exec", s.sql_id, s.child_number as child#, au.username as parsing_user, s.last_active_time, s.first_load_time, s.sql_fulltext from v$sql s join all_users au on au.user_id = s.parsing_user_id where au.username not in ('SYS', 'SYSTEM', 'SYSMAN', 'DBSNMP', 'EXFSYS') order by elapsed_time desc nulls last ) where rownum <= 100;
Jein, ist eher ein Insert. Das braucht normalerweise kaum Zeit. Kann natürlich sein, dass es so viele Inserts sind, dass es so lange dauert, aber der Verdacht ist da eher, dass irgendetwas gelockt ist. Du könntest Dir auch mal die Sperren anschauen, die auf den Tabellen liegen.
Select ap.POS_WERT_NETTO_NETTO * NVL(NVL(ap.TAGESKURS, ak.TAGESKURS),
1) Pos_Wert,
Decode(ap.POS_WERT_BRUTTO, 0, 0, ((1 - (ap.POS_WERT_NETTO_NETTO /
ap.POS_WERT_BRUTTO)) * 100)) rabatt,
ak.A_ART,
ak.A_STATUS || ' - ' || bez.bez_status(ak.A_STATUS) Status_aktuell,
ak.STATUS_RG || ' - ' || bez.bez_status(ak.STATUS_RG) Status_RG,
kfm_status.ermittle_status_kopf(i_a_art => a.A_ART, i_jahr => a.JAHR, i_anr =>
a.ANR, i_datum => :DATUM_2) || ' - ' ||
bez.bez_status(kfm_status.ermittle_status_kopf(i_a_art => a.A_ART, i_jahr =>
a.JAHR, i_anr => a.ANR, i_datum => :DATUM_2)) status_stichtag,
ak.PROJEKT_A_ART,
ak.PROJEKT_JAHR,
ak.PROJEKT_ANR,
ak.PROJEKT_INDEX,
ak.PROJEKT_STICHWORT,
ak.VERK_REGION,
a.KDNR,
g.NAME1 Kunde,
b.NAME Branche,
a.RENR,
ak.IHRZEICHEN,
a.PRODUKT_GR,
a.TEILENR,
a.GRNR,
ap.LIEFERTERMIN,
ak.UNSER_ZEICHEN,
ak.LANDCODE,
ak.AUFTRAG_DATUM,
NVL(ap.KOSTENST, pp.KOSTENST) As kostenst,
v.NAME1,
ak.JAHR,
ak.ANR,
ap.POSNR,
NVL(vertrieb.ermittle_durchschnittspreis(ap.SCHLUESSEL),
ap.POS_WERT_NETTO_NETTO * NVL(NVL(ap.TAGESKURS, ak.TAGESKURS),
1)) durchschnittspreis,
ap.BEZEICHNUNG,
p1.BEZEICHNUNG As BEZEICHNUNG1,
p2.BEZEICHNUNG As BEZEICHNUNG2,
ap.MENGE_BESTELLT,
z.SKONTO,
seriennummer.suche_snr('AUF_POS', ap.SCHLUESSEL, ',') Seriennummer,
Decode(ap.STATUS_LI, Null, 'offen', bez.bez_status(ap.STATUS_LI))
Lieferstatus,
Decode(ap.STATUS_RG, Null, 'offen', bez.bez_status(ap.STATUS_RG))
Rechnungsstatus,
(Select Max(x.LIEFERTERMIN) Lieferdatum From (Select ak.AUFTRAG_DATUM,
ak.A_STATUS,
ak.A_ART,
ak.LIEFERTERMIN
From AUF_KOPF ak
Connect By Prior ak.A_ART = ak.MUTTER_A_ART And Prior ak.JAHR =
ak.MUTTER_JAHR And Prior ak.ANR = ak.MUTTER_ANR
Start With ak.A_ART = a.A_ART And ak.JAHR = a.JAHR And ak.ANR = a.ANR) x
Where x.A_ART In ('LI') And
x.A_STATUS != 7300) Liefertermin_Lieferschein,
vk_auswertungen.rechnungsdatum_ermitteln(ak.A_ART, ak.JAHR, ak.ANR,
:DATUM_2) Rechnungsdatum,
(Select w.KZSTATUS || ' - ' || bez.bez_status(w.KZSTATUS) From WRKOR w
Where w.A_ART = a.A_ART And w.JAHR = a.JAHR And
w.ANR = To_Char(a.ANR)) Status_Technik,
vk_auswertungen.rechnungswert_auftrag(i_a_art => ak.A_ART, i_jahr =>
ak.JAHR, i_anr => ak.ANR, i_datum_bis => :DATUM_2, i_datum_von => Null,
i_firmenwaehrung_jn => 'J') Rechnungswert,
vk_auswertungen.rechnungs_nr_ermitteln(i_a_art => ak.A_ART, i_jahr =>
ak.JAHR, i_anr => ak.ANR, i_datum_bis => :DATUM_2, i_datum_von => Null,
i_rechnung_typ => Null) Rechnungsnummern,
NVL((Select Sum(ar.BETRAG) From AUF_RABATTE ar, RABATT_ARTEN ra
Where ar.TYP = ra.RABATT_TYP And ra.STAFFEL_RABATT = 'W' And ar.POSNR = -1 And
ap.A_ART = ar.A_ART And ap.JAHR = ar.JAHR And ap.ANR = ar.ANR),
0) Wertrabbatte,
NVL((Select Sum(az.BETRAG) From AUF_ZUSATZ az
Where az.POSNR = 0 And ap.A_ART = az.A_ART And ap.JAHR = az.JAHR And
ap.ANR = az.ANR), 0) Zusatzkosten,
(Select Sum(apos.POS_WERT_NETTO_NETTO * NVL(apos.TAGESKURS, 1))
From AUF_POS apos
Where apos.UNTER_POSNR = 0 And ap.A_ART = apos.A_ART And ap.JAHR = apos.JAHR
And ap.ANR = apos.ANR) Sum_Positionen,
(ap.POS_WERT_NETTO_NETTO * NVL(NVL(ap.TAGESKURS, ak.TAGESKURS), 1) /
Decode((Select Sum(apos.POS_WERT_NETTO_NETTO * NVL(apos.TAGESKURS, 1))
From AUF_POS apos
Where apos.UNTER_POSNR = 0 And ap.A_ART = apos.A_ART And ap.JAHR = apos.JAHR
And ap.ANR = apos.ANR), 0, 1, (Select Sum(apos.POS_WERT_NETTO_NETTO *
NVL(apos.TAGESKURS, 1)) From AUF_POS apos
Where apos.UNTER_POSNR = 0 And ap.A_ART = apos.A_ART And ap.JAHR = apos.JAHR
And ap.ANR = apos.ANR)) * NVL((Select Sum(ar.BETRAG)
From AUF_RABATTE ar, RABATT_ARTEN ra
Where ar.TYP = ra.RABATT_TYP And ra.STAFFEL_RABATT = 'W' And ar.POSNR = -1 And
ap.A_ART = ar.A_ART And ap.JAHR = ar.JAHR And ap.ANR = ar.ANR),
0)) Wertrabattanteil,
(ap.POS_WERT_NETTO_NETTO * NVL(NVL(ap.TAGESKURS, ak.TAGESKURS), 1) /
Decode((Select Sum(apos.POS_WERT_NETTO_NETTO * NVL(apos.TAGESKURS, 1))
From AUF_POS apos
Where apos.UNTER_POSNR = 0 And ap.A_ART = apos.A_ART And ap.JAHR = apos.JAHR
And ap.ANR = apos.ANR), 0, 1, (Select Sum(apos.POS_WERT_NETTO_NETTO *
NVL(apos.TAGESKURS, 1)) From AUF_POS apos
Where apos.UNTER_POSNR = 0 And ap.A_ART = apos.A_ART And ap.JAHR = apos.JAHR
And ap.ANR = apos.ANR)) * NVL((Select Sum(az.BETRAG) From AUF_ZUSATZ az
Where az.POSNR = 0 And ap.A_ART = az.A_ART And ap.JAHR = az.JAHR And
ap.ANR = az.ANR), 0)) Zusatzkostenanteil,
bi.bi_ermittle_vk_preis(i_a_art => ap.A_ART, i_jahr => ap.JAHR,
i_anr => ap.ANR, i_posnr => ap.POSNR, i_unter_posnr => ap.UNTER_POSNR,
i_tageskurs => NVL(ap.TAGESKURS, ak.TAGESKURS)) VK_Preis,
bi.bi_ermittle_vk_preis(i_a_art => ap.A_ART, i_jahr => ap.JAHR,
i_anr => ap.ANR, i_posnr => ap.POSNR, i_unter_posnr => ap.UNTER_POSNR,
i_tageskurs => NVL(ap.TAGESKURS, ak.TAGESKURS)) -
NVL(vertrieb.ermittle_durchschnittspreis(ap.SCHLUESSEL),
ap.POS_WERT_NETTO_NETTO * NVL(NVL(ap.TAGESKURS, ak.TAGESKURS),
1)) ZUSATZERLOESE
From VK_STATISTIK a,
AUF_KOPF ak,
AUF_POS ap,
KUNDLIEF g,
BRANCHE b,
PROJEKT_POS pp,
AUF_VERTRETER av,
VERTRETER v,
TEILE p,
PRODUKTGRUPPE p1,
PRODUKTGRUPPE p2,
AUF_ZAHLBED az,
ZAHLBED z
Where ak.A_ART(+) = a.A_ART And ak.JAHR(+) = a.JAHR And ak.ANR(+) = a.ANR And
ap.A_ART = a.A_ART And ap.JAHR = a.JAHR And ap.ANR = a.ANR And
ap.POSNR = a.POSNR And ap.UNTER_POSNR = a.UNTER_POSNR And g.KDNR(+) = a.KDNR
And g.KUNDLIEF_C1(+) = a.KUNDLIEF_C1 And b.BRANCHE(+) = g.BRANCHE And
ak.PROJEKT_A_ART = pp.A_ART(+) And ak.PROJEKT_JAHR = pp.JAHR(+) And
ak.PROJEKT_ANR = pp.ANR(+) And ak.PROJEKT_INDEX = pp.POS_INDEX(+) And
ak.PROJEKT_LFD_NR = pp.LFD_NR(+) And ak.A_ART = av.A_ART(+) And
ak.JAHR = av.JAHR(+) And ak.ANR = av.ANR(+) And av.VERTNR = v.VERTNR(+) And
ap.TEILENR = p.TEILENR And p.PRODUKT_GR = p1.PRODUKT_GR(+) And
p.PRODUKT_GR2 = p2.PRODUKT_GR(+) And ak.A_ART = az.A_ART(+) And
ak.JAHR = az.JAHR(+) And ak.ANR = az.ANR(+) And az.ZBED = z.ZBED(+) And
av.POSNR(+) = -1 And z.SPRACHE(+) = 'D' And a.LOGIN_USER = User
VK_STATISTIK_FUELLEN.fuellen_bi('AU',:DATUM_1,:DATUM_2);
SELECT plan_table_output
FROM dbms_xplan.display_cursor(sql_id => 'dhxdhu73b7bbk',
cursor_child_no => null,
format => 'ALIAS BYTES COST NOTE ROWS ALLSTATS PREDICATE'))
with fk_columns as (
select c.table_name,
cc.column_name,
cc.position as column_position,
c.constraint_name as constraint_name,
pk.table_name as target_table
from user_constraints c
join user_cons_columns cc ON c.constraint_name = cc.constraint_name
join user_constraints pk ON pk.constraint_name = c.r_constraint_name
where c.constraint_type = 'R'
), index_columns AS (
select i.table_name, ic.column_name, ic.column_position, i.index_name
from user_indexes i
join user_ind_columns ic ON i.index_name = ic.index_name
), missing_indexes AS (
select fk.table_name,
fk.column_name,
fk.column_position,
fk.constraint_name,
fk.target_table
from fk_columns fk
left join index_columns ic
on ic.table_name = fk.table_name
and ic.column_name = fk.column_name
and ic.column_position = fk.column_position
where ic.index_name is null
)
select table_name,
target_table as referenced_table,
'CREATE INDEX IX_'||substr(constraint_name,1,27)||' ON '||table_name||' ('||listagg(column_name, ',') within group (order by column_position)||');' as missing_index_definition,
'Changing data in '||target_table||' will lock table '||table_name as problem_description
from missing_indexes
group by table_name, target_table, constraint_name
order by table_name;
Alles in allem scheint mir da so viel im Argen zu liegen, dass ihr mit Hilfe aus einem Forum (von "Amateuren") nicht wirklich weiterkommen wirst. Das solltet ihr euch professionellen Support holen, der das vor Ort analysieren kann.
SELECT plan_table_output FROM dbms_xplan.display_cursor(sql_id => 'dhxdhu73b7bbk', cursor_child_no => null, format => 'ALIAS BYTES COST NOTE ROWS ALLSTATS PREDICATE'))
Die hohen Werte bei Concurrency Waits (b55awk..., bxxjc... oder 5w5n...) finde ich beunruhigend. Um das zu analysieren müsste man wissen, was das für Befehle sind. Sind das INSERTs, dann liegt das meistens daran, dass konkurrierende Transaktionen die gleichen Werte für einen primary (oder unique) key einfügen wollen.
Code:with fk_columns as ( select c.table_name, cc.column_name, cc.position as column_position, c.constraint_name as constraint_name, pk.table_name as target_table from user_constraints c join user_cons_columns cc ON c.constraint_name = cc.constraint_name join user_constraints pk ON pk.constraint_name = c.r_constraint_name where c.constraint_type = 'R' ), index_columns AS ( select i.table_name, ic.column_name, ic.column_position, i.index_name from user_indexes i join user_ind_columns ic ON i.index_name = ic.index_name ), missing_indexes AS ( select fk.table_name, fk.column_name, fk.column_position, fk.constraint_name, fk.target_table from fk_columns fk left join index_columns ic on ic.table_name = fk.table_name and ic.column_name = fk.column_name and ic.column_position = fk.column_position where ic.index_name is null ) select table_name, target_table as referenced_table, 'CREATE INDEX IX_'||substr(constraint_name,1,27)||' ON '||table_name||' ('||listagg(column_name, ',') within group (order by column_position)||');' as missing_index_definition, 'Changing data in '||target_table||' will lock table '||table_name as problem_description from missing_indexes group by table_name, target_table, constraint_name order by table_name;
Diese Abfrage basiert auf definierten FK
Die Definition von Schlüsselwerten, Primärschlüssel und Fremdschlüssel sind ein Hauptmerkmal relationaler Datenbanken. Sie bilden die Basis für ein Hauptleistungsmerkmal einer Datenbank, nämlich Datenkonsistenz.Was sind FK?
Das ersteHier mal 2 Ergebnisse:
ist der Aufruf einer Stored Procedure und relativ nichtssagend. In dieser SP kann ein oder dutzende Statements und wiederum Prozeduraufrufe erfolgen. Einige oder alle davon können besonders langsam sein. Hier muss man sich den Inhalt der Prozedur ansehen.MENUE.FUELLE_MENUE_WF
Hallo,Hallo zusammen,
ja, ich weiß, die Überschrift ist sehr allgemein gehalten. Also versuche ich mein Problem ein wenig genauer zu beschreiben.
Nach einem Wechsel einer ERP Software, die auf einer MS SQL basierte, haben wir zu einem ERP Programm auf Oracle SQL gewechselt.
Nun tauchen immer wieder Probleme auf, die mir unter MS SQL nicht bekannt waren. Da geht es z.B. um die allgemeine Performance.
Ja, ich kann nachvollziehen, daß sehr komplexe Abfragen auch seine Zeit dauern. Aber ist es normal, daß z.B. eine Abfrage mit Datensätzen 8 bis 15 Minuten dauert?
Manchmal kann es auch noch länger dauern. Hierbei geht es um Auswertungen für einen Zeitraum von einem Jahr. Möchte man z.B. einen Jahresvergleich von gewissen Umsätzen darstellen, ist das fast unmöglich.
Wie soll ich sowas der Geschäftsleitung erklären?
So kann man ehrlich gesagt nicht arbeiten.
Gibt es eine Möglichkeit, die Performance zu kontrollieren?
Hardwareseitig haben wir keine Probleme, da der Server ziemlich gut aufgestellt und neu ist. Genug RAM ist vorhanden und Festplatten sind alle SSD's.
Ja, der Lieferant wurde diesbezüglich schon kontaktiert. Bekomme aber nur Wischi Waschi Antworten.
Wenn jemand Tipps, Tricks oder Anregungen hat, bin ich für jeden Vorschlag dankbar.
Wie gesagt, daß ist hier allles sehr allgemein gehalten.
Falls Informationen fehlen sollten, kann ich diese gerne nachreichen.
Randnotiz: Ich bin kein Oracle SQL Profi!