<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>PostgreSQL 7.4 - Verständnisproblem ...</title>
    <link>http://forum.geizhals.at/feed.jsp?id=387535</link>
    <description>Geizhals-Forum</description>
    <item>
      <title>PostgreSQL 7.4 - Verständnisproblem ...</title>
      <link>http://forum.geizhals.at/t387535,3074775.html#3074775</link>
      <description>Hi !&lt;br&gt;&lt;br&gt;Gegeben sei eine Tabelle mit ein paar Millionen Datensatzzeilen - und unter anderem gebe es ein Attribut "fixstop", das ein Boolean not null ist.&lt;br&gt;&lt;br&gt;Die Histogramme sind noch auf dem Defaultwert 10, und auf den Boolean gebe es einen Index.&lt;br&gt;&lt;br&gt;Hier ein paar Ausgaben:&lt;br&gt;&lt;br&gt;&lt;div class=code&gt;&lt;pre&gt;&#xD;
SELECT attname, n_distinct, most_common_vals FROM pg_stats WHERE tablename = 'lieferliste';&#xD;
....&#xD;
&#xD;
fixstop |          1 | {f}&#xD;
# Es sind also nur 'false-Werte' in der DB gespeichert.&#xD;
&#xD;
kis2_prod=# EXPLAIN select * from lieferliste where fixstop='t';&#xD;
                                  QUERY PLAN&#xD;
------------------------------------------------------------------------------&#xD;
 Index Scan using idx_test on lieferliste  (cost=0.00..2.01 rows=1 width=118)&#xD;
   Index Cond: (fixstop = true)&#xD;
# Bei einer Query nach 't' erkennt er anhand der Statistic die Selektivität von 't' - und geht über den Index - soweit ok&#xD;
&#xD;
kis2_prod=# EXPLAIN select * from lieferliste where fixstop='f';&#xD;
                              QUERY PLAN&#xD;
-----------------------------------------------------------------------&#xD;
 Seq Scan on lieferliste  (cost=0.00..55892.88 rows=1379510 width=118)&#xD;
   Filter: (fixstop = false)&#xD;
(2 Zeilen)&#xD;
# Bei einer Query nach 'f' erkennt er anhand der Statistic die Wertlosigkeit der WHERE-Clause - und macht korrekt einen Full Table Scan.&#xD;
&#xD;
&#xD;
EXPLAIN select * from lieferliste where fixstop;&#xD;
                           QUERY PLAN&#xD;
-----------------------------------------------------------------&#xD;
 Seq Scan on lieferliste  (cost=0.00..52444.10 rows=1 width=118)&#xD;
   Filter: fixstop&#xD;
# Das hier versteh ich nicht.&#xD;
&lt;/pre&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;Nun zu meiner Frage:&lt;br&gt;In der Tabelle gibt es keinen einzigen True-wert für fixstop - wie man an der ersten Query sieht.&lt;br&gt;Daher ist für mich der Weg bei der Query nach "fixstop='t'" völlig klar. Mich verblüfft allerdings, daß ein "WHERE fixstop='t'" kein Synonym zu "WHERE fixstop" ist - denn da macht er ja den full table scan.&lt;br&gt;&lt;br&gt;In der Doku habe ich keinen Hinweis drauf gefunden - wie lautet jetzt die genaue Vorgehensweise des Optimizers ? Und... läßt sich dieses Feature sinnvoll nutzen ? Bleibt das Verhalten konstant oder kann es sein, daß sich das mit der 8er oder 8.1er bereits geändert hat ?&lt;br/&gt;</description>
      <pubDate>Sun, 01 Jan 2006 15:09:35 GMT</pubDate>
      <guid>http://forum.geizhals.at/t387535,3074775.html#3074775</guid>
      <dc:creator>gepeinigter_aon_neukunde</dc:creator>
      <dc:date>2006-01-01T15:09:35Z</dc:date>
    </item>
    <item>
      <title>PostgreSQL 7.4 - Verständnisproblem ...</title>
      <link>http://forum.geizhals.at/t387535,3074840.html#3074840</link>
      <description>Hi !&lt;br&gt;&lt;br&gt;Gegeben sei eine Tabelle mit ein paar Millionen Datensatzzeilen - und unter anderem gebe es ein Attribut "fixstop", das ein Boolean not null ist.&lt;br&gt;&lt;br&gt;Die Histogramme sind noch auf dem Defaultwert 10, und auf den Boolean gebe es einen Index.&lt;br&gt;&lt;br&gt;Hier ein paar Ausgaben:&lt;br&gt;&lt;br&gt;&lt;div class=code&gt;&lt;pre&gt;&#xD;
SELECT attname, n_distinct, most_common_vals FROM pg_stats WHERE tablename = 'lieferliste';&#xD;
....&#xD;
&#xD;
fixstop |          1 | {f}&#xD;
# Es sind also nur 'false-Werte' in der DB gespeichert.&#xD;
&#xD;
kis2_prod=# EXPLAIN select * from lieferliste where fixstop='t';&#xD;
                                  QUERY PLAN&#xD;
------------------------------------------------------------------------------&#xD;
 Index Scan using idx_test on lieferliste  (cost=0.00..2.01 rows=1 width=118)&#xD;
   Index Cond: (fixstop = true)&#xD;
# Bei einer Query nach 't' erkennt er anhand der Statistic die Selektivität von 't' - und geht über den Index - soweit ok&#xD;
&#xD;
kis2_prod=# EXPLAIN select * from lieferliste where fixstop='f';&#xD;
                              QUERY PLAN&#xD;
-----------------------------------------------------------------------&#xD;
 Seq Scan on lieferliste  (cost=0.00..55892.88 rows=1379510 width=118)&#xD;
   Filter: (fixstop = false)&#xD;
(2 Zeilen)&#xD;
# Bei einer Query nach 'f' erkennt er anhand der Statistic die Wertlosigkeit der WHERE-Clause - und macht korrekt einen Full Table Scan.&#xD;
&#xD;
&#xD;
EXPLAIN select * from lieferliste where fixstop;&#xD;
                           QUERY PLAN&#xD;
-----------------------------------------------------------------&#xD;
 Seq Scan on lieferliste  (cost=0.00..52444.10 rows=1 width=118)&#xD;
   Filter: fixstop&#xD;
# Das hier versteh ich nicht.&#xD;
&lt;/pre&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;Nun zu meiner Frage:&lt;br&gt;In der Tabelle gibt es keinen einzigen True-wert für fixstop - wie man an der ersten Query sieht.&lt;br&gt;Daher ist für mich der Weg bei der Query nach "fixstop='t'" völlig klar. Mich verblüfft allerdings, daß ein "WHERE fixstop='t'" kein Synonym zu "WHERE fixstop" ist - denn da macht er ja den full table scan.&lt;br&gt;&lt;br&gt;In der Doku habe ich keinen Hinweis drauf gefunden - wie lautet jetzt die genaue Vorgehensweise des Optimizers ? Und... läßt sich dieses Feature sinnvoll nutzen ? Bleibt das Verhalten konstant oder kann es sein, daß sich das mit der 8er oder 8.1er bereits geändert hat ?&lt;br&gt;&lt;br&gt;&lt;br&gt;EDIT:&lt;br&gt;Die Queries wurden direkt nach einem VACUUM ANALYZE abgesetzt, an veralteten Statistiken dürft's aber nicht liegen. Einsatzszenario: Die Millionen Datensatzzeilen werden bleiben - und es werden maximal 50 das fixstop auf 'true' gesetzt bekommen - ein Index-Scan macht also sowohl bei "WHERE fixstop" als auch bei "WHERE fixstop='t'" durchaus Sinn.&lt;br/&gt;</description>
      <pubDate>Sun, 01 Jan 2006 15:09:35 GMT</pubDate>
      <guid>http://forum.geizhals.at/t387535,3074840.html#3074840</guid>
      <dc:creator>gepeinigter_aon_neukunde</dc:creator>
      <dc:date>2006-01-01T15:09:35Z</dc:date>
    </item>
    <item>
      <title>PostgreSQL 7.4 - Verständnisproblem ...</title>
      <link>http://forum.geizhals.at/t387535,3081216.html#3081216</link>
      <description>Hi !&lt;br&gt;&lt;br&gt;Gegeben sei eine Tabelle mit ein paar Millionen Datensatzzeilen - und unter anderem gebe es ein Attribut "fixstop", das ein Boolean not null ist.&lt;br&gt;&lt;br&gt;Die Histogramme sind noch auf dem Defaultwert 10, und auf den Boolean gebe es einen Index.&lt;br&gt;&lt;br&gt;Hier ein paar Ausgaben:&lt;br&gt;&lt;br&gt;&lt;div class=code&gt;&lt;pre&gt;&#xD;
SELECT attname, n_distinct, most_common_vals FROM pg_stats WHERE tablename = 'lieferliste';&#xD;
....&#xD;
&#xD;
fixstop |          1 | {f}&#xD;
# Es sind also nur 'false-Werte' in der DB gespeichert.&#xD;
&#xD;
kis2_prod=# EXPLAIN select * from lieferliste where fixstop='t';&#xD;
                                  QUERY PLAN&#xD;
------------------------------------------------------------------------------&#xD;
 Index Scan using idx_test on lieferliste  (cost=0.00..2.01 rows=1 width=118)&#xD;
   Index Cond: (fixstop = true)&#xD;
# Bei einer Query nach 't' erkennt er anhand der Statistic die Selektivität von 't' - und geht über den Index - soweit ok&#xD;
&#xD;
kis2_prod=# EXPLAIN select * from lieferliste where fixstop='f';&#xD;
                              QUERY PLAN&#xD;
-----------------------------------------------------------------------&#xD;
 Seq Scan on lieferliste  (cost=0.00..55892.88 rows=1379510 width=118)&#xD;
   Filter: (fixstop = false)&#xD;
(2 Zeilen)&#xD;
# Bei einer Query nach 'f' erkennt er anhand der Statistic die Wertlosigkeit der WHERE-Clause - und macht korrekt einen Full Table Scan.&#xD;
&#xD;
&#xD;
EXPLAIN select * from lieferliste where fixstop;&#xD;
                           QUERY PLAN&#xD;
-----------------------------------------------------------------&#xD;
 Seq Scan on lieferliste  (cost=0.00..52444.10 rows=1 width=118)&#xD;
   Filter: fixstop&#xD;
# Das hier versteh ich nicht.&#xD;
&lt;/pre&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;Nun zu meiner Frage:&lt;br&gt;In der Tabelle gibt es keinen einzigen True-wert für fixstop - wie man an der ersten Query sieht.&lt;br&gt;Daher ist für mich der Weg bei der Query nach "fixstop='t'" völlig klar. Mich verblüfft allerdings, daß ein "WHERE fixstop='t'" kein Synonym zu "WHERE fixstop" ist - denn da macht er ja den full table scan.&lt;br&gt;&lt;br&gt;In der Doku habe ich keinen Hinweis drauf gefunden - wie lautet jetzt die genaue Vorgehensweise des Optimizers ? Und... läßt sich dieses Feature sinnvoll nutzen ? Bleibt das Verhalten konstant oder kann es sein, daß sich das mit der 8er oder 8.1er bereits geändert hat ?&lt;br&gt;&lt;br&gt;&lt;br&gt;EDIT:&lt;br&gt;Die Queries wurden direkt nach einem VACUUM ANALYZE abgesetzt, an veralteten Statistiken dürft's aber nicht liegen. Einsatzszenario: Die Millionen Datensatzzeilen werden bleiben - und es werden maximal 50 das fixstop auf 'true' gesetzt bekommen - ein Index-Scan macht also sowohl bei "WHERE fixstop" als auch bei "WHERE fixstop='t'" durchaus Sinn.&lt;br&gt;&lt;br&gt;EDIT²:&lt;br&gt;Hier zum Nachstellen...&lt;br&gt;&lt;br&gt;&lt;div class=code&gt;&lt;pre&gt;&#xD;
psql test&#xD;
Willkommen bei psql 7.4.2, dem interaktiven PostgreSQL-Terminal.&#xD;
&#xD;
Geben Sie ein:  \copyright für Urheberrechtsinformationen&#xD;
                \h für Hilfe über SQL-Anweisungen&#xD;
                \? für Hilfe über interne Anweisungen&#xD;
                \g oder Semikolon, um eine Anfrage auszuführen&#xD;
                \q um zu beenden&#xD;
&#xD;
test=# \d&#xD;
         Liste der Relationen&#xD;
 Schema | Name |   Typ   | Eigentümer&#xD;
--------+------+---------+-------------&#xD;
 public | a    | Tabelle | grueni&#xD;
(1 Zeile)&#xD;
&#xD;
test=# CREATE TABLE laaang ( id serial primary key not null, bool boolean not null default 'f');&#xD;
NOTICE:  CREATE TABLE will create implicit sequence "laaang_id_seq" for "serial" column "laaang.id"&#xD;
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "laaang_pkey" for table "laaang"&#xD;
CREATE TABLE&#xD;
test=# INSERT INTO laaang(wert) values ('f');&#xD;
ERROR:  column "wert" of relation "laaang" does not exist&#xD;
test=# INSERT INTO laaang(bool) values ('f');&#xD;
INSERT 17180 1&#xD;
test=# INSERT INTO laaang(bool) values ('f');&#xD;
INSERT 17181 1&#xD;
test=# INSERT INTO laaang(bool) values ('f');&#xD;
INSERT 17182 1&#xD;
test=# INSERT INTO laaang(bool) values ('f');&#xD;
INSERT 17183 1&#xD;
test=# INSERT INTO laaang(bool) values ('f');&#xD;
INSERT 17184 1&#xD;
test=# SELECT count(*) from pg_statistic ;&#xD;
 count&#xD;
-------&#xD;
   245&#xD;
(1 Zeile)&#xD;
&#xD;
test=# INSERT INTO laaang (bool) SELECT 'f' from pg_statistic a, pg_statistic b;&#xD;
&#xD;
INSERT 0 60025&#xD;
test=#&#xD;
test=# SELECT count(*) from laaang;&#xD;
 count&#xD;
-------&#xD;
 60030&#xD;
(1 Zeile)&#xD;
&#xD;
test=# INSERT INTO laaang(bool) SELECT bool from laaang;&#xD;
INSERT 0 60030&#xD;
test=# INSERT INTO laaang(bool) SELECT bool from laaang;&#xD;
INSERT 0 120060&#xD;
test=# VACUUM ANALYZE ;&#xD;
VACUUM&#xD;
&#xD;
test=# CREATE INDEX idx_laang on laaang (bool);&#xD;
CREATE INDEX&#xD;
test=# EXPLAIN SELECT * from laaang where bool='t';&#xD;
                               QUERY PLAN&#xD;
------------------------------------------------------------------------&#xD;
 Index Scan using idx_laang on laaang  (cost=0.00..2.01 rows=1 width=5)&#xD;
   Index Cond: (bool = true)&#xD;
(2 Zeilen)&#xD;
--- So soll es sein !&#xD;
&#xD;
test=# EXPLAIN SELECT * from laaang where bool;&#xD;
                       QUERY PLAN&#xD;
---------------------------------------------------------&#xD;
 Seq Scan on laaang  (cost=0.00..3579.20 rows=1 width=5)&#xD;
   Filter: bool&#xD;
(2 Zeilen)&#xD;
&#xD;
-- So soll es nicht sein!&#xD;
&lt;/pre&gt;&lt;/div&gt;&lt;br/&gt;</description>
      <pubDate>Sun, 01 Jan 2006 15:09:35 GMT</pubDate>
      <guid>http://forum.geizhals.at/t387535,3081216.html#3081216</guid>
      <dc:creator>gepeinigter_aon_neukunde</dc:creator>
      <dc:date>2006-01-01T15:09:35Z</dc:date>
    </item>
  </channel>
</rss>
