{"id":292,"date":"2017-04-30T12:56:06","date_gmt":"2017-04-30T10:56:06","guid":{"rendered":"http:\/\/blog.sqlora.com\/de\/?p=292"},"modified":"2018-04-08T22:57:58","modified_gmt":"2018-04-08T20:57:58","slug":"datenhistorisierung-ii","status":"publish","type":"post","link":"https:\/\/blog.sqlora.com\/de\/datenhistorisierung-ii\/","title":{"rendered":"Datenhistorisierung II"},"content":{"rendered":"<p>Im <a href=\"http:\/\/blog.sqlora.com\/en\/how-to-simplify-the-data-historization\/\" target=\"_blank\" rel=\"noopener noreferrer\">vorherigen Post<\/a> habe ich die M\u00f6glichkeit gezeigt, wie man eine Kombination aus UNION ALL und GROUP BY nutzen kann, um die Daten als Slowly Changing Dimension Type 2 zu historisieren. Seitdem habe ich einige Performance-Tests durchgef\u00fchrt, um diesen Ansatz mit herk\u00f6mmlichen Vorgehensweisen in verschiedenen Situationen zu vergleichen. <!--more--><\/p>\n<p><strong>Testfall 1 <\/strong><\/p>\n<p>Wir betrachten das Laden einer versionierten Tabelle im Datawarehouse Core-Bereich aus einer Staging-Tabelle. Schauen wir uns erst mal m\u00f6gliche Konstellationen an, welche Datenmengen wir zu verarbeiten haben und wo die Performance verloren gehen kann. Grunds\u00e4tzlich gibt es zwei Implementierungvarienten f\u00fcr diesen ETL-Prozess: Voll- und Delta-Laden.<\/p>\n<div id=\"attachment_363\" style=\"width: 916px\" class=\"wp-caption alignnone\"><a href=\"http:\/\/blog.sqlora.com\/en\/wp-content\/uploads\/sites\/2\/2017\/04\/full1.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-363\" class=\"size-full wp-image-363\" src=\"http:\/\/blog.sqlora.com\/en\/wp-content\/uploads\/sites\/2\/2017\/04\/full1.png\" alt=\"Full loading\" width=\"906\" height=\"385\" \/><\/a><p id=\"caption-attachment-363\" class=\"wp-caption-text\">Vollladen<\/p><\/div>\n<p>Beim Vollladen haben wir den vollen Datenabzug aus dem Quellsystem im Staging-Bereich. Der Join von diesem Vollabzug zu allen g\u00fcltigen Datens\u00e4tzen in der versionierten Tabelle kann unter Umst\u00e4nden langsam sein. Und dieser Join muss dazu auch noch <a href=\"https:\/\/blog.sqlora.com\/de\/wie-vereinfache-ich-die-historisierung-der-daten#zweimal\" target=\"_blank\" rel=\"noopener noreferrer\">zwei mal ausgef\u00fchrt werden<\/a>, es sei denn wie w\u00fcrden die Zwischenergebnisse des Joins im ETL-Prozess materialisieren.<\/p>\n<p>Auf der anderen Seite m\u00fcssen wir mit dem &#8222;neuen&#8220; Ansatz \u00fcber die Datenmenge gruppieren, die zwei mal so gro\u00df ist wie der Vollabzug der Daten aus dem Quellsystem. Und das kann auch langsam sein!<\/p>\n<div id=\"attachment_365\" style=\"width: 896px\" class=\"wp-caption alignnone\"><a href=\"http:\/\/blog.sqlora.com\/en\/wp-content\/uploads\/sites\/2\/2017\/04\/full2.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-365\" class=\"size-full wp-image-365\" src=\"http:\/\/blog.sqlora.com\/en\/wp-content\/uploads\/sites\/2\/2017\/04\/full2.png\" alt=\"Delta loading\" width=\"886\" height=\"380\" \/><\/a><p id=\"caption-attachment-365\" class=\"wp-caption-text\">Delta-Laden<\/p><\/div>\n<p>Beim Delta-Laden haben wir im Staging-Bereich in der Regel nur einen kleinen Teil der Daten &#8211; die neuen und die aktualisierten Datens\u00e4tze. Somit kann der Join zu g\u00fcltigen Datens\u00e4tzen im Core ziemlich effizient sein, wobei wir mit dem &#8222;neuen&#8220; Ansatz immer noch \u00fcber betr\u00e4chtliche Datenmenge gruppieren m\u00fcssen: alle aktuellen Datens\u00e4tze plus &#8222;Delta&#8220;. Wie k\u00f6nnen wir das verbessern?<\/p>\n<div id=\"attachment_366\" style=\"width: 895px\" class=\"wp-caption alignnone\"><a href=\"http:\/\/blog.sqlora.com\/en\/wp-content\/uploads\/sites\/2\/2017\/04\/full3.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-366\" class=\"size-full wp-image-366\" src=\"http:\/\/blog.sqlora.com\/en\/wp-content\/uploads\/sites\/2\/2017\/04\/full3.png\" alt=\"Delta loading with pre-filter\" width=\"885\" height=\"380\" \/><\/a><p id=\"caption-attachment-366\" class=\"wp-caption-text\">Delta-Laden mit einem Vorfilter<\/p><\/div>\n<p>Offensichtlich m\u00fcssen wir nur die Datens\u00e4tze vergliechen (auf die \u00c4nderungen untersuchen), die es bereits im Core-Bereich gab. Wir k\u00f6nnen eine Art Vorfilter einbauen, zum Beispiel als IN- oder EXISTS-Unterabfrage \u00fcber den Business Key. Somit muss am Ende nur \u00fcber eine Datenmenge gruppiert werden, die ungef\u00e4hr zwei Mal so gro\u00df ist, wie der Delta-Extrakt.<\/p>\n<p>Einige Rahmenbedingungen und Zahlen zum meinem Testfall:<\/p>\n<ul>\n<li>ziemlich breite Tabelle mit 120 Spalten<\/li>\n<li>Vergleich des herk\u00f6mmlichen Ansatzes mit GROUP BY bzw. analytischen FUnktion<\/li>\n<li>Vollextrakt in der Staging-Tabelle als Quelle vs. Deltaextrakt (mit und ohne Vorfilter)<\/li>\n<li>ca. 6 Mio Datens\u00e4tze in der Zieltabelle<\/li>\n<li>ca. 3 Mio Datens\u00e4tze im Vollextrakt<\/li>\n<li>ca. 3000 Datens\u00e4tze im Deltaextrakt<\/li>\n<\/ul>\n\n<table id=\"tablepress-core_ela\" class=\"tablepress tablepress-id-core_ela\">\n<thead>\n<tr class=\"row-1\">\n\t<th class=\"column-1\">Vorgehensweise<\/th><th class=\"column-2\">Delta-Laden, min<\/th><th class=\"column-3\">Vollladen, min<\/th>\n<\/tr>\n<\/thead>\n<tbody class=\"row-striping row-hover\">\n<tr class=\"row-2\">\n\t<td class=\"column-1\">Outer Join (herk\u00f6mmliche Ansatz)<\/td><td class=\"column-2\">0:09<\/td><td class=\"column-3\">0:41<\/td>\n<\/tr>\n<tr class=\"row-3\">\n\t<td class=\"column-1\">GROUP BY<\/td><td class=\"column-2\">1:10<\/td><td class=\"column-3\">1:04<\/td>\n<\/tr>\n<tr class=\"row-4\">\n\t<td class=\"column-1\">GROUP BY mit Vorfilter<\/td><td class=\"column-2\">0:04<\/td><td class=\"column-3\">N\/A<\/td>\n<\/tr>\n<tr class=\"row-5\">\n\t<td class=\"column-1\">Analytische Function<\/td><td class=\"column-2\">2:12<\/td><td class=\"column-3\">4:52<\/td>\n<\/tr>\n<tr class=\"row-6\">\n\t<td class=\"column-1\">Analytische Function mit Vorfilter<\/td><td class=\"column-2\">0:12<\/td><td class=\"column-3\">N\/A<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<!-- #tablepress-core_ela from cache -->\n<p>Beim Laden von Deltaextrakt sah der herk\u00f6mmliche Ansatz aus der Performance-Sicht ziemlich gut aus. Vor allem seine Komplexit\u00e4t, mit dem aufwendigen Vergleich aller Spalten oder Generieren, Speichern und Vergleichen eines Hash-Diffs f\u00fcr alle Datens\u00e4tze, war der Grund f\u00fcr die Suche nach einem alternativen Verfahren. Auf der anderen Seite, der &#8222;reine&#8220; GROUP BY Ansatz ist einfacher aber aber deutlich langsamer. Der Gewinner ist hier der GROUP BY mit Vorfilter. Aber der Preis ist wieder eine etwas h\u00f6here Komplexit\u00e4t.<\/p>\n<p>Beim Vollladen kann der &#8222;neue&#8220; Ansatz mit dem Join nicht mithalten &#8211; er ist um ca. 50% langsamer.<\/p>\n<p>Um den Unterschied zwischen GROUP BY und analytischen Funktion zu verstehen, m\u00fcssen wir uns die Ausf\u00fchrungspl\u00e4ne anschauen. Das Gruppieren wurde bis Oracle 10g Release 2 mithilfe der Operation SORT GROUP BY durchgef\u00fchrt. Und diese ist vergleichbar mit WINDOW SORT, die wir in dem Plan f\u00fcr die analytische Funktion COUNT() sehen. Mit 10g Release 2 wurde <strong>hash aggregation<\/strong> eingef\u00fchrt. Diese k\u00f6nnen wir durch die Schritte HASH GROUP BY im Ausf\u00fchrungsplan erkennen (Listing 1, Zeile 21). Aber die analytischen Funktionen profitieren nicht von dem neuen Feature, die Zeit geht an den Zeilen 14 and 15 (Listing 2) &#8211; WINDOW SORT &#8211; verloren.<\/p>\n<pre class=\"brush: sql; highlight: [21]; title: ; notranslate\" title=\"\">\r\n                                                                                                                                                                                                                                                                                                           \r\n-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------                                                                                   \r\n| Id  | Operation                                | Name              | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   |    TQ  |IN-OUT| PQ Distrib | A-Rows |   A-Time   | Buffers | Reads  |  OMem |  1Mem |  O\/1\/M   |                                                                                   \r\n-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------                                                                                   \r\n|   0 | MERGE STATEMENT                          |                   |      1 |        |       | 10843 (100)|          |        |      |            |      0 |00:00:04.33 |    2447 |      0 |       |       |          |                                                                                   \r\n|   1 |  MERGE                                   | CO_S_ORDER_TEST   |      1 |        |       |            |          |        |      |            |      0 |00:00:04.33 |    2447 |      0 |       |       |          |                                                                                   \r\n|   2 |   VIEW                                   |                   |      1 |        |       |            |          |        |      |            |   3799 |00:00:04.29 |     796 |      0 |       |       |          |                                                                                   \r\n|   3 |    SEQUENCE                              | SEQ_CO_S_ORDER    |      1 |        |       |            |          |        |      |            |   3799 |00:00:04.29 |     796 |      0 |       |       |          |                                                                                   \r\n|   4 |     PX COORDINATOR                       |                   |      1 |        |       |            |          |        |      |            |   3799 |00:00:04.28 |      36 |      0 |       |       |          |                                                                                   \r\n|   5 |      PX SEND QC (RANDOM)                 | :TQ10005          |      0 |    241 |  2353K| 10843  (44)| 00:00:02 |  Q1,05 | P-&gt;S | QC (RAND)  |      0 |00:00:00.01 |       0 |      0 |       |       |          |                                                                                   \r\n|*  6 |       HASH JOIN OUTER BUFFERED           |                   |      4 |    241 |  2353K| 10843  (44)| 00:00:02 |  Q1,05 | PCWP |            |   3799 |00:00:11.51 |       0 |      0 |  3418K|  1207K|     4\/0\/0|                                                                                   \r\n|   7 |        PX RECEIVE                        |                   |      4 |    241 |  2248K|  6095  (50)| 00:00:01 |  Q1,05 | PCWP |            |   3799 |00:00:00.01 |       0 |      0 |       |       |          |                                                                                   \r\n|   8 |         PX SEND HASH                     | :TQ10003          |      0 |    241 |  2248K|  6095  (50)| 00:00:01 |  Q1,03 | P-&gt;P | HASH       |      0 |00:00:00.01 |       0 |      0 |       |       |          |                                                                                   \r\n|*  9 |          VIEW                            |                   |      4 |    241 |  2248K|  6095  (50)| 00:00:01 |  Q1,03 | PCWP |            |   3799 |00:00:00.04 |       0 |      0 |       |       |          |                                                                                   \r\n|  10 |           WINDOW SORT                    |                   |      4 |    241 |   727K|  6095  (50)| 00:00:01 |  Q1,03 | PCWP |            |   3799 |00:00:00.04 |       0 |      0 |  3046K|   544K|     4\/0\/0|                                                                                   \r\n|  11 |            PX RECEIVE                    |                   |      4 |    241 |   727K|  6095  (50)| 00:00:01 |  Q1,03 | PCWP |            |   3799 |00:00:00.01 |       0 |      0 |       |       |          |                                                                                   \r\n|  12 |             PX SEND HASH                 | :TQ10002          |      0 |    241 |   727K|  6095  (50)| 00:00:01 |  Q1,02 | P-&gt;P | HASH       |      0 |00:00:00.01 |       0 |      0 |       |       |          |                                                                                   \r\n|* 13 |              FILTER                      |                   |      4 |        |       |            |          |  Q1,02 | PCWC |            |   3799 |00:00:00.07 |       0 |      0 |       |       |          |                                                                                   \r\n|  14 |               HASH GROUP BY              |                   |      4 |    241 |   727K|  6095  (50)| 00:00:01 |  Q1,02 | PCWP |            |   4300 |00:00:00.07 |       0 |      0 |    22M|  2073K|     4\/0\/0|                                                                                   \r\n|  15 |                PX RECEIVE                |                   |      4 |    241 |   727K|  6095  (50)| 00:00:01 |  Q1,02 | PCWP |            |   4654 |00:00:00.04 |       0 |      0 |       |       |          |                                                                                   \r\n|  16 |                 PX SEND HASH             | :TQ10001          |      0 |    241 |   727K|  6095  (50)| 00:00:01 |  Q1,01 | P-&gt;P | HASH       |      0 |00:00:00.01 |       0 |      0 |       |       |          |                                                                                   \r\n|  17 |                  HASH GROUP BY           |                   |      4 |    241 |   727K|  6095  (50)| 00:00:01 |  Q1,01 | PCWP |            |   4654 |00:00:03.41 |     100K|  99050 |    35M|  4145K|     4\/0\/0|                                                                                   \r\n|  18 |                   VIEW                   |                   |      4 |   4801 |    14M|  6093  (50)| 00:00:01 |  Q1,01 | PCWP |            |   4801 |00:00:00.77 |     100K|  99050 |       |       |          |                                                                                   \r\n|  19 |                    UNION-ALL             |                   |      4 |        |       |            |          |  Q1,01 | PCWP |            |   4801 |00:00:00.77 |     100K|  99050 |       |       |          |                                                                                   \r\n|  20 |                     PX BLOCK ITERATOR    |                   |      4 |   3120 |  1523K|     4   (0)| 00:00:01 |  Q1,01 | PCWC |            |   3120 |00:00:00.01 |     290 |      0 |       |       |          |                                                                                   \r\n|* 21 |                      TABLE ACCESS FULL   | STG_S_ORDER_DELTA |     58 |   3120 |  1523K|     4   (0)| 00:00:01 |  Q1,01 | PCWP |            |   3120 |00:00:00.01 |     290 |      0 |       |       |          |                                                                                   \r\n|* 22 |                     HASH JOIN RIGHT SEMI |                   |      4 |   4152 |  1857K|  6088  (50)| 00:00:01 |  Q1,01 | PCWP |            |   1681 |00:00:04.41 |   99890 |  99050 |  1295K|  1295K|     4\/0\/0|                                                                                   \r\n|  23 |                      PX RECEIVE          |                   |      4 |   3120 | 31200 |     4   (0)| 00:00:01 |  Q1,01 | PCWP |            |  12480 |00:00:00.02 |       0 |      0 |       |       |          |                                                                                   \r\n|  24 |                       PX SEND BROADCAST  | :TQ10000          |      0 |   3120 | 31200 |     4   (0)| 00:00:01 |  Q1,00 | P-&gt;P | BROADCAST  |      0 |00:00:00.01 |       0 |      0 |       |       |          |                                                                                   \r\n|  25 |                        PX BLOCK ITERATOR |                   |      4 |   3120 | 31200 |     4   (0)| 00:00:01 |  Q1,00 | PCWC |            |   3120 |00:00:00.01 |     290 |      0 |       |       |          |                                                                                   \r\n|* 26 |                         TABLE ACCESS FULL| STG_S_ORDER_DELTA |     58 |   3120 | 31200 |     4   (0)| 00:00:01 |  Q1,00 | PCWP |            |   3120 |00:00:00.01 |     290 |      0 |       |       |          |                                                                                   \r\n|  27 |                      PX BLOCK ITERATOR   |                   |      4 |   4135K|  1766M|  6048  (50)| 00:00:01 |  Q1,01 | PCWC |            |   3710K|00:00:03.26 |   99890 |  99050 |       |       |          |                                                                                   \r\n|* 28 |                       TABLE ACCESS FULL  | CO_S_ORDER_TEST   |     84 |   4135K|  1766M|  6048  (50)| 00:00:01 |  Q1,01 | PCWP |            |   3710K|00:00:02.92 |   99890 |  99050 |       |       |          |                                                                                   \r\n|  29 |        PX RECEIVE                        |                   |      4 |   6107K|  2609M|  4694  (35)| 00:00:01 |  Q1,05 | PCWP |            |   6107K|00:00:11.11 |       0 |      0 |       |       |          |                                                                                   \r\n|  30 |         PX SEND HASH                     | :TQ10004          |      0 |   6107K|  2609M|  4694  (35)| 00:00:01 |  Q1,04 | P-&gt;P | HASH       |      0 |00:00:00.01 |       0 |      0 |       |       |          |                                                                                   \r\n|  31 |          PX BLOCK ITERATOR               |                   |      4 |   6107K|  2609M|  4694  (35)| 00:00:01 |  Q1,04 | PCWC |            |   6107K|00:00:05.37 |   99890 |  99050 |       |       |          |                                                                                   \r\n|* 32 |           TABLE ACCESS FULL              | CO_S_ORDER_TEST   |     84 |   6107K|  2609M|  4694  (35)| 00:00:01 |  Q1,04 | PCWP |            |   6107K|00:00:04.69 |   99890 |  99050 |       |       |          |                                                                                   \r\n-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------                                                                                   \r\n\r\n<\/pre>\n<p><strong>Listing 1<\/strong> Ausf\u00fchrungsplan f\u00fcr GROUP BY mit Vorfilter<\/p>\n<pre class=\"brush: sql; highlight: [18,19]; title: ; notranslate\" title=\"\">\r\n\r\n----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------                                                              \r\n| Id  | Operation                           | Name             | Starts | E-Rows |E-Bytes|E-Temp | Cost (%CPU)| E-Time   |    TQ  |IN-OUT| PQ Distrib | A-Rows |   A-Time   | Buffers | Reads  | Writes |  OMem |  1Mem |  O\/1\/M   | Max-Tmp |                                                              \r\n----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------                                                              \r\n|   0 | MERGE STATEMENT                     |                  |      1 |        |       |       |   221K(100)|          |        |      |            |      0 |00:05:46.11 |    2447 |      0 |      0 |       |       |          |         |                                                              \r\n|   1 |  MERGE                              | CO_S_ORDER_TEST  |      1 |        |       |       |            |          |        |      |            |      0 |00:05:46.11 |    2447 |      0 |      0 |       |       |          |         |                                                              \r\n|   2 |   VIEW                              |                  |      1 |        |       |       |            |          |        |      |            |   3799 |00:05:45.89 |     797 |      0 |      0 |       |       |          |         |                                                              \r\n|   3 |    SEQUENCE                         | SEQ_CO_S_ORDER   |      1 |        |       |       |            |          |        |      |            |   3799 |00:05:45.89 |     797 |      0 |      0 |       |       |          |         |                                                              \r\n|   4 |     PX COORDINATOR                  |                  |      1 |        |       |       |            |          |        |      |            |   3799 |00:05:45.88 |      37 |      0 |      0 |       |       |          |         |                                                              \r\n|   5 |      PX SEND QC (RANDOM)            | :TQ10003         |      0 |   7422K|    69G|       |   221K  (3)| 00:00:35 |  Q1,03 | P-&gt;S | QC (RAND)  |      0 |00:00:00.01 |       0 |      0 |      0 |       |       |          |         |                                                              \r\n|*  6 |       HASH JOIN RIGHT OUTER BUFFERED|                  |     16 |   7422K|    69G|       |   221K  (3)| 00:00:35 |  Q1,03 | PCWP |            |   3799 |00:15:42.85 |       0 |     71 |     71 |  2047M|    33M|    16\/0\/0|    1024 |                                                              \r\n|   7 |        PX RECEIVE                   |                  |     16 |   6107K|  2609M|       |  1174  (35)| 00:00:01 |  Q1,03 | PCWP |            |   6107K|00:01:42.93 |       0 |      0 |      0 |       |       |          |         |                                                              \r\n|   8 |         PX SEND HASH                | :TQ10001         |      0 |   6107K|  2609M|       |  1174  (35)| 00:00:01 |  Q1,01 | P-&gt;P | HASH       |      0 |00:00:00.01 |       0 |      0 |      0 |       |       |          |         |                                                              \r\n|   9 |          PX BLOCK ITERATOR          |                  |     16 |   6107K|  2609M|       |  1174  (35)| 00:00:01 |  Q1,01 | PCWC |            |   6107K|00:00:05.42 |     101K|  99050 |      0 |       |       |          |         |                                                              \r\n|* 10 |           TABLE ACCESS FULL         | CO_S_ORDER_TEST  |    251 |   6107K|  2609M|       |  1174  (35)| 00:00:01 |  Q1,01 | PCWP |            |   6107K|00:00:04.86 |     101K|  99050 |      0 |       |       |          |         |                                                              \r\n|  11 |        PX RECEIVE                   |                  |     16 |   7422K|    66G|       |   219K  (3)| 00:00:35 |  Q1,03 | PCWP |            |   3799 |00:08:25.26 |       0 |      0 |      0 |       |       |          |         |                                                              \r\n|  12 |         PX SEND HASH                | :TQ10002         |      0 |   7422K|    66G|       |   219K  (3)| 00:00:35 |  Q1,02 | P-&gt;P | HASH       |      0 |00:00:00.01 |       0 |      0 |      0 |       |       |          |         |                                                              \r\n|* 13 |          VIEW                       |                  |     16 |   7422K|    66G|       |   219K  (3)| 00:00:35 |  Q1,02 | PCWP |            |   3799 |01:08:17.83 |     823 |   1127K|   1127K|       |       |          |         |                                                              \r\n|  14 |           WINDOW SORT               |                  |     16 |   7422K|    21G|    25G|   219K  (3)| 00:00:35 |  Q1,02 | PCWP |            |   7422K|01:23:52.70 |     823 |   1127K|   1127K|    10G|    24M|    4\/12\/0|     591K|                                                              \r\n|  15 |            WINDOW SORT              |                  |     16 |   7422K|    21G|    25G|   219K  (3)| 00:00:35 |  Q1,02 | PCWP |            |   7422K|00:52:43.97 |     754 |    601K|    601K|    10G|    24M|          |     615K|                                                              \r\n|  16 |             PX RECEIVE              |                  |     16 |   7422K|    21G|       |  2188  (45)| 00:00:01 |  Q1,02 | PCWP |            |   7422K|00:11:15.00 |       0 |      0 |      0 |       |       |          |         |                                                              \r\n|  17 |              PX SEND HASH           | :TQ10000         |      0 |   7422K|    21G|       |  2188  (45)| 00:00:01 |  Q1,00 | P-&gt;P | HASH       |      0 |00:00:00.01 |       0 |      0 |      0 |       |       |          |         |                                                              \r\n|  18 |               VIEW                  |                  |     16 |   7422K|    21G|       |  2188  (45)| 00:00:01 |  Q1,00 | PCWP |            |   7422K|00:01:03.91 |     161K|    156K|      0 |       |       |          |         |                                                              \r\n|  19 |                UNION-ALL            |                  |     16 |        |       |       |            |          |  Q1,00 | PCWP |            |   7422K|00:00:52.98 |     161K|    156K|      0 |       |       |          |         |                                                              \r\n|  20 |                 PX BLOCK ITERATOR   |                  |     16 |   3710K|  1525M|       |   676  (36)| 00:00:01 |  Q1,00 | PCWC |            |   3712K|00:00:24.22 |   59203 |  57097 |      0 |       |       |          |         |                                                              \r\n|* 21 |                  TABLE ACCESS FULL  | STG_S_ORDER_FULL |    234 |   3710K|  1525M|       |   676  (36)| 00:00:01 |  Q1,00 | PCWP |            |   3712K|00:00:24.75 |   59203 |  57097 |      0 |       |       |          |         |                                                              \r\n|  22 |                 PX BLOCK ITERATOR   |                  |     16 |   4135K|  1766M|       |  1512  (50)| 00:00:01 |  Q1,00 | PCWC |            |   3710K|00:00:22.72 |     101K|  99050 |      0 |       |       |          |         |                                                              \r\n|* 23 |                  TABLE ACCESS FULL  | CO_S_ORDER_TEST  |    251 |   4135K|  1766M|       |  1512  (50)| 00:00:01 |  Q1,00 | PCWP |            |   3710K|00:00:22.19 |     101K|  99050 |      0 |       |       |          |         |                                                              \r\n----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------                                                              \r\n \r\n<\/pre>\n<p><strong>Listing 2<\/strong> Ausf\u00fchrungsplan f\u00fcr analytische Funktion mit Vorfilter<\/p>\n<p><strong>Testfall 2 <\/strong><\/p>\n<p>Die Quelle f\u00fcr den ETL-Prozess im ersten Testfall war eine Staging-Tabelle. Aber was w\u00e4re, wenn wir eine Dimensionstabelle aus einer riesengro\u00dfen versionereten Core-Tabelle oder \u00fcber eine View laden w\u00fcrden? Der Vorteil, dass wir die gro\u00dfe Tabelle nicht zwei mal lesen m\u00fcssen oder die komplizierte View-Logik nicht zwei mal ausf\u00fchren m\u00fcssen kann den Performnaceverlust beim Gruppieren durchaus \u00fcberwiegen, sogar ohne Vorfilter. In meinem Testfall werden einige &#8222;gro\u00dfe&#8220; Tabellen (50 Gb, 40+ Mio Datens\u00e4tze) in einer View gejoint. Daraus werden t\u00e4glich etwa 500 DImensionsdatens\u00e4tze produziert. Die Ladezeit konnte um 45% reduziert werden (3 min 50 sec \u2192 2 min).<\/p>\n<p><strong>Fazit <\/strong><\/p>\n<p>Ich finde, der vorgeschlagene Ansatz ist eine einfache Alternative, die durchaus weiteres Testen verdient hat. Nicht in jedem Anwendungsfall. Nach meinem Verst\u00e4ndnis sollte die Entwicklung eines Data-Warehouse-Systems hochautomatisiert ablaufen, mit Einsatz entsprechender Generator- \/DWH-Automation Tools, wie z.B. <a href=\"https:\/\/bigenius.info\/\" target=\"_blank\" rel=\"noopener noreferrer\">biGENiUS<\/a>, die die ganze Komplexit\u00e4t der Deltaerkennung verstecken. Sollte das nicht der Fall sein und die ganzen ETL-Prozesse mit Versionierung der Daten im Wesentlichem manuell entwickelt werden, kann man durchaus diesen &#8222;neuen&#8220; Ansatz in Betracht ziehen und von seiner Einfachheit in der Entwicklung und Pflege profitieren.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Im vorherigen Post habe ich die M\u00f6glichkeit gezeigt, wie man eine Kombination aus UNION ALL und GROUP BY nutzen kann, um die Daten als Slowly Changing Dimension Type 2 zu historisieren. Seitdem habe ich einige Performance-Tests durchgef\u00fchrt, um diesen Ansatz mit herk\u00f6mmlichen Vorgehensweisen in verschiedenen Situationen zu vergleichen.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1,39,3,22],"tags":[44,43,40,41,42],"class_list":["post-292","post","type-post","status-publish","format-standard","hentry","category-allgemein","category-data-warehouse","category-oracle","category-trivadis","tag-deltaerkennung","tag-historisierung","tag-owb","tag-scd2","tag-slowly-changing-dimensions"],"_links":{"self":[{"href":"https:\/\/blog.sqlora.com\/de\/wp-json\/wp\/v2\/posts\/292","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.sqlora.com\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.sqlora.com\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.sqlora.com\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.sqlora.com\/de\/wp-json\/wp\/v2\/comments?post=292"}],"version-history":[{"count":14,"href":"https:\/\/blog.sqlora.com\/de\/wp-json\/wp\/v2\/posts\/292\/revisions"}],"predecessor-version":[{"id":440,"href":"https:\/\/blog.sqlora.com\/de\/wp-json\/wp\/v2\/posts\/292\/revisions\/440"}],"wp:attachment":[{"href":"https:\/\/blog.sqlora.com\/de\/wp-json\/wp\/v2\/media?parent=292"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.sqlora.com\/de\/wp-json\/wp\/v2\/categories?post=292"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.sqlora.com\/de\/wp-json\/wp\/v2\/tags?post=292"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}