boolsche WHERE-Bedingungen
- Dieses Thema hat 3 Antworten und 1 Teilnehmer, und wurde zuletzt aktualisiert vor 13 Jahre, 1 Monat von
Anonym.
-
AuthorPosts
-
3. August 2010 um 12:50 Uhr #4089
AnonymInaktivHallo,
ich habe hier ein paar Fragen, die vllt. etwas in die Richtung Sommerloch gehen aber dennoch ganz interessant sind.
Anwendungsentwickler programmieren ja gerne mal Bedingungen wie "and :hvar = 1" ins SQL, um langweilige IF-Konstrukte im Quelltext zu sparen.
Jetzt ist aufgefallen, dass DB2 das "=" wesentlich besser interpretieren kann als ein "<>".
Bei meinen Analysen habe ich bemerkt, dass bei einem Zugriff mit festen Zahlen wie "WHERE 0=1" DB2 einen PRUNED PRIMARY ACCESS durchführt; macht also nichts (so deute ich das). Dagegen bekomme ich im Explain einen "normalen" Zugriff, wenn ich "WHERE 1<>1" kodiere.
1. Frage: warum kann DB2 diese beiden einfachen boolschen Ausdrücke nicht gleichwertig interprtieren?
2. Frage: warum hat so ein SQL bei <> mehr GetPages als bei = ?
3. Frage: wieso greift DB2 auch teuer zu, wenn ich das 1<>1 in "WHERE NOT 1=1" umdrehe?Als addon dann noch das:
in dem SQL, der aufgrund der Where-Bedingung "AND 1<>1" auf keinen Fall Daten liefern kann, ist auch ein ORDER BY feld drin. Laut Monitor verbringt der Befehl fast seine gesamte Laufzeit (von immerhin fast einer Sekunde) im SORT…
4. Frage: was macht der im SORT, wenn es nichts zu sortieren gibt?
5. Frage: Wohin gehen die 153 GetPages, die der Befehl macht (bei Einsatz von = sind es genau 9!)?Bei Verwendung von Hilfsvariablen bestätigt sich, dass <> immer teurer ist als = . Nicht dass jemand glaubt, dass wir WHERE 1<>1 in nserem SQL haben 😉
Vielleicht hat ja jemand Lust, mir das Verhalten näherzubringen 😀
Wir haben noch V8 im Einsatz; ich weiss aber, dass es sich unter V9 genauso verhält.Der komplexe SQL-Befehl:
(jenachdem wird die WHERE-Bedingung modifiziert)
SELECT NAMEÂ Â Â Â Â Â Â Â
FROMÂ Â SYSIBM.SYSTABLES
WHEREÂ CREATOR = ‚AA9’Â
ANDÂ Â 1Â Â Â Â = 2Â Â Â Â
ORDER BY NAME DESC   ÂDanke&Grüsse
Alexander
4. August 2010 um 10:18 Uhr #4243
AnonymInaktivNaja, wann DB2 jetzt genau "pruned" habe ich auch noch nicht rausbekommen.
Bei WHERE 1 = 2 macht es es ja, bei WHERE 1 ^= 1 nicht.Könnte u.U. daran liegen, dass a = b indexfähig ist, a ^= b aber nicht, vielleicht auch daran, dass der Filterfaktor der ersten Bedingung um einiges niedriger ist.
WHERE 1 > 2 "pruned" übrigens auch nicht, dagegen
WHERE spalte > ‚B‘ AND spalte < ‚A‘ schon.
Mehrere GET-Pages … hm, wenn Du das ganze über SPUFI/QMF… getestest hast könnte es daran liegen, dass beim ersten mal ein (aufwändiger) PREPARE gemacht wird, die nachfolgenden male das Statement aus dem DYNAMIC STATEMENT CACHE genommen wird und der PREPARE entfällt. Notfalls jedes Statement öfters absetzen und die GET PAGES vergleichen.
Bei uns ( V9-System ) kommen beide Statements übrigens auf je 16 Getpages wenn sie aus dem Cache geladen werden
… naja kommt vielleich daher, dass es einen CREATOR = ‚AA9‘ bei uns nicht gibt, verwende ich einen vorhandenen, sinds tatsächlich 5 GP mehr, allerdings auch kein SORTIch habe übrigens schon erlebt, dass bei derartigen Statements im Programm das komplette Statement durch den Precompiler durch eine simple SQLCODE= Zuweisung ersetzt wurde, aber auch, dass das ganze ( obwohl durch das 1=0 ziemlich sinnlos ) zur Ausführungszeit einen Tablespace-Scan verursachte. Beidemale stand in der PLAN_TABLE "PRUNED".
Verbringt DB2 denn die Zeit auch im SORT, wenn Du das ORDER BY nicht drin hast ?
Möglich wäre dann z.B. ein komplettes Scannen der SYSIBM.SYSTABLES, die durch ein List Prefetch über den Index DSNDTX01 realisiert wird ( in dem Tablespace sind ja mehrere Tabellen und segmented ist der Katalog auch nicht )Eigentlich wollte ich noch vorschlagen, dass Du über den Monitor nachschaust, welchen Bufferpool diese zusätzlichen GPs verwenden ( in der Hoffnung, dass bei Euch Katalog und Anwenderdaten getrennte Pools verwenden ), aber die SYSIBM.SYSTABLES liegt ja auch im Katalog, so dass nicht unterscheidbar ist, ob DB2 zur Optimierung auf den Katalog zugreift, oder schon Daten der SYSTABLES liest.Â
4. August 2010 um 12:27 Uhr #4357
AnonymInaktivHi Uli,
ich hab dafür extra ein Cobol-Progrämmchen geschrieben, das parametergesteuert jeweils einen anderen Cursor ansteuert. Also alles statisch und fest gebunden.Der SORT wurde bei ORDER BY TSNAME angeschmissen; ohne ORDER BY bzw. ORDER BY NAME gabs keinen Sort… (lt. Explain). Auch war der ORDER BY TSNAME der einzige Lauf, wo die elapsedTime überhaupt messbar war.
das mit 1>2 und spalte > AND spalte < ist auch witzig…
Grüsse
Alexander
6. August 2010 um 18:51 Uhr #4440
AnonymInaktivHallo zusammen,
vielleicht kann ich mit meinen Erkenntnissen zu Erhellung beitragen:
In der Library SDSNMACS(DSN6SPRM), der Vorlage also für den DSNTIJUZ (die DSNZPARM’s) habe ich folgendes gefunden:
[tt]xxxxxxxx.SDSNMACS(DSN6SPRM)Â Â Â Â Â Â Line 00000589 Col
Command ===>Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Scroll =
*Â Â PREDPRUNE – NO OR YES. IF YES, ENABLE PK30857 OPTIMIZERÂ Â PK55076*
*          ENHANCEMENTS. DEFAULT IS NO.                * [/tt]Eventuell läßt sich damit die beobachtete Verhaltensweise erklären – PK055076 – Improved Pruning of ALWAYS TRUE and ALWAYS FALSE Predicates. (for v9 fix):
Slow performance for queries with OR predicates and an always false predicate within the OR.
Examples:[tt]WHERE ‚ABC‘ IN (‚DEF‘,’HIJ‘)
OR INDEX_COL = 123;WHERE INDEX_COL = 123 OR 54=23;
WHERE NOT_NULL_COL IS NULL
OR INDEX_COL = 123;[/tt]Note that not all cases of always false predicates are handled, just all literal constants and not nullable columns IS NULL.
Problem conclusion: DB2 has been fixed to better handle always false predicates under an OR context.
A new zparm PREDPRUNE is added with this APAR to enable pruning of the following types of constructs in queries:
- Predicates containing literals under an OR context that always resolve to FALSE; and
- An IS NULL predicate on a column defined as NOT NULL.
The zparm is turned off by default. The recommended setting is to take the default.
Simply applying this PTF will not change DB2 behavior. However, if you wish to enable the pruning described above, set PREDPRUNE to YES.
Gruß
Gernot
-
AuthorPosts
You must be logged in to reply to this topic.