Announcement

Collapse
No announcement yet.

Randomisierte daten ein schleife einfügen?

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Randomisierte daten ein schleife einfügen?

    Hi,

    Ich bin grad dabei dummy daaten in eine Datenbank ein zu üfgen. Normal mache ich das so - in einem sql script und dann über sqlplus rufe ich es auf und übergebe die parameter für 1,2,3. Wobei die anzahl über den ersten Parameter gesteuert wird ("loop")

    Code:
    INSERT INTO TableXY (A, TMSTAMP,B,REC_ID_A,REC_ID_B)
        WITH GUIDS AS
          (select
            sys_guid() RECID1_VAL,
            sys_guid() RECID2_VAL
            from dual
            connect by level <= &1
          )
        SELECT
              'Hallo DB',
              TO_TIMESTAMP('&3'),
              'HUHU &2',
              '<REC_ID_A>'||G.RECID1_VAL||'</REC_ID_A>',
              '<REC_ID_B>'||G.RECID2_VAL||'</REC_ID_B>'
        FROM GUIDS G;
    
    COMMIT;
    Diesmal habe ich folgende Statements:
    Code:
    Insert into TABLE1 (A,B,C,D,E)
    values (
    '<Random String X one out of 5>' ,
    <Random Date & Time in Past (Date Format)>   ,
    to_date('2018-12-06 23:59:59','yyyy-MM-DD HH24:MI:SS')   ,
    <I>   ,
    '<Random String Y one out of 15>');  
    
    Insert into TABLE2 (A,B,C,D,E,F,G,H,I)
    values (
    '<Random String V one out of 15>' ,
    '<Random String V one out of 15>' ,
    <Random INT A1 one out of 5>   ,
    <Random INT A2 one out of 5>   ,
    sys_guid()   ,
    <Random INT B1 one out of 5>   ,
    <Random INT B2 one out of 5>   ,
    'REASON' ,<I>);
    Dabei muss ich in zwei verschiedene Tabellen einfügen, die jeweils über den <I> (eine ID) wert verknüpft sind.
    Die anderen Probleme Reduzieren sich darauf, dass cih entweder einen String oder einen Int wert aus einer gruppe von werten randomisiert wählen will + ein DateTime aus der vergangenheit.

    Wie sollte ich das in ein sqlplus script einbauen um wie bei meinem Alten script die Anzahl der Insert vorgänge vor zu geben - was ist da die richtige herangehens weiße?



  • #2
    Der Text ist schwer verständlich (Rechtschreibung), die Beispiele passen nicht zur Frage (welche/ wo sind die FK, wo ist die Schleife).
    Was genau ist die Frage?

    Augenscheinlich handelt es sich um Oracle -> verschoben

    Pseudocode:
    - Schleifenstart über die Anzahl der gewünschten Insertvorgänge
    - Tabelle 1 mit Zufallsdaten füllen (ID merken)
    - Tabelle 2 mit der ID aus Tabelle 1 und den Zufallsdaten füllen
    - Schleifenende
    oder
    - Schleifenstart über die Anzahl der gewünschten Insertvorgänge
    - Tabelle 1 mit Zufallsdaten füllen
    - Schleifenende
    - Schleife über alle Ids der Tabelle 1 gehen und in Tabelle 2 mit dieser ID Zufallsdaten erzeugen.

    Code:
          FOR aktZeile IN (
                SELECT
                       TB1.ID
                FROM TABELLE1 TB1
            ) LOOP
    insert into TABELLE2 (id,..)values(aktZeile.id,...
    END LOOP
    Christian

    Comment


    • #3
      Hi,

      Sollte nicht um die Urzeit versuchen zu denken.
      Habe jetzt mein Skript mal detaillierter erstellt (PK/FK ist die LOGID/Entry_ID):

      Es macht folgendes:
      1) Erstellt temporäre Tabellen mit dummy data
      2) In der schleife werden die Daten eingefügt
      Dabei werden die Zufalls Daten mit folgenden zwei Queries aus den tmp tables geholt:
      A: SELECT RND_VALUE FROM ( SELECT RND_VALUE FROM SCHEMA.TMP_TBL_ACTION ORDER BY DBMS_RANDOM.VALUE ) WHERE ROWNUM = 1;
      B: SELECT RND_VALUE FROM ( SELECT RND_VALUE FROM SCHEMA.TMP_TBL_CORREL SAMPLE(20) ) WHERE ROWNUM = 1;
      3) Die Correlation id wird noch extra behandelt, damit manche der Einträge dieselbe correlation ID haben
      Bei jedem 10ten mal wird keine neue ID erzeugt sondern aus der Tmp table geholt
      Sonst eben neue und die wird auch in die temp table hinzugefügt
      4) Zum schluss werden die Tmp tables gedropped


      Die Probleme sind, das es langsam ist.
      Die Methode von Query A (ORDER BY DBMS_RANDOM.VALUE) dürfte bei größeren Tabellen langsamer werden.
      Die Methode von Query B (SAMPLE(20)) liefert nicht verlässlich Werte (also auch mal NULL).

      Jetzt ist die Frage wie kriege ich höhere Performance ohne überall die Methode B zu nutzen, da mir bei (so glaube ich es fest gestellt zu haben) kleinen Tabellen nicht sicher Daten zurück kommen,
      aber methode A auch schon bei mittelgroßen Tabellen langsamer wird.
      (in meinem Richtigen script sind die Tabellen eine Spur größer (aber auch nicht mehr als 1000 rows))

      Code:
      CREATE TABLE SCHEMA.TMP_TBL_ACTION
      (
        RND_VALUE VARCHAR2(10)
      );
      INSERT INTO SCHEMA.TMP_TBL_ACTION (RND_VALUE) VALUES ('Create');
      INSERT INTO SCHEMA.TMP_TBL_ACTION (RND_VALUE) VALUES ('Read');
      INSERT INTO SCHEMA.TMP_TBL_ACTION (RND_VALUE) VALUES ('Update');
      INSERT INTO SCHEMA.TMP_TBL_ACTION (RND_VALUE) VALUES ('Delete');
      COMMIT;
      
      CREATE TABLE SCHEMA.TMP_TBL_ROLE
      (
        RND_VALUE VARCHAR2(10)
      );
      INSERT INTO SCHEMA.TMP_TBL_APP (RND_VALUE) VALUES ('Role1');
      INSERT INTO SCHEMA.TMP_TBL_APP (RND_VALUE) VALUES ('Role2');
      INSERT INTO SCHEMA.TMP_TBL_APP (RND_VALUE) VALUES ('Role3');
      INSERT INTO SCHEMA.TMP_TBL_APP (RND_VALUE) VALUES ('Role4');
      INSERT INTO SCHEMA.TMP_TBL_APP (RND_VALUE) VALUES ('Role5');
      COMMIT;
      
      CREATE TABLE SCHEMA.TMP_TBL_ROLEACTION
      (
        RND_VALUE VARCHAR2(80),
        RND_ROLE VARCHAR2(10)
      );
      INSERT INTO SCHEMA.TMP_TBL_ROLEACTION (RND_ROLE, RND_VALUE) VALUES ('Role1', 'An Role1 Action A');
      INSERT INTO SCHEMA.TMP_TBL_ROLEACTION (RND_ROLE, RND_VALUE) VALUES ('Role1', 'An Role1 Action B');
      INSERT INTO SCHEMA.TMP_TBL_ROLEACTION (RND_ROLE, RND_VALUE) VALUES ('Role1', 'An Role1 Action C');
      INSERT INTO SCHEMA.TMP_TBL_ROLEACTION (RND_ROLE, RND_VALUE) VALUES ('Role2', 'An Role2 Action A');
      INSERT INTO SCHEMA.TMP_TBL_ROLEACTION (RND_ROLE, RND_VALUE) VALUES ('Role2', 'An Role2 Action B');
      INSERT INTO SCHEMA.TMP_TBL_ROLEACTION (RND_ROLE, RND_VALUE) VALUES ('Role2', 'An Role2 Action C');
      INSERT INTO SCHEMA.TMP_TBL_ROLEACTION (RND_ROLE, RND_VALUE) VALUES ('Role3', 'An Role3 Action A');
      INSERT INTO SCHEMA.TMP_TBL_ROLEACTION (RND_ROLE, RND_VALUE) VALUES ('Role3', 'An Role3 Action B');
      INSERT INTO SCHEMA.TMP_TBL_ROLEACTION (RND_ROLE, RND_VALUE) VALUES ('Role3', 'An Role3 Action C');
      INSERT INTO SCHEMA.TMP_TBL_ROLEACTION (RND_ROLE, RND_VALUE) VALUES ('Role4', 'An Role4 Action A');
      INSERT INTO SCHEMA.TMP_TBL_ROLEACTION (RND_ROLE, RND_VALUE) VALUES ('Role4', 'An Role4 Action B');
      INSERT INTO SCHEMA.TMP_TBL_ROLEACTION (RND_ROLE, RND_VALUE) VALUES ('Role4', 'An Role4 Action C');
      INSERT INTO SCHEMA.TMP_TBL_ROLEACTION (RND_ROLE, RND_VALUE) VALUES ('Role5', 'An Role5 Action A');
      INSERT INTO SCHEMA.TMP_TBL_ROLEACTION (RND_ROLE, RND_VALUE) VALUES ('Role5', 'An Role5 Action B');
      INSERT INTO SCHEMA.TMP_TBL_ROLEACTION (RND_ROLE, RND_VALUE) VALUES ('Role5', 'An Role5 Action C');
      
      COMMIT;
      
      CREATE TABLE SCHEMA.TMP_TBL_USERNAME
      (
        RND_VALUE VARCHAR2(16)
      );
      INSERT INTO SCHEMA.TMP_TBL_USERNAME (RND_VALUE) VALUES ('USER_A');
      INSERT INTO SCHEMA.TMP_TBL_USERNAME (RND_VALUE) VALUES ('USER_B');
      INSERT INTO SCHEMA.TMP_TBL_USERNAME (RND_VALUE) VALUES ('USER_C');
      INSERT INTO SCHEMA.TMP_TBL_USERNAME (RND_VALUE) VALUES ('USER_D');
      INSERT INTO SCHEMA.TMP_TBL_USERNAME (RND_VALUE) VALUES ('USER_E');
      INSERT INTO SCHEMA.TMP_TBL_USERNAME (RND_VALUE) VALUES ('USER_F');
      INSERT INTO SCHEMA.TMP_TBL_USERNAME (RND_VALUE) VALUES ('USER_G');
      COMMIT;
      
      CREATE TABLE SCHEMA.TMP_TBL_INTEGER
      (
        RND_VALUE integer
      );
      INSERT INTO SCHEMA.TMP_TBL_INTEGER (RND_VALUE) VALUES (1);
      INSERT INTO SCHEMA.TMP_TBL_INTEGER (RND_VALUE) VALUES (2);
      INSERT INTO SCHEMA.TMP_TBL_INTEGER (RND_VALUE) VALUES (3);
      INSERT INTO SCHEMA.TMP_TBL_INTEGER (RND_VALUE) VALUES (4);
      INSERT INTO SCHEMA.TMP_TBL_INTEGER (RND_VALUE) VALUES (5);
      INSERT INTO SCHEMA.TMP_TBL_INTEGER (RND_VALUE) VALUES (6);
      INSERT INTO SCHEMA.TMP_TBL_INTEGER (RND_VALUE) VALUES (7);
      INSERT INTO SCHEMA.TMP_TBL_INTEGER (RND_VALUE) VALUES (8);
      INSERT INTO SCHEMA.TMP_TBL_INTEGER (RND_VALUE) VALUES (9);
      INSERT INTO SCHEMA.TMP_TBL_INTEGER (RND_VALUE) VALUES (13);
      INSERT INTO SCHEMA.TMP_TBL_INTEGER (RND_VALUE) VALUES (23);
      INSERT INTO SCHEMA.TMP_TBL_INTEGER (RND_VALUE) VALUES (42);
      COMMIT;
      
      CREATE TABLE SCHEMA.TMP_TBL_IP
      (
        RND_VALUE VARCHAR2(16)
      );
      INSERT INTO SCHEMA.TMP_TBL_IP (RND_VALUE) VALUES ('255.255.255.255');
      INSERT INTO SCHEMA.TMP_TBL_IP (RND_VALUE) VALUES ('1.1.1.1');
      INSERT INTO SCHEMA.TMP_TBL_IP (RND_VALUE) VALUES ('2.2.2.2');
      INSERT INTO SCHEMA.TMP_TBL_IP (RND_VALUE) VALUES ('3.3.3.3');
      INSERT INTO SCHEMA.TMP_TBL_IP (RND_VALUE) VALUES ('4.4.4.4');
      INSERT INTO SCHEMA.TMP_TBL_IP (RND_VALUE) VALUES ('5.5.5.5');
      INSERT INTO SCHEMA.TMP_TBL_IP (RND_VALUE) VALUES ('6.6.6.6');
      INSERT INTO SCHEMA.TMP_TBL_IP (RND_VALUE) VALUES ('7.7.7.7');
      INSERT INTO SCHEMA.TMP_TBL_IP (RND_VALUE) VALUES ('8.8.8.8');
      INSERT INTO SCHEMA.TMP_TBL_IP (RND_VALUE) VALUES ('9.9.9.9');
      INSERT INTO SCHEMA.TMP_TBL_IP (RND_VALUE) VALUES ('192.168.0.1');
      COMMIT;
      
      CREATE TABLE SCHEMA.TMP_TBL_CORREL
      (
        RND_VALUE VARCHAR2(100)
      );
      INSERT INTO SCHEMA.TMP_TBL_CORREL (RND_VALUE) VALUES ('CORID_'||sys_guid());
      INSERT INTO SCHEMA.TMP_TBL_CORREL (RND_VALUE) VALUES ('CORID_'||sys_guid());
      INSERT INTO SCHEMA.TMP_TBL_CORREL (RND_VALUE) VALUES ('CORID_'||sys_guid());
      INSERT INTO SCHEMA.TMP_TBL_CORREL (RND_VALUE) VALUES ('CORID_'||sys_guid());
      INSERT INTO SCHEMA.TMP_TBL_CORREL (RND_VALUE) VALUES ('CORID_'||sys_guid());
      INSERT INTO SCHEMA.TMP_TBL_CORREL (RND_VALUE) VALUES ('CORID_'||sys_guid());
      INSERT INTO SCHEMA.TMP_TBL_CORREL (RND_VALUE) VALUES ('CORID_'||sys_guid());
      INSERT INTO SCHEMA.TMP_TBL_CORREL (RND_VALUE) VALUES ('CORID_'||sys_guid());
      INSERT INTO SCHEMA.TMP_TBL_CORREL (RND_VALUE) VALUES ('CORID_'||sys_guid());
      INSERT INTO SCHEMA.TMP_TBL_CORREL (RND_VALUE) VALUES ('CORID_'||sys_guid());
      INSERT INTO SCHEMA.TMP_TBL_CORREL (RND_VALUE) VALUES ('CORID_'||sys_guid());
      INSERT INTO SCHEMA.TMP_TBL_CORREL (RND_VALUE) VALUES ('CORID_'||sys_guid());
      INSERT INTO SCHEMA.TMP_TBL_CORREL (RND_VALUE) VALUES ('CORID_'||sys_guid());
      INSERT INTO SCHEMA.TMP_TBL_CORREL (RND_VALUE) VALUES ('CORID_'||sys_guid());
      COMMIT;
      
      declare
        entry_id integer := 100;
        v_username VARCHAR2(16);
        v_rolename VARCHAR2(10);
        v_correlation VARCHAR2(100);
      begin
        for idx in 1..1000000 loop
          entry_id := 1000000+idx;
      
          SELECT RND_VALUE INTO v_username FROM ( SELECT RND_VALUE FROM SCHEMA.TMP_TBL_USERNAME ORDER BY DBMS_RANDOM.VALUE ) WHERE ROWNUM = 1;
          SELECT RND_VALUE INTO v_rolename FROM ( SELECT RND_VALUE FROM SCHEMA.TMP_TBL_APP ORDER BY DBMS_RANDOM.VALUE ) WHERE ROWNUM = 1;
      
          IF mod(idx,10) = 1
          THEN
              -- use old one
              SELECT RND_VALUE INTO v_correlation FROM ( SELECT RND_VALUE FROM SCHEMA.TMP_TBL_CORREL SAMPLE(50) ) WHERE ROWNUM = 1;
          ELSE
              -- use new one
              SELECT 'CORID_'||sys_guid() INTO v_correlation FROM DUAL;
              INSERT INTO SCHEMA.TMP_TBL_CORREL (RND_VALUE) VALUES (v_correlation);
          END IF;
      
          Insert into SCHEMA.LOGDATA (LOGID,ACTION,USERNAME,EX_ROLENAME,TIMESTAMPLP,TERMINALIP) values
          ( entry_id
          , (SELECT RND_VALUE FROM ( SELECT RND_VALUE FROM SCHEMA.TMP_TBL_ACTION ORDER BY DBMS_RANDOM.VALUE ) WHERE ROWNUM = 1)
          , v_username
          , v_username||'_'||v_rolename
          , to_date(to_char(to_date(sysdate,'DD.MM.RR')||to_char(to_date('2010-01-01', 'yyyy-mm-dd')+dbms_random.value(1,1000), 'HH24:MI:SS')), 'DD.MM.RR HH24:MI:SS')
          , (SELECT RND_VALUE FROM ( SELECT RND_VALUE FROM SCHEMA.TMP_TBL_IP ORDER BY DBMS_RANDOM.VALUE ) WHERE ROWNUM = 1));
      
          Insert into SCHEMA.LOGDATA2 (LOGID,RECORDID,VAL_1,VAL_2,ROLE_ACTION,TRANSACTIONID) values
          ( entry_id
          , 'RECORDID_'||sys_guid()
          , (SELECT RND_VALUE FROM ( SELECT RND_VALUE FROM SCHEMA.TMP_TBL_INTEGER ORDER BY DBMS_RANDOM.VALUE ) WHERE ROWNUM = 1)
          , (SELECT RND_VALUE FROM ( SELECT RND_VALUE FROM SCHEMA.TMP_TBL_INTEGER ORDER BY DBMS_RANDOM.VALUE ) WHERE ROWNUM = 1)
          , (SELECT RND_VALUE FROM ( SELECT RND_VALUE FROM SCHEMA.TMP_TBL_ROLEACTION WHERE RND_ROLE = v_rolename ORDER BY DBMS_RANDOM.VALUE  ) WHERE ROWNUM = 1)
          , v_correlation);
      
          -- Commit every 100th time
          IF mod(idx,100) = 1
          THEN
              COMMIT;
          END IF;
        end loop;
      end;
      /
      
      DROP TABLE SCHEMA.TMP_TBL_IP;
      DROP TABLE SCHEMA.TMP_TBL_ACTION;
      DROP TABLE SCHEMA.TMP_TBL_ROLEACTION;
      DROP TABLE SCHEMA.TMP_TBL_INTEGER;
      DROP TABLE SCHEMA.TMP_TBL_CORREL;
      DROP TABLE SCHEMA.TMP_TBL_INTERFACTE;
      DROP TABLE SCHEMA.TMP_TBL_USERNAME;
      DROP TABLE SCHEMA.TMP_TBL_PORT;
      DROP TABLE SCHEMA.TMP_TBL_PROTOCOL;
      DROP TABLE SCHEMA.TMP_TBL_APP;
      EXIT;

      Comment


      • #4
        Zum Code
        Danke für das Testbeispiel, aber es sind einige Fehler drin...
        Im Script fehlen die Definitionen für LOGDATA und LOGDATA2, TMP_TBL_ROLE wird gebaut aber scheinbar TMP_TBL_APP verwendet...

        Zur Performance
        Prinzipiell solltest Du alles was in SQL erledigt werden kann mit SQL programmieren und nicht mit PL/SQL.
        Ich denke, dass die Skripte alle mit purem SQL geschrieben werden können.
        Aber 1.000.000 DBMS_RANDOM.VALUE Abrufe benötigen natürlich etwas Zeit:
        SELECT max(DBMS_RANDOM.VALUE) FROM dual CONNECT BY level<=1000000;

        Zum Programm:
        Ein COMMIT in der LOOP ist meist keine gute Idee, dazu gibt es im Web viele Hinweise.
        Ab ORACLE 12 kann man TOP-n queries etwas "hübscher" (evtl. auch performanter) schreiben:

        SELECT RND_VALUE FROM (SELECT RND_VALUE FROM TMP_TBL_USERNAME ORDER BY DBMS_RANDOM.VALUE ) WHERE ROWNUM = 1;

        SELECT RND_VALUE FROM TMP_TBL_USERNAME ORDER BY DBMS_RANDOM.VALUE FETCH FIRST ROW ONLY;


        Ich hoffe, die Anmerkungen helfen etwas, melde Dich wenn Du konkrete Probleme beim SQL hast.




        Comment


        • #5
          Ich verstehe nicht warum Du einen Zufallswert aus einer Tabelle holst, die permanent auf 1 Datensatz limitiert ist und auch noch nach Zufall sortierst. *
          Werte die Null sind aber nicht sein sollen, kann man zuverlässig durch "where <spalte> is not null" ausschließen.

          "ein commit ist meist keine gute idee" finde ich sehr milde ausgedrückt.
          Man benutzt es allgemein im Glauben, es beschleunigt irgendwas. Das ist allgemein Blödsinn.

          Mit dem gezielte oder ungezielten Einstreuen von "Commit" beraubt man sich eines Hauptwerkzeugs einer transaktionalen Datenbank.
          Für das Erstellen von Testdaten mag das bei bestimmten Strategien sinnvoll sein, hilfreich ist es aber m.E. vor allem so:
          Wenn etwas bricht, erfolgt ein rollback und ich lande automatisch auf einem 100% definierten Ausgangszustand.
          Wenn mir meine Script Experimente nicht gefallen, löse ich das roleback selbst aus und lande beim definierten Ausgangszustand.
          Ein explizites commit gehört nicht in normalen Code, weil es unbemerkt definierte Ausgangszustände verändert.


          *mit Code verstehe ich es
          Yum hat die Performanceaspekte auch schon erklärt.
          Das Ganze erfolgt am besten als ein SQL Statement (reines insert statement ohne programm code).
          Die zufällig identischen correlation id musst Du dann mit einem limitierten Random Range - / Modulo Verfahren oder so im SQL Statement erzeugen.

          Wenn Du sowieso diverse Tabellen gezielt mit Werten befüllst, die Du zufällig aber alle immer wieder einzeln abfragst, kannst Du das auch direkt uneingeschränkt machen und etwas permutieren (siehe connect by prior und join ohne Kriterium) und Du hast Dein Select Statement was aus einer handvoll Basiswerten 1 Mio records generiert.

          Comment


          • #6
            Originally posted by jum View Post
            Zum Code
            Danke für das Testbeispiel, aber es sind einige Fehler drin...
            Im Script fehlen die Definitionen für LOGDATA und LOGDATA2, TMP_TBL_ROLE wird gebaut aber scheinbar TMP_TBL_APP verwendet...
            Naja die definition von LOGDATA und LOGDATA2 sind denke ich ja implizit (die Typen sind alle Varchar2, Date und Number), Ja es sollte TMP_TBL_ROLE sein.


            Originally posted by jum View Post
            Zum Code
            Zur Performance
            Prinzipiell solltest Du alles was in SQL erledigt werden kann mit SQL programmieren und nicht mit PL/SQL.
            Ich denke, dass die Skripte alle mit purem SQL geschrieben werden können.
            Aber 1.000.000 DBMS_RANDOM.VALUE Abrufe benötigen natürlich etwas Zeit:
            SELECT max(DBMS_RANDOM.VALUE) FROM dual CONNECT BY level<=1000000;
            Hehe naja ich bin kein SQL-Profi & frage mich daher wie sie mit purem SQL geschrieben würden, darum geht es mir ja.
            Bisschen Zeit is OK, aber ich will eben auch bisschen performance.


            Originally posted by jum View Post
            Zum Code
            Zum Programm:
            Ein COMMIT in der LOOP ist meist keine gute Idee, dazu gibt es im Web viele Hinweise.
            Ab ORACLE 12 kann man TOP-n queries etwas "hübscher" (evtl. auch performanter) schreiben:
            SELECT RND_VALUE FROM (SELECT RND_VALUE FROM TMP_TBL_USERNAME ORDER BY DBMS_RANDOM.VALUE ) WHERE ROWNUM = 1;
            SELECT RND_VALUE FROM TMP_TBL_USERNAME ORDER BY DBMS_RANDOM.VALUE FETCH FIRST ROW ONLY;

            Ich hoffe, die Anmerkungen helfen etwas, melde Dich wenn Du konkrete Probleme beim SQL hast.
            Prinzipjell sit es ein problem weil ich eben sonst nicht wüsste wie ...


            Originally posted by defo2 View Post
            Ich verstehe nicht warum Du einen Zufallswert aus einer Tabelle holst, die permanent auf 1 Datensatz limitiert ist und auch noch nach Zufall sortierst. *
            Naja um aus der Tabelle 1nen Zufallswert zu holen.


            Originally posted by defo2 View Post
            Werte die Null sind aber nicht sein sollen, kann man zuverlässig durch "where <spalte> is not null" ausschließen.
            Hmmm vl klappt es damit, aber eigentlich sollten die doch eh alle NICHT null sein, da ich sie ja immer befülle.
            Ich dachte das kommt von SAMPLE() ???
            Sonst würde dass ggf schon alls performance verbesserung reichen wenn ich das überall verwende.


            Originally posted by defo2 View Post
            "ein commit ist meist keine gute idee" finde ich sehr milde ausgedrückt.
            Man benutzt es allgemein im Glauben, es beschleunigt irgendwas. Das ist allgemein Blödsinn.

            Mit dem gezielte oder ungezielten Einstreuen von "Commit" beraubt man sich eines Hauptwerkzeugs einer transaktionalen Datenbank.
            Für das Erstellen von Testdaten mag das bei bestimmten Strategien sinnvoll sein, hilfreich ist es aber m.E. vor allem so:
            Wenn etwas bricht, erfolgt ein rollback und ich lande automatisch auf einem 100% definierten Ausgangszustand.
            Wenn mir meine Script Experimente nicht gefallen, löse ich das roleback selbst aus und lande beim definierten Ausgangszustand.
            Ein explizites commit gehört nicht in normalen Code, weil es unbemerkt definierte Ausgangszustände verändert.
            Das ist natürlich ein Argument (das ich sogar verstehe) - aber bei mir ging es da eigentlich nur darum zusehen, dass es noch läuft, da es sonst ewig läuft und ich nichts sehe und nicht weiß ob/wie es wo hängt.


            Originally posted by defo2 View Post
            Das Ganze erfolgt am besten als ein SQL Statement (reines insert statement ohne programm code).
            Die zufällig identischen correlation id musst Du dann mit einem limitierten Random Range - / Modulo Verfahren oder so im SQL Statement erzeugen.

            Wenn Du sowieso diverse Tabellen gezielt mit Werten befüllst, die Du zufällig aber alle immer wieder einzeln abfragst, kannst Du das auch direkt uneingeschränkt machen und etwas permutieren (siehe connect by prior und join ohne Kriterium) und Du hast Dein Select Statement was aus einer handvoll Basiswerten 1 Mio records generiert.
            Sorry, das verstehe ich nicht, kann mir nicht vorstellen wie das funktionieren soll .. v.a. als ein Statement, da ich ja in zwei Tabellen Inserten muss. Auch wie ich randomisiert ohne den Trick über die Temp Tables an meine Werte komme - das mit der Correlation ID kann ich natürlich matematich nachvollziehen, aber ebenso wie ich das in SQL abbilden kann ... ekine Ahnung.




            Comment


            • #7
              Das COMMIT machst Du nur, um zu sehen, ob noch irgendwas läuft, dann benutze besser DBMS_APPLICATION_INFO speziell DBMS_APPLICATION_INFO.SET_CLIENT_INFO


              Code:
              BEGIN
              
              FOR i IN 1..1000
              LOOP
              
                DBMS_APPLICATION_INFO.SET_CLIENT_INFO('i='||i);
                dbms_lock.sleep(0.1);
              
              END LOOP;
              
              END;
              Mit einem Tool (hier SQL-Developer, Spalte CLIENT_INFO) kannst Du die Session dann überwachen:

              test.png

              Comment


              • #8
                Originally posted by Paul.Finn View Post
                Hmmm vl klappt es damit, aber eigentlich sollten die doch eh alle NICHT null sein, da ich sie ja immer befülle.
                Ich dachte das kommt von SAMPLE() ???
                Sonst würde dass ggf schon alls performance verbesserung reichen wenn ich das überall verwende.
                Woher die Nulls kommen, kann ich nicht sagen, etwas merkwürdig (anhand Deiner Beispielskripte, -daten nicht richtig nachvollziehbar). Deine Ausdrücke zum Generien sind aber teilweise auch etwas merkwürdig, z.B. der Zeitstempel. Die Verwendung der Sample Clause ist natürlich ein absoluter Performance Killer, ist Dir klar was das macht?

                Originally posted by Paul.Finn View Post
                Das ist natürlich ein Argument (das ich sogar verstehe) - aber bei mir ging es da eigentlich nur darum zusehen, dass es noch läuft, da es sonst ewig läuft und ich nichts sehe und nicht weiß ob/wie es wo hängt.
                Einen Tipp dazu hast Du schon von yum. Ansonsten empfehle ich "autonomous transactions" (>commit nur für separat generierte Infodaten) oder bei wirklich lang arbeitenden Prozessen den Einsatz von oracle jobs package. Die bringen eine Fülle von Monitoring Möglichkeiten mit- auch ohne autonome Transaktionen.

                Originally posted by Paul.Finn View Post
                Sorry, das verstehe ich nicht, kann mir nicht vorstellen wie das funktionieren soll .. v.a. als ein Statement, da ich ja in zwei Tabellen Inserten muss. Auch wie ich randomisiert ohne den Trick über die Temp Tables an meine Werte komme - das mit der Correlation ID kann ich natürlich matematich nachvollziehen, aber ebenso wie ich das in SQL abbilden kann ... ekine Ahnung.
                Für 2 Tabellen brauchst Du natürlich 2 Statements. Wenn Du die Ergebnisdaten später joinen willst, musst Du notgedrungen dafür sorgen, das passende Daten in den Tabellen landen, obwohl du autarkte Statements verwendest. Das mit den Temptables ist im Prinzip schon ok. Je kleiner sie sind, desto eher kann man sie vielleicht in das Statement "einbauen". Ich habe das etwas variiert, poste ich gleich.

                Vlt reicht Dir das als Idee, wie es weitergeht.

                Comment


                • #9
                  Der erste Punkt ist die Basisdaten etwas anders anzulegen.
                  Code:
                  CREATE TABLE SCHEMA.XTMP_TBL_ACTION
                  ( aid numeric(10),
                    RND_VALUE VARCHAR2(10)
                  );
                  INSERT INTO SCHEMA.XTMP_TBL_ACTION VALUES (1, 'Create');
                  INSERT INTO SCHEMA.XTMP_TBL_ACTION VALUES (2, 'Read');
                  INSERT INTO SCHEMA.XTMP_TBL_ACTION VALUES (3, 'Update');
                  INSERT INTO SCHEMA.XTMP_TBL_ACTION VALUES (4, 'Delete');
                  --COMMIT;
                  
                  CREATE TABLE SCHEMA.XTMP_TBL_ROLE
                  ( rid numeric(10),
                    RND_VALUE VARCHAR2(10)
                  );
                  INSERT INTO SCHEMA.XTMP_TBL_ROLE VALUES (1, 'Role1');
                  INSERT INTO SCHEMA.XTMP_TBL_ROLE VALUES (2, 'Role2');
                  INSERT INTO SCHEMA.XTMP_TBL_ROLE VALUES (3, 'Role3');
                  INSERT INTO SCHEMA.XTMP_TBL_ROLE VALUES (4, 'Role4');
                  INSERT INTO SCHEMA.XTMP_TBL_ROLE VALUES (5, 'Role5');
                  --COMMIT;
                  
                  CREATE TABLE SCHEMA.XTMP_TBL_ROLEACTION
                  ( lid numeric(10),
                    RND_VALUE VARCHAR2(80),
                    RND_ROLE VARCHAR2(20)
                  );
                  INSERT INTO SCHEMA.XTMP_TBL_ROLEACTION VALUES ( 1, 'Role1', 'An Role1 Action A');
                  INSERT INTO SCHEMA.XTMP_TBL_ROLEACTION VALUES ( 2, 'Role1', 'An Role1 Action B');
                  INSERT INTO SCHEMA.XTMP_TBL_ROLEACTION VALUES ( 3, 'Role1', 'An Role1 Action C');
                  INSERT INTO SCHEMA.XTMP_TBL_ROLEACTION VALUES ( 4, 'Role2', 'An Role2 Action A');
                  INSERT INTO SCHEMA.XTMP_TBL_ROLEACTION VALUES ( 5, 'Role2', 'An Role2 Action B');
                  INSERT INTO SCHEMA.XTMP_TBL_ROLEACTION VALUES ( 6, 'Role2', 'An Role2 Action C');
                  INSERT INTO SCHEMA.XTMP_TBL_ROLEACTION VALUES ( 7, 'Role3', 'An Role3 Action A');
                  INSERT INTO SCHEMA.XTMP_TBL_ROLEACTION VALUES ( 8, 'Role3', 'An Role3 Action B');
                  INSERT INTO SCHEMA.XTMP_TBL_ROLEACTION VALUES ( 9, 'Role3', 'An Role3 Action C');
                  INSERT INTO SCHEMA.XTMP_TBL_ROLEACTION VALUES (10, 'Role4', 'An Role4 Action A');
                  INSERT INTO SCHEMA.XTMP_TBL_ROLEACTION VALUES (11, 'Role4', 'An Role4 Action B');
                  INSERT INTO SCHEMA.XTMP_TBL_ROLEACTION VALUES (12, 'Role4', 'An Role4 Action C');
                  INSERT INTO SCHEMA.XTMP_TBL_ROLEACTION VALUES (13, 'Role5', 'An Role5 Action A');
                  INSERT INTO SCHEMA.XTMP_TBL_ROLEACTION VALUES (14, 'Role5', 'An Role5 Action B');
                  INSERT INTO SCHEMA.XTMP_TBL_ROLEACTION VALUES (15, 'Role5', 'An Role5 Action C');
                  --COMMIT;
                  
                  CREATE TABLE SCHEMA.XTMP_TBL_USERNAME
                  ( usid numeric(10),
                    RND_VALUE VARCHAR2(16)
                  );
                  INSERT INTO SCHEMA.XTMP_TBL_USERNAME VALUES ( 1, 'USER_A');
                  INSERT INTO SCHEMA.XTMP_TBL_USERNAME VALUES ( 2, 'USER_B');
                  INSERT INTO SCHEMA.XTMP_TBL_USERNAME VALUES ( 3, 'USER_C');
                  INSERT INTO SCHEMA.XTMP_TBL_USERNAME VALUES ( 4, 'USER_D');
                  INSERT INTO SCHEMA.XTMP_TBL_USERNAME VALUES ( 5, 'USER_E');
                  INSERT INTO SCHEMA.XTMP_TBL_USERNAME VALUES ( 6, 'USER_F');
                  INSERT INTO SCHEMA.XTMP_TBL_USERNAME VALUES ( 7, 'USER_G');
                  --COMMIT;                                                                                                  
                  
                  CREATE TABLE SCHEMA.XTMP_TBL_INTEGER
                  ( iid numeric(10),
                    RND_VALUE integer
                  );
                  INSERT INTO SCHEMA.XTMP_TBL_INTEGER VALUES ( 1, 1);
                  INSERT INTO SCHEMA.XTMP_TBL_INTEGER VALUES ( 2, 2);
                  INSERT INTO SCHEMA.XTMP_TBL_INTEGER VALUES ( 3, 3);
                  INSERT INTO SCHEMA.XTMP_TBL_INTEGER VALUES ( 4, 4);
                  INSERT INTO SCHEMA.XTMP_TBL_INTEGER VALUES ( 5, 5);
                  INSERT INTO SCHEMA.XTMP_TBL_INTEGER VALUES ( 6, 6);
                  INSERT INTO SCHEMA.XTMP_TBL_INTEGER VALUES ( 7, 7);
                  INSERT INTO SCHEMA.XTMP_TBL_INTEGER VALUES ( 8, 8);
                  INSERT INTO SCHEMA.XTMP_TBL_INTEGER VALUES ( 9, 9);
                  INSERT INTO SCHEMA.XTMP_TBL_INTEGER VALUES (10, 13);
                  INSERT INTO SCHEMA.XTMP_TBL_INTEGER VALUES (11, 23);
                  INSERT INTO SCHEMA.XTMP_TBL_INTEGER VALUES (12, 42);
                  --COMMIT;                                            
                  
                  CREATE TABLE SCHEMA.XTMP_TBL_IP                          
                  ( pid numeric(10),
                    RND_VALUE VARCHAR2(16)
                  );
                  INSERT INTO SCHEMA.XTMP_TBL_IP VALUES ( 1, '255.255.255.255');
                  INSERT INTO SCHEMA.XTMP_TBL_IP VALUES ( 2, '1.1.1.1');
                  INSERT INTO SCHEMA.XTMP_TBL_IP VALUES ( 3, '2.2.2.2');
                  INSERT INTO SCHEMA.XTMP_TBL_IP VALUES ( 4, '3.3.3.3');
                  INSERT INTO SCHEMA.XTMP_TBL_IP VALUES ( 5, '4.4.4.4');
                  INSERT INTO SCHEMA.XTMP_TBL_IP VALUES ( 6, '5.5.5.5');
                  INSERT INTO SCHEMA.XTMP_TBL_IP VALUES ( 7, '6.6.6.6');
                  INSERT INTO SCHEMA.XTMP_TBL_IP VALUES ( 8, '7.7.7.7');
                  INSERT INTO SCHEMA.XTMP_TBL_IP VALUES ( 9, '8.8.8.8');
                  INSERT INTO SCHEMA.XTMP_TBL_IP VALUES (10, '9.9.9.9');
                  INSERT INTO SCHEMA.XTMP_TBL_IP VALUES (11, '192.168.0.1');
                  --COMMIT;                                        
                  
                  CREATE TABLE SCHEMA.XTMP_TBL_CORREL                
                  ( rid numeric(10),                              
                    RND_VALUE VARCHAR2(100)
                  );
                  INSERT INTO SCHEMA.XTMP_TBL_CORREL VALUES ( 1, 'CORID_'||sys_guid());
                  INSERT INTO SCHEMA.XTMP_TBL_CORREL VALUES ( 2, 'CORID_'||sys_guid());
                  INSERT INTO SCHEMA.XTMP_TBL_CORREL VALUES ( 3, 'CORID_'||sys_guid());
                  INSERT INTO SCHEMA.XTMP_TBL_CORREL VALUES ( 4, 'CORID_'||sys_guid());
                  INSERT INTO SCHEMA.XTMP_TBL_CORREL VALUES ( 5, 'CORID_'||sys_guid());
                  INSERT INTO SCHEMA.XTMP_TBL_CORREL VALUES ( 6, 'CORID_'||sys_guid());
                  INSERT INTO SCHEMA.XTMP_TBL_CORREL VALUES ( 7, 'CORID_'||sys_guid());
                  INSERT INTO SCHEMA.XTMP_TBL_CORREL VALUES ( 8, 'CORID_'||sys_guid());
                  INSERT INTO SCHEMA.XTMP_TBL_CORREL VALUES ( 9, 'CORID_'||sys_guid());
                  INSERT INTO SCHEMA.XTMP_TBL_CORREL VALUES (10, 'CORID_'||sys_guid());
                  INSERT INTO SCHEMA.XTMP_TBL_CORREL VALUES (11, 'CORID_'||sys_guid());
                  INSERT INTO SCHEMA.XTMP_TBL_CORREL VALUES (12, 'CORID_'||sys_guid());
                  INSERT INTO SCHEMA.XTMP_TBL_CORREL VALUES (13, 'CORID_'||sys_guid());
                  INSERT INTO SCHEMA.XTMP_TBL_CORREL VALUES (14, 'CORID_'||sys_guid());
                  --COMMIT;                                            
                  
                  
                  -- am Ende der Insertstatements für alle Testdaten Abschluss per commit
                  --    andernfalls (Weglassen aller commit) haben wir den Effekt,
                  --    dass nur die Testdaten der letzten Tabelle nicht commited sind!
                  Commit;
                  
                  -- eine sequence für laufende Nummern, muss bei Bedarf reseted, dropped und recreated werden
                  create sequence tmpseq;
                  Das Insert bzw. vorher das Create der Logtabelle:

                  Code:
                  --  zuerst die Logdata Table mit einer kleinen Stichprobe erzeugen, dann create auskommentieren, connect by level hochsetzen
                  --create table logdata as  
                  insert into logdata
                  select tmpseq.nextval as LOGID,
                         ACTION,USERNAME, EX_ROLENAME,
                         xtimestamp as TIMESTAMPLP,TERMINALIP from(
                  select        
                  --   entry_id,
                     x.action_id,
                     a.rnd_value as action,
                     x.user_id,
                     u.rnd_value as username,
                     x.role_id,
                     r.rnd_value,
                     u.rnd_value||'_'||r.rnd_value as EX_ROLENAME,
                     xtimestamp,
                     x.ip_id ,
                     i.rnd_value as TERMINALIP
                      from (select                             --    tmpseq.nextval as entry_id,
                        trunc(DBMS_RANDOM.VALUE(1,4+1)) as action_id      --> XTMP_TBL_ACTION
                      , trunc(DBMS_RANDOM.VALUE(1,7+1)) as user_id        --> XTMP_TBL_USERNAME
                      , trunc(DBMS_RANDOM.VALUE(1,5+1)) as role_id        --> XTMP_TBL_ROLE
                      , to_date(to_char(to_date(sysdate,'DD.MM.RR')||to_char(to_date('2010-01-01', 'yyyy-mm-dd')+
                                TRUNC(dbms_random.value(1,1000)), 'HH24:MI:SS')), 'DD.MM.RR HH24:MI:SS') xtimestamp
                      , trunc(DBMS_RANDOM.VALUE(1,11+1)) as ip_id         --> XTMP_TBL_IP
                      from dual CONNECT BY level<=1111111 order by dbms_random.value)x ,
                      --                          ^^^^^^^ erzeugte Datenmenge
                           SCHEMA.XTMP_TBL_ACTION A,
                           SCHEMA.XTMP_TBL_USERNAME U,
                           SCHEMA.Xtmp_Tbl_Role R,
                           SCHEMA.Xtmp_Tbl_ip I
                     where x.action_id = a.aid
                       and x.user_id = u.usid
                       and x.role_id = r.rid      
                       and x.ip_id = i.pid
                       )y;
                  Das läuft auf einer alten VM bei mir mit ca 100 Sekunden.
                  Bei der nächsten Tabelle analog, hier muss man etwas mehr Aufwand treiben für die correlation ID.
                  Am Ende weiß ich nicht genau, wie Du das dann joinen willst, daher würde ich sagen, versuch mal selbst, das für Deinen Bedarf zu erweitern.

                  Wenn man noch Zeit rausquetschen will, kann man z.B. mit sowas 10-20 % Platz und Zeit sparen-wenn die Daten dieser Tabelle nicht mehr geändert werden!:
                  Code:
                  alter table logdata
                      PCTFREE 0
                      PCTUSED 99
                          STORAGE
                           (INITIAL 10M
                            NEXT 10M)
                  Die Storagewerte sollten natürlich irgendwie zu der finalen Größe der Logtabelle passen.
                  Zuletzt editiert von defo2; 15.12.2018, 00:37.

                  Comment

                  Working...
                  X