dos2unix on all repo files, and added OR REPLACE clauses to view and function creation.
authorGurjeet Singh <singh.gurjeet@gmail.com>
Tue, 1 Jun 2010 20:48:40 +0000 (02:18 +0530)
committerGurjeet Singh <singh.gurjeet@gmail.com>
Tue, 1 Jun 2010 20:48:40 +0000 (02:18 +0530)
Makefile
README.pgadviser
resources/index_advisory.create.sql
resources/sample_error_messages.sql
resources/sample_error_messages.txt
resources/sample_psql_session.sql
resources/sample_psql_session.txt
resources/select_index_advisory.create.sql
resources/show_index_advisory.create.sql

index c00c8b117277e377beeddfddee1cd23428a15e19..66b3121e39ee495a7075d95635e927798007789b 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,39 +1,39 @@
-#\r
-# PostgreSQL Adviser top level makefile\r
-#\r
-\r
-PGFILEDESC = "PostgreSQL Index Advisor"\r
-\r
-ifdef USE_PGXS\r
-PGXS := $(shell pg_config --pgxs)\r
-include $(PGXS)\r
-else\r
-subdir = contrib/adviser\r
-top_builddir = ../..\r
-include $(top_builddir)/src/Makefile.global\r
-include $(top_srcdir)/contrib/contrib-global.mk\r
-endif\r
-\r
-\r
-all:\r
-   $(MAKE) -C index_adviser $@\r
-   $(MAKE) -C pg_advise $@\r
-   $(MAKE) -C resources $@\r
-   @echo "PostgreSQL Index Advisor successfully made. Ready to install."\r
-\r
-install:\r
-   $(MAKE) -C index_adviser $@\r
-   $(MAKE) -C pg_advise $@\r
-   $(MAKE) -C resources $@\r
-   @echo "PostgreSQL Index Advisor installed."\r
-\r
-uninstall:\r
-   $(MAKE) -C index_adviser $@\r
-   $(MAKE) -C pg_advise $@\r
-   $(MAKE) -C resources $@\r
-   @echo "PostgreSQL Index Advisor uninstalled."\r
-\r
-clean:\r
-   $(MAKE) -C index_adviser $@\r
-   $(MAKE) -C pg_advise $@\r
-   $(MAKE) -C resources $@\r
+#
+# PostgreSQL Adviser top level makefile
+#
+
+PGFILEDESC = "PostgreSQL Index Advisor"
+
+ifdef USE_PGXS
+PGXS := $(shell pg_config --pgxs)
+include $(PGXS)
+else
+subdir = contrib/adviser
+top_builddir = ../..
+include $(top_builddir)/src/Makefile.global
+include $(top_srcdir)/contrib/contrib-global.mk
+endif
+
+
+all:
+   $(MAKE) -C index_adviser $@
+   $(MAKE) -C pg_advise $@
+   $(MAKE) -C resources $@
+   @echo "PostgreSQL Index Advisor successfully made. Ready to install."
+
+install:
+   $(MAKE) -C index_adviser $@
+   $(MAKE) -C pg_advise $@
+   $(MAKE) -C resources $@
+   @echo "PostgreSQL Index Advisor installed."
+
+uninstall:
+   $(MAKE) -C index_adviser $@
+   $(MAKE) -C pg_advise $@
+   $(MAKE) -C resources $@
+   @echo "PostgreSQL Index Advisor uninstalled."
+
+clean:
+   $(MAKE) -C index_adviser $@
+   $(MAKE) -C pg_advise $@
+   $(MAKE) -C resources $@
index 8417d6f3285f26d96096c96c7c22b974277690db..6279e266556b32a9f58d47e9d8cdc1fa83f8d328 100644 (file)
@@ -1,2 +1,2 @@
-As of now, this module contains only an index adviser. Please read index_adviser/README.index_advisery.\r
-\r
+As of now, this module contains only an index adviser. Please read index_adviser/README.index_advisery.
+
index 1317107582f3f242f220b3865355ac151ccec1e9..a9238e9a072a5b0a4ab668bfe036bc1eab989cea 100644 (file)
@@ -1,10 +1,10 @@
-\r
-create table index_advisory(   reloid      oid,\r
-                               attrs       integer[],\r
-                               profit      real,\r
-                               index_size  integer,\r
-                               backend_pid integer,\r
-                               timestamp   timestamptz);\r
-\r
-create index IA_reloid on index_advisory( reloid );\r
-create index IA_backend_pid on index_advisory( backend_pid );\r
+
+create table index_advisory(   reloid      oid,
+                               attrs       integer[],
+                               profit      real,
+                               index_size  integer,
+                               backend_pid integer,
+                               timestamp   timestamptz);
+
+create index IA_reloid on index_advisory( reloid );
+create index IA_backend_pid on index_advisory( backend_pid );
index 2ef008d8848b951deedd6cdac25bc5c356813e52..503cd105dda58fa20ac05a9e77dcb0ab698ca0cf 100644 (file)
@@ -1,80 +1,80 @@
-\r
-\c postgres test\r
-\r
-drop table if exists advise_index;\r
-drop view if exists advise_index;\r
-\r
-/* create the advise_index same as provided in the contrib module */;\r
-create table advise_index( reloid oid, attrs integer[], profit real,\r
-                           index_size integer, backend_pid integer,\r
-                           timestamp timestamptz);\r
-\r
-/* set the client to see the log messages generated by the Adviser */;\r
-set client_min_messages to log;\r
-\r
-/* As expected, the EXPLAIN will work */;\r
-explain select * from t where a = 100;\r
-\r
-select * from advise_index;\r
-\r
-/* Now lets drop the advise_index and see what ERROR it throws */;\r
-drop table if exists advise_index;\r
-drop view if exists advise_index;\r
-\r
-explain select * from t where a = 100;\r
-\r
-/* create another object by the same name (in the same namespace) */;\r
-create index advise_index on t1(a);\r
-\r
-/* advise_index does exist, but its not a table or view! */;\r
-explain select * from t where a = 100;\r
-\r
-/* now create a table named advise_index, but with a different signature! */;\r
-drop index advise_index;\r
-\r
-create table advise_index(a int);\r
-\r
-/* This ERROR comes from the executor, but we still see our DETAIL and HINT */;\r
-explain select * from t where a = 100;\r
-\r
-/* create a table with same signature but different name */;\r
-drop table if exists advise_index;\r
-drop view if exists advise_index;\r
-\r
-drop table if exists advise_index_data cascade;\r
-\r
-create table advise_index_data( reloid oid, attrs integer[], profit real,\r
-                               index_size integer, backend_pid integer,\r
-                               timestamp timestamptz);\r
-\r
-/* and a view on that table */;\r
-create view advise_index as select * from advise_index_data;\r
-\r
-/* now try to insert into the view, and notice the ERROR, DETAIL and HINT from executor */;\r
-explain select * from t where a = 100;\r
-\r
-/* now create a RULE on the view that redirects the INSERTs into the table */;\r
-create or replace rule advise_index_insert as\r
-ON INSERT to advise_index\r
-do instead\r
-INSERT into advise_index_data values (new.reloid, new.attrs, new.profit,\r
-                                       new.index_size, new.backend_pid,\r
-                                       new.timestamp) ;\r
-\r
-/* and voila, (internal) INSERT into the view succeeds! */;\r
-explain select * from t where a = 100;\r
-\r
-/* Now, lets try what happens under a read-only transaction */;\r
-begin;\r
-\r
-set transaction_read_only=t;\r
-\r
-show transaction_read_only;\r
-\r
-explain select * from t where a = 100;\r
-\r
-end;\r
-\r
-select * from advise_index;\r
-\r
-select * from advise_index_data;\r
+
+\c postgres test
+
+drop table if exists advise_index;
+drop view if exists advise_index;
+
+/* create the advise_index same as provided in the contrib module */;
+create table advise_index( reloid oid, attrs integer[], profit real,
+                           index_size integer, backend_pid integer,
+                           timestamp timestamptz);
+
+/* set the client to see the log messages generated by the Adviser */;
+set client_min_messages to log;
+
+/* As expected, the EXPLAIN will work */;
+explain select * from t where a = 100;
+
+select * from advise_index;
+
+/* Now lets drop the advise_index and see what ERROR it throws */;
+drop table if exists advise_index;
+drop view if exists advise_index;
+
+explain select * from t where a = 100;
+
+/* create another object by the same name (in the same namespace) */;
+create index advise_index on t1(a);
+
+/* advise_index does exist, but its not a table or view! */;
+explain select * from t where a = 100;
+
+/* now create a table named advise_index, but with a different signature! */;
+drop index advise_index;
+
+create table advise_index(a int);
+
+/* This ERROR comes from the executor, but we still see our DETAIL and HINT */;
+explain select * from t where a = 100;
+
+/* create a table with same signature but different name */;
+drop table if exists advise_index;
+drop view if exists advise_index;
+
+drop table if exists advise_index_data cascade;
+
+create table advise_index_data( reloid oid, attrs integer[], profit real,
+                               index_size integer, backend_pid integer,
+                               timestamp timestamptz);
+
+/* and a view on that table */;
+create view advise_index as select * from advise_index_data;
+
+/* now try to insert into the view, and notice the ERROR, DETAIL and HINT from executor */;
+explain select * from t where a = 100;
+
+/* now create a RULE on the view that redirects the INSERTs into the table */;
+create or replace rule advise_index_insert as
+ON INSERT to advise_index
+do instead
+INSERT into advise_index_data values (new.reloid, new.attrs, new.profit,
+                                       new.index_size, new.backend_pid,
+                                       new.timestamp) ;
+
+/* and voila, (internal) INSERT into the view succeeds! */;
+explain select * from t where a = 100;
+
+/* Now, lets try what happens under a read-only transaction */;
+begin;
+
+set transaction_read_only=t;
+
+show transaction_read_only;
+
+explain select * from t where a = 100;
+
+end;
+
+select * from advise_index;
+
+select * from advise_index_data;
index db6dc7797c86d4de0051bea485535de1ade823c4..8a49dc976b4f39030ab9275d6c2a2c17e229b1a6 100644 (file)
-\r
-postgres=> \c postgres test\r
-You are now connected to database "postgres".\r
-postgres=>\r
-postgres=> drop table if exists advise_index;\r
-NOTICE:  table "advise_index" does not exist, skipping\r
-DROP TABLE\r
-postgres=> drop view if exists advise_index;\r
-NOTICE:  view "advise_index" does not exist, skipping\r
-DROP VIEW\r
-postgres=>\r
-postgres=> /* create the advise_index same as provided in the contrib module */;\r
-postgres=> create table advise_index( reloid oid, attrs integer[], profit real,\r
-postgres(>                             index_size integer, backend_pid integer,\r
-postgres(>                             timestamp timestamptz);\r
-CREATE TABLE\r
-postgres=>\r
-postgres=> /* set the client to see the log messages generated by the Adviser */;\r
-postgres=> set client_min_messages to log;\r
-SET\r
-postgres=>\r
-postgres=> /* As expected, the EXPLAIN will work */;\r
-postgres=> explain select * from t where a = 100;\r
-LOG:  Index Adviser: Plan using estimates for suggested indexes:\r
-\r
-Index Scan using idx_adv_0 on t  (cost=0.00..8.28 rows=1 width=8)\r
-  Index Cond: (a = 100)\r
-\r
-                     QUERY PLAN\r
-----------------------------------------------------\r
- Seq Scan on t  (cost=0.00..1791.00 rows=1 width=8)\r
-   Filter: (a = 100)\r
-(2 rows)\r
-\r
-postgres=>\r
-postgres=> select * from advise_index;\r
- reloid | attrs | profit  | index_size | backend_pid |           timestamp\r
---------+-------+---------+------------+-------------+-------------------------------\r
-  16395 | {1}   | 1782.72 |       2608 |        5256 | 2007-01-13 13:08:53.593+05:30\r
-(1 row)\r
-\r
-postgres=>\r
-postgres=> /* Now lets drop the advise_index and see what ERROR it throws */;\r
-postgres=> drop table if exists advise_index;\r
-DROP TABLE\r
-postgres=> drop view if exists advise_index;\r
-NOTICE:  view "advise_index" does not exist, skipping\r
-DROP VIEW\r
-postgres=>\r
-postgres=> explain select * from t where a = 100;\r
-LOG:  Index Adviser: Plan using estimates for suggested indexes:\r
-\r
-Index Scan using idx_adv_0 on t  (cost=0.00..8.28 rows=1 width=8)\r
-  Index Cond: (a = 100)\r
-\r
-ERROR:  relation "advise_index" does not exist.\r
-DETAIL:  Index Adviser uses "advise_index" table to store it's advisory. You should have INSERT permissions on a table or an (INSERT-able) view named "advise_index". Also, make sure that you are not running the Index Adviser under a read-only transaction.\r
-HINT:  Please create the "advise_index" table using the script provided in pg_advise_index contrib module.\r
-postgres=>\r
-postgres=> /* create another object by the same name (in the same namespace) */;\r
-\r
-postgres=> create index advise_index on t1(a);\r
-CREATE INDEX\r
-postgres=>\r
-postgres=> /* advise_index does exist, but its not a table or view! */;\r
-postgres=> explain select * from t where a = 100;\r
-LOG:  Index Adviser: Plan using estimates for suggested indexes:\r
-\r
-Index Scan using idx_adv_0 on t  (cost=0.00..8.28 rows=1 width=8)\r
-  Index Cond: (a = 100)\r
-\r
-ERROR:  "advise_index" is not a table or view.\r
-DETAIL:  Index Adviser uses "advise_index" table to store it's advisory. You should have INSERT permissions on a table or an (INSERT-able) view named "advise_index". Also, make sure that you are not running the Index Adviser under a read-only transaction.\r
-HINT:  Please create the "advise_index" table using the script provided in pg_advise_index contrib module.\r
-postgres=>\r
-postgres=> /* now create a table named advise_index, but with a different signature! */;\r
-postgres=> drop index advise_index;\r
-DROP INDEX\r
-postgres=>\r
-postgres=> create table advise_index(a int);\r
-CREATE TABLE\r
-postgres=>\r
-postgres=> /* This ERROR comes from the executor, but we still see our DETAIL and HINT */;\r
-postgres=> explain select * from t where a = 100;\r
-LOG:  Index Adviser: Plan using estimates for suggested indexes:\r
-\r
-Index Scan using idx_adv_0 on t  (cost=0.00..8.28 rows=1 width=8)\r
-  Index Cond: (a = 100)\r
-\r
-ERROR:  INSERT has more expressions than target columns\r
-DETAIL:  Index Adviser uses "advise_index" table to store it's advisory. You should have INSERT permissions on a table or an (INSERT-able) view named "advise_index". Also, make sure that you are not running the Index Adviser under a read-only transaction.\r
-HINT:  Please create the "advise_index" table using the script provided in pg_advise_index contrib module.\r
-CONTEXT:  SQL statement "insert into "advise_index" values( 16395, array[1], 1782.719482, 2608, 5256, now());"\r
-postgres=>\r
-postgres=> /* create a table with same signature but different name */;\r
-postgres=> drop table if exists advise_index;\r
-DROP TABLE\r
-postgres=> drop view if exists advise_index;\r
-NOTICE:  view "advise_index" does not exist, skipping\r
-DROP VIEW\r
-postgres=>\r
-postgres=> drop table if exists advise_index_data cascade;\r
-NOTICE:  table "advise_index_data" does not exist, skipping\r
-DROP TABLE\r
-postgres=>\r
-postgres=> create table advise_index_data( reloid oid, attrs integer[], profit real,\r
-postgres(>                                 index_size integer, backend_pid integer,\r
-postgres(>                                 timestamp timestamptz);\r
-CREATE TABLE\r
-postgres=>\r
-postgres=> /* and a view on that table */;\r
-postgres=> create view advise_index as select * from advise_index_data;\r
-CREATE VIEW\r
-postgres=>\r
-postgres=> /* now try to insert into the view, and notice the ERROR, DETAIL and HINT from executor */;\r
-postgres=> explain select * from t where a = 100;\r
-LOG:  Index Adviser: Plan using estimates for suggested indexes:\r
-\r
-Index Scan using idx_adv_0 on t  (cost=0.00..8.28 rows=1 width=8)\r
-  Index Cond: (a = 100)\r
-\r
-ERROR:  cannot insert into a view\r
-DETAIL:  Index Adviser uses "advise_index" table to store it's advisory. You should have INSERT permissions on a table or an (INSERT-able) view named "advise_index". Also, make sure that you are not running the Index Adviser under a read-only transaction.\r
-HINT:  Please create the "advise_index" table using the script provided in pg_advise_index contrib module.\r
-CONTEXT:  SQL statement "insert into "advise_index" values( 16395, array[1], 1782.719482, 2608, 5256, now());"\r
-postgres=>\r
-postgres=> /* now create a RULE on the view that redirects the INSERTs into the\r
-table */;\r
-postgres=> create or replace rule advise_index_insert as\r
-postgres-> ON INSERT to advise_index\r
-postgres-> do instead\r
-postgres-> INSERT into advise_index_data values (new.reloid, new.attrs, new.profit,\r
-postgres(>                                         new.index_size, new.backend_pid,\r
-postgres(>                                         new.timestamp) ;\r
-CREATE RULE\r
-postgres=>\r
-postgres=> /* and voila, (internal) INSERT into the view succeeds! */;\r
-postgres=> explain select * from t where a = 100;\r
-LOG:  Index Adviser: Plan using estimates for suggested indexes:\r
-\r
-Index Scan using idx_adv_0 on t  (cost=0.00..8.28 rows=1 width=8)\r
-  Index Cond: (a = 100)\r
-\r
-                     QUERY PLAN\r
-----------------------------------------------------\r
- Seq Scan on t  (cost=0.00..1791.00 rows=1 width=8)\r
-   Filter: (a = 100)\r
-(2 rows)\r
-\r
-postgres=>\r
-postgres=> /* Now, lets try what happens under a read-only transaction */;\r
-postgres=> begin;\r
-BEGIN\r
-postgres=>\r
-postgres=> set transaction_read_only=t;\r
-SET\r
-postgres=>\r
-postgres=> show transaction_read_only;\r
- transaction_read_only\r
------------------------\r
- on\r
-(1 row)\r
-\r
-postgres=>\r
-postgres=> explain select * from t where a = 100;\r
-LOG:  Index Adviser: Plan using estimates for suggested indexes:\r
-\r
-Index Scan using idx_adv_0 on t  (cost=0.00..8.28 rows=1 width=8)\r
-  Index Cond: (a = 100)\r
-\r
-ERROR:  transaction is read-only\r
-DETAIL:  Index Adviser uses "advise_index" table to store it's advisory. You should have INSERT permissions on a table or an (INSERT-able) view named "advise_index". Also, make sure that you are not running the Index Adviser under a read-only transaction.\r
-HINT:  Please create the "advise_index" table using the script provided in pg_advise_index contrib module.\r
-CONTEXT:  SQL statement "insert into "advise_index" values( 16395, array[1], 1782.719482, 2608, 5256, now());"\r
-postgres=>\r
-postgres=> end;\r
-ROLLBACK\r
-postgres=>\r
-postgres=> select * from advise_index;\r
- reloid | attrs | profit  | index_size | backend_pid |          timestamp\r
---------+-------+---------+------------+-------------+------------------------------\r
-  16395 | {1}   | 1782.72 |       2608 |        5256 | 2007-01-13 13:08:54.25+05:30\r
-(1 row)\r
-\r
-postgres=>\r
-postgres=> select * from advise_index_data;\r
- reloid | attrs | profit  | index_size | backend_pid |          timestamp\r
---------+-------+---------+------------+-------------+------------------------------\r
-  16395 | {1}   | 1782.72 |       2608 |        5256 | 2007-01-13 13:08:54.25+05:30\r
-(1 row)\r
-\r
-postgres=>\r
+
+postgres=> \c postgres test
+You are now connected to database "postgres".
+postgres=>
+postgres=> drop table if exists advise_index;
+NOTICE:  table "advise_index" does not exist, skipping
+DROP TABLE
+postgres=> drop view if exists advise_index;
+NOTICE:  view "advise_index" does not exist, skipping
+DROP VIEW
+postgres=>
+postgres=> /* create the advise_index same as provided in the contrib module */;
+postgres=> create table advise_index( reloid oid, attrs integer[], profit real,
+postgres(>                             index_size integer, backend_pid integer,
+postgres(>                             timestamp timestamptz);
+CREATE TABLE
+postgres=>
+postgres=> /* set the client to see the log messages generated by the Adviser */;
+postgres=> set client_min_messages to log;
+SET
+postgres=>
+postgres=> /* As expected, the EXPLAIN will work */;
+postgres=> explain select * from t where a = 100;
+LOG:  Index Adviser: Plan using estimates for suggested indexes:
+
+Index Scan using idx_adv_0 on t  (cost=0.00..8.28 rows=1 width=8)
+  Index Cond: (a = 100)
+
+                     QUERY PLAN
+----------------------------------------------------
+ Seq Scan on t  (cost=0.00..1791.00 rows=1 width=8)
+   Filter: (a = 100)
+(2 rows)
+
+postgres=>
+postgres=> select * from advise_index;
+ reloid | attrs | profit  | index_size | backend_pid |           timestamp
+--------+-------+---------+------------+-------------+-------------------------------
+  16395 | {1}   | 1782.72 |       2608 |        5256 | 2007-01-13 13:08:53.593+05:30
+(1 row)
+
+postgres=>
+postgres=> /* Now lets drop the advise_index and see what ERROR it throws */;
+postgres=> drop table if exists advise_index;
+DROP TABLE
+postgres=> drop view if exists advise_index;
+NOTICE:  view "advise_index" does not exist, skipping
+DROP VIEW
+postgres=>
+postgres=> explain select * from t where a = 100;
+LOG:  Index Adviser: Plan using estimates for suggested indexes:
+
+Index Scan using idx_adv_0 on t  (cost=0.00..8.28 rows=1 width=8)
+  Index Cond: (a = 100)
+
+ERROR:  relation "advise_index" does not exist.
+DETAIL:  Index Adviser uses "advise_index" table to store it's advisory. You should have INSERT permissions on a table or an (INSERT-able) view named "advise_index". Also, make sure that you are not running the Index Adviser under a read-only transaction.
+HINT:  Please create the "advise_index" table using the script provided in pg_advise_index contrib module.
+postgres=>
+postgres=> /* create another object by the same name (in the same namespace) */;
+
+postgres=> create index advise_index on t1(a);
+CREATE INDEX
+postgres=>
+postgres=> /* advise_index does exist, but its not a table or view! */;
+postgres=> explain select * from t where a = 100;
+LOG:  Index Adviser: Plan using estimates for suggested indexes:
+
+Index Scan using idx_adv_0 on t  (cost=0.00..8.28 rows=1 width=8)
+  Index Cond: (a = 100)
+
+ERROR:  "advise_index" is not a table or view.
+DETAIL:  Index Adviser uses "advise_index" table to store it's advisory. You should have INSERT permissions on a table or an (INSERT-able) view named "advise_index". Also, make sure that you are not running the Index Adviser under a read-only transaction.
+HINT:  Please create the "advise_index" table using the script provided in pg_advise_index contrib module.
+postgres=>
+postgres=> /* now create a table named advise_index, but with a different signature! */;
+postgres=> drop index advise_index;
+DROP INDEX
+postgres=>
+postgres=> create table advise_index(a int);
+CREATE TABLE
+postgres=>
+postgres=> /* This ERROR comes from the executor, but we still see our DETAIL and HINT */;
+postgres=> explain select * from t where a = 100;
+LOG:  Index Adviser: Plan using estimates for suggested indexes:
+
+Index Scan using idx_adv_0 on t  (cost=0.00..8.28 rows=1 width=8)
+  Index Cond: (a = 100)
+
+ERROR:  INSERT has more expressions than target columns
+DETAIL:  Index Adviser uses "advise_index" table to store it's advisory. You should have INSERT permissions on a table or an (INSERT-able) view named "advise_index". Also, make sure that you are not running the Index Adviser under a read-only transaction.
+HINT:  Please create the "advise_index" table using the script provided in pg_advise_index contrib module.
+CONTEXT:  SQL statement "insert into "advise_index" values( 16395, array[1], 1782.719482, 2608, 5256, now());"
+postgres=>
+postgres=> /* create a table with same signature but different name */;
+postgres=> drop table if exists advise_index;
+DROP TABLE
+postgres=> drop view if exists advise_index;
+NOTICE:  view "advise_index" does not exist, skipping
+DROP VIEW
+postgres=>
+postgres=> drop table if exists advise_index_data cascade;
+NOTICE:  table "advise_index_data" does not exist, skipping
+DROP TABLE
+postgres=>
+postgres=> create table advise_index_data( reloid oid, attrs integer[], profit real,
+postgres(>                                 index_size integer, backend_pid integer,
+postgres(>                                 timestamp timestamptz);
+CREATE TABLE
+postgres=>
+postgres=> /* and a view on that table */;
+postgres=> create view advise_index as select * from advise_index_data;
+CREATE VIEW
+postgres=>
+postgres=> /* now try to insert into the view, and notice the ERROR, DETAIL and HINT from executor */;
+postgres=> explain select * from t where a = 100;
+LOG:  Index Adviser: Plan using estimates for suggested indexes:
+
+Index Scan using idx_adv_0 on t  (cost=0.00..8.28 rows=1 width=8)
+  Index Cond: (a = 100)
+
+ERROR:  cannot insert into a view
+DETAIL:  Index Adviser uses "advise_index" table to store it's advisory. You should have INSERT permissions on a table or an (INSERT-able) view named "advise_index". Also, make sure that you are not running the Index Adviser under a read-only transaction.
+HINT:  Please create the "advise_index" table using the script provided in pg_advise_index contrib module.
+CONTEXT:  SQL statement "insert into "advise_index" values( 16395, array[1], 1782.719482, 2608, 5256, now());"
+postgres=>
+postgres=> /* now create a RULE on the view that redirects the INSERTs into the
+table */;
+postgres=> create or replace rule advise_index_insert as
+postgres-> ON INSERT to advise_index
+postgres-> do instead
+postgres-> INSERT into advise_index_data values (new.reloid, new.attrs, new.profit,
+postgres(>                                         new.index_size, new.backend_pid,
+postgres(>                                         new.timestamp) ;
+CREATE RULE
+postgres=>
+postgres=> /* and voila, (internal) INSERT into the view succeeds! */;
+postgres=> explain select * from t where a = 100;
+LOG:  Index Adviser: Plan using estimates for suggested indexes:
+
+Index Scan using idx_adv_0 on t  (cost=0.00..8.28 rows=1 width=8)
+  Index Cond: (a = 100)
+
+                     QUERY PLAN
+----------------------------------------------------
+ Seq Scan on t  (cost=0.00..1791.00 rows=1 width=8)
+   Filter: (a = 100)
+(2 rows)
+
+postgres=>
+postgres=> /* Now, lets try what happens under a read-only transaction */;
+postgres=> begin;
+BEGIN
+postgres=>
+postgres=> set transaction_read_only=t;
+SET
+postgres=>
+postgres=> show transaction_read_only;
+ transaction_read_only
+-----------------------
+ on
+(1 row)
+
+postgres=>
+postgres=> explain select * from t where a = 100;
+LOG:  Index Adviser: Plan using estimates for suggested indexes:
+
+Index Scan using idx_adv_0 on t  (cost=0.00..8.28 rows=1 width=8)
+  Index Cond: (a = 100)
+
+ERROR:  transaction is read-only
+DETAIL:  Index Adviser uses "advise_index" table to store it's advisory. You should have INSERT permissions on a table or an (INSERT-able) view named "advise_index". Also, make sure that you are not running the Index Adviser under a read-only transaction.
+HINT:  Please create the "advise_index" table using the script provided in pg_advise_index contrib module.
+CONTEXT:  SQL statement "insert into "advise_index" values( 16395, array[1], 1782.719482, 2608, 5256, now());"
+postgres=>
+postgres=> end;
+ROLLBACK
+postgres=>
+postgres=> select * from advise_index;
+ reloid | attrs | profit  | index_size | backend_pid |          timestamp
+--------+-------+---------+------------+-------------+------------------------------
+  16395 | {1}   | 1782.72 |       2608 |        5256 | 2007-01-13 13:08:54.25+05:30
+(1 row)
+
+postgres=>
+postgres=> select * from advise_index_data;
+ reloid | attrs | profit  | index_size | backend_pid |          timestamp
+--------+-------+---------+------------+-------------+------------------------------
+  16395 | {1}   | 1782.72 |       2608 |        5256 | 2007-01-13 13:08:54.25+05:30
+(1 row)
+
+postgres=>
index f3ba47391210f538ef298de51265f9bee49245de..56e56de27a8d226d0b3151c3908f61d90d8a486a 100644 (file)
@@ -1,80 +1,80 @@
-\r
-create language plpgsql;\r
-\r
-drop schema if exists test cascade;\r
-\r
-drop user if exists test;\r
-\r
-create user test;\r
-\r
-create schema test authorization test;\r
-\r
-\c postgres test\r
-\r
-load '$libdir/plugins/index_adviser';\r
-\r
-drop view if exists select_index_advisory;\r
-drop function if exists show_index_advisory(index_advisory.backend_pid%type);\r
-drop table if exists index_advisory;\r
-\r
-\i contrib/pgadviser/resources/index_advisory.create.sql\r
-\r
-\i contrib/pgadviser/resources/show_index_advisory.create.sql\r
-\r
-\i contrib/pgadviser/resources/select_index_advisory.create.sql\r
-\r
-drop table if exists t, t1;\r
-\r
-create table t( a int, b int );\r
-\r
-insert into t select s, 99999-s from generate_series(0,99999) as s;\r
-\r
-analyze t;\r
-\r
-create table t1 as select * from t;\r
-\r
-/* notice no ANALYZE for T1 */;\r
-\r
-select count(*) from t;\r
-\r
-select count(*) from t1;\r
-\r
-/* stop here if you wish to run only pg_advise tool */;\r
-\r
-/* set the client to see the log messages generated by the Adviser */;\r
-set client_min_messages to log;\r
-\r
-explain select * from t where a = 100;\r
-\r
-explain select * from t where b = 100;\r
-\r
-explain select * from t where a = 100 and b = 100;\r
-\r
-explain select * from t where a = 100 or b = 100;\r
-\r
-/* now we shall test with T1 */;\r
-\r
-explain select * from t1 where a = 100;\r
-\r
-explain select * from t1 where b = 100;\r
-\r
-explain select * from t1 where a = 100 and b = 100;\r
-\r
-explain select * from t1 where a = 100 or b = 100;\r
-\r
-/* let's do some sensible join over these two tables */;\r
-explain \r
-select *\r
-from   t,\r
-       t1\r
-where  t.a = 100\r
-and        t1.a = 100\r
-   or t.b = 100\r
-       and t1.b = 100;\r
-\r
-/* following are the contents of the advise_index table */;\r
-select * from index_advisory;\r
-\r
-/* And following is the summary of the advices generated */;\r
-\r
-select * from select_index_advisory;\r
+
+create language plpgsql;
+
+drop schema if exists test cascade;
+
+drop user if exists test;
+
+create user test;
+
+create schema test authorization test;
+
+\c postgres test
+
+load '$libdir/plugins/index_adviser';
+
+drop view if exists select_index_advisory;
+drop function if exists show_index_advisory(index_advisory.backend_pid%type);
+drop table if exists index_advisory;
+
+\i contrib/pgadviser/resources/index_advisory.create.sql
+
+\i contrib/pgadviser/resources/show_index_advisory.create.sql
+
+\i contrib/pgadviser/resources/select_index_advisory.create.sql
+
+drop table if exists t, t1;
+
+create table t( a int, b int );
+
+insert into t select s, 99999-s from generate_series(0,99999) as s;
+
+analyze t;
+
+create table t1 as select * from t;
+
+/* notice no ANALYZE for T1 */;
+
+select count(*) from t;
+
+select count(*) from t1;
+
+/* stop here if you wish to run only pg_advise tool */;
+
+/* set the client to see the log messages generated by the Adviser */;
+set client_min_messages to log;
+
+explain select * from t where a = 100;
+
+explain select * from t where b = 100;
+
+explain select * from t where a = 100 and b = 100;
+
+explain select * from t where a = 100 or b = 100;
+
+/* now we shall test with T1 */;
+
+explain select * from t1 where a = 100;
+
+explain select * from t1 where b = 100;
+
+explain select * from t1 where a = 100 and b = 100;
+
+explain select * from t1 where a = 100 or b = 100;
+
+/* let's do some sensible join over these two tables */;
+explain 
+select *
+from   t,
+       t1
+where  t.a = 100
+and        t1.a = 100
+   or t.b = 100
+       and t1.b = 100;
+
+/* following are the contents of the advise_index table */;
+select * from index_advisory;
+
+/* And following is the summary of the advices generated */;
+
+select * from select_index_advisory;
index 149451f40f6733852928dd884e43042adbc58eed..1ab3b8a79110f487a27fdc28ba8c9221ce5f6a15 100644 (file)
-\r
-Welcome to psql 8.2.1, the PostgreSQL interactive terminal.\r
-\r
-Type:  \copyright for distribution terms\r
-       \h for help with SQL commands\r
-       \? for help with psql commands\r
-       \g or terminate with semicolon to execute query\r
-       \q to quit\r
-\r
-Warning: Console code page (437) differs from Windows code page (1252)\r
-         8-bit characters may not work correctly. See psql reference\r
-         page "Notes for Windows users" for details.\r
-\r
-postgres=# /*\r
-postgres*# You must start the session with something like:\r
-postgres*#\r
-postgres*# env PGOPTIONS='-c local_preload_libraries=libpg_index_adviser' psql postgres\r
-postgres*# */;\r
-postgres=#\r
-postgres=# create language plpgsql;\r
-CREATE LANGUAGE\r
-postgres=#\r
-postgres=# drop schema if exists test cascade;\r
-NOTICE:  schema "test" does not exist, skipping\r
-DROP SCHEMA\r
-postgres=#\r
-postgres=# drop user if exists test;\r
-NOTICE:  role "test" does not exist, skipping\r
-DROP ROLE\r
-postgres=#\r
-postgres=# create user test;\r
-CREATE ROLE\r
-postgres=#\r
-postgres=# create schema test authorization test;\r
-CREATE SCHEMA\r
-postgres=#\r
-postgres=# \c postgres test\r
-You are now connected to database "postgres" as user "test".\r
-postgres=>\r
-postgres=> drop table if exists advise_index;\r
-NOTICE:  table "advise_index" does not exist, skipping\r
-DROP TABLE\r
-postgres=>\r
-postgres=> \i contrib/pg_index_adviser/advise_index.create.sql\r
-CREATE TABLE\r
-postgres=>\r
-postgres=> \d advise_index;\r
-             Table "test.advise_index"\r
-   Column    |           Type           | Modifiers\r
--------------+--------------------------+-----------\r
- reloid      | oid                      |\r
- attrs       | integer[]                |\r
- profit      | real                     |\r
- index_size  | integer                  |\r
- backend_pid | integer                  |\r
- timestamp   | timestamp with time zone |\r
-\r
-postgres=>\r
-postgres=> \i contrib/pg_index_adviser/advise_index_show.create.sql\r
-CREATE FUNCTION\r
-postgres=>\r
-postgres=> select * from advise_index;\r
- reloid | attrs | profit | index_size | backend_pid | timestamp\r
---------+-------+--------+------------+-------------+-----------\r
-(0 rows)\r
-\r
-postgres=>\r
-postgres=> drop table if exists t, t1;\r
-NOTICE:  table "t" does not exist, skipping\r
-NOTICE:  table "t1" does not exist, skipping\r
-DROP TABLE\r
-postgres=>\r
-postgres=> create table t( a int, b int );\r
-CREATE TABLE\r
-postgres=>\r
-postgres=> insert into t select s, 99999-s from generate_series(0,99999) as s;\r
-INSERT 0 100000\r
-postgres=>\r
-postgres=> analyze t;\r
-ANALYZE\r
-postgres=>\r
-postgres=> create table t1 as select * from t;\r
-SELECT\r
-postgres=>\r
-postgres=> /* notice no ANALYZE for T1 */;\r
-postgres=>\r
-postgres=> select count(*) from t;\r
- count\r
---------\r
- 100000\r
-(1 row)\r
-\r
-postgres=>\r
-postgres=> select count(*) from t1;\r
- count\r
---------\r
- 100000\r
-(1 row)\r
-\r
-postgres=>\r
-postgres=> /* stop here if you wish to run only pg_advise_index tool */;\r
-postgres=>\r
-postgres=> -- set enable_advise_index to true;\r
-postgres=> /* set the client to see the log messages generated by the Adviser */\r
-;\r
-postgres=> set client_min_messages to log;\r
-SET\r
-postgres=>\r
-postgres=> explain select * from t where a = 100;\r
-LOG:  Index Adviser: Plan using estimates for suggested indexes:\r
-\r
-Index Scan using idx_adv_0 on t  (cost=0.00..8.28 rows=1 width=8)\r
-  Index Cond: (a = 100)\r
-\r
-                     QUERY PLAN\r
-----------------------------------------------------\r
- Seq Scan on t  (cost=0.00..1791.00 rows=1 width=8)\r
-   Filter: (a = 100)\r
-(2 rows)\r
-\r
-postgres=>\r
-postgres=> explain select * from t where b = 100;\r
-LOG:  Index Adviser: Plan using estimates for suggested indexes:\r
-\r
-Index Scan using idx_adv_0 on t  (cost=0.00..8.28 rows=1 width=8)\r
-  Index Cond: (b = 100)\r
-\r
-                     QUERY PLAN\r
-----------------------------------------------------\r
- Seq Scan on t  (cost=0.00..1791.00 rows=1 width=8)\r
-   Filter: (b = 100)\r
-(2 rows)\r
-\r
-postgres=>\r
-postgres=> explain select * from t where a = 100 and b = 100;\r
-LOG:  Index Adviser: Plan using estimates for suggested indexes:\r
-\r
-Index Scan using idx_adv_1 on t  (cost=0.00..8.28 rows=1 width=8)\r
-  Index Cond: (b = 100)\r
-  Filter: (a = 100)\r
-\r
-                     QUERY PLAN\r
-----------------------------------------------------\r
- Seq Scan on t  (cost=0.00..2041.00 rows=1 width=8)\r
-   Filter: ((a = 100) AND (b = 100))\r
-(2 rows)\r
-\r
-postgres=>\r
-postgres=> explain select * from t where a = 100 or b = 100;\r
-LOG:  Index Adviser: Plan using estimates for suggested indexes:\r
-\r
-Bitmap Heap Scan on t  (cost=8.54..16.21 rows=2 width=8)\r
-  Recheck Cond: ((a = 100) OR (b = 100))\r
-  ->  BitmapOr  (cost=8.54..8.54 rows=2 width=0)\r
-        ->  Bitmap Index Scan on idx_adv_0  (cost=0.00..4.27 rows=1 width=0)\r
-              Index Cond: (a = 100)\r
-        ->  Bitmap Index Scan on idx_adv_1  (cost=0.00..4.27 rows=1 width=0)\r
-              Index Cond: (b = 100)\r
-\r
-                     QUERY PLAN\r
-----------------------------------------------------\r
- Seq Scan on t  (cost=0.00..2041.00 rows=2 width=8)\r
-   Filter: ((a = 100) OR (b = 100))\r
-(2 rows)\r
-\r
-postgres=>\r
-postgres=> /* now we shall test with T1 */;\r
-postgres=>\r
-postgres=> explain select * from t1 where a = 100;\r
-                      QUERY PLAN\r
--------------------------------------------------------\r
- Seq Scan on t1  (cost=0.00..1852.93 rows=525 width=8)\r
-   Filter: (a = 100)\r
-(2 rows)\r
-\r
-postgres=>\r
-postgres=> explain select * from t1 where b = 100;\r
-                      QUERY PLAN\r
--------------------------------------------------------\r
- Seq Scan on t1  (cost=0.00..1852.93 rows=525 width=8)\r
-   Filter: (b = 100)\r
-(2 rows)\r
-\r
-postgres=>\r
-postgres=> explain select * from t1 where a = 100 and b = 100;\r
-                     QUERY PLAN\r
------------------------------------------------------\r
- Seq Scan on t1  (cost=0.00..2115.31 rows=3 width=8)\r
-   Filter: ((a = 100) AND (b = 100))\r
-(2 rows)\r
-\r
-postgres=>\r
-postgres=> explain select * from t1 where a = 100 or b = 100;\r
-                       QUERY PLAN\r
---------------------------------------------------------\r
- Seq Scan on t1  (cost=0.00..2115.31 rows=1047 width=8)\r
-   Filter: ((a = 100) OR (b = 100))\r
-(2 rows)\r
-\r
-postgres=>\r
-postgres=> /* let's do some sensible join over these two tables */;\r
-postgres=> explain\r
-postgres-> select       *\r
-postgres-> from t,\r
-postgres->              t1\r
-postgres-> where        t.a = 100\r
-postgres-> and          t1.a = 100\r
-postgres->      or t.b = 100\r
-postgres->              and t1.b = 100;\r
-LOG:  Index Adviser: Plan using estimates for suggested indexes:\r
-\r
-Nested Loop  (cost=8.54..7395.45 rows=1050 width=16)\r
-  Join Filter: (((t.a = 100) AND (t1.a = 100)) OR ((t.b = 100) AND (t1.b = 100)))\r
-  ->  Bitmap Heap Scan on t  (cost=8.54..16.21 rows=2 width=8)\r
-        Recheck Cond: ((a = 100) OR (b = 100))\r
-        ->  BitmapOr  (cost=8.54..8.54 rows=2 width=0)\r
-              ->  Bitmap Index Scan on idx_adv_0  (cost=0.00..4.27 rows=1 width=0)\r
-                    Index Cond: (a = 100)\r
-              ->  Bitmap Index Scan on idx_adv_1  (cost=0.00..4.27 rows=1 width=0)\r
-                    Index Cond: (b = 100)\r
-  ->  Seq Scan on t1  (cost=0.00..1590.54 rows=104954 width=8)\r
-\r
-                                    QUERY PLAN\r
------------------------------------------------------------------------------------\r
- Nested Loop  (cost=0.00..368963541.00 rows=1050 width=16)\r
-   Join Filter: (((t.a = 100) AND (t1.a = 100)) OR ((t.b = 100) AND (t1.b = 100)))\r
-   ->  Seq Scan on t  (cost=0.00..1541.00 rows=100000 width=8)\r
-   ->  Seq Scan on t1  (cost=0.00..1590.54 rows=104954 width=8)\r
-(4 rows)\r
-\r
-postgres=>\r
-postgres=> /* following are the contents of the advise_index table */;\r
-postgres=> select * from advise_index;\r
- reloid | attrs |    profit    | index_size | backend_pid |           timestamp\r
---------+-------+--------------+------------+-------------+-------------------------------\r
-  16395 | {1}   |      1782.72 |       2608 |        2272 | 2007-01-13 12:30:02.39+05:30\r
-  16395 | {2}   |      1782.72 |       2608 |        2272 | 2007-01-13 12:30:02.531+05:30\r
-  16395 | {2}   |      2032.72 |       2608 |        2272 | 2007-01-13 12:30:02.578+05:30\r
-  16395 | {1}   |       1012.4 |       2608 |        2272 | 2007-01-13 12:30:02.64+05:30\r
-  16395 | {2}   |       1012.4 |       2608 |        2272 | 2007-01-13 12:30:02.64+05:30\r
-  16395 | {1}   | 1.84478e+008 |       2608 |        2272 | 2007-01-13 12:30:17.984+05:30\r
-  16395 | {2}   | 1.84478e+008 |       2608 |        2272 | 2007-01-13 12:30:17.984+05:30\r
-(7 rows)\r
-\r
-postgres=>\r
-postgres=> /* And following is the summary of the advices generated */;\r
-postgres=>\r
-postgres=> select       E'backend_pid\n'\r
-postgres->              ||      E'===========\n'\r
-postgres->              ||      backend_pid,\r
-postgres->              advise_index_show( backend_pid )\r
-postgres-> from (select distinct backend_pid\r
-postgres(>              from    advise_index as adv\r
-postgres(>              where   adv.reloid in   (select oid\r
-postgres(>                                       from pg_class\r
-postgres(>                                       where relkind = 'r')\r
-postgres(>      ) as v;\r
-  ?column?   |                         advise_index_show\r
--------------+--------------------------------------------------------------------\r
- backend_pid | /* Index Adviser */\r
- =========== : /* ============= */\r
- 2272        :\r
-             : /* size: 2608 KB, benefit: 1.84483e+008, gain: 70737.3067484663 */\r
-             : create index idx_t_b on t(b);\r
-             :\r
-             : /* size: 2608 KB, benefit: 1.84481e+008, gain: 70736.527607362 */\r
-             : create index idx_t_a on t(a);\r
-             :\r
-(1 row)\r
-\r
-postgres=>\r
+
+Welcome to psql 8.2.1, the PostgreSQL interactive terminal.
+
+Type:  \copyright for distribution terms
+       \h for help with SQL commands
+       \? for help with psql commands
+       \g or terminate with semicolon to execute query
+       \q to quit
+
+Warning: Console code page (437) differs from Windows code page (1252)
+         8-bit characters may not work correctly. See psql reference
+         page "Notes for Windows users" for details.
+
+postgres=# /*
+postgres*# You must start the session with something like:
+postgres*#
+postgres*# env PGOPTIONS='-c local_preload_libraries=libpg_index_adviser' psql postgres
+postgres*# */;
+postgres=#
+postgres=# create language plpgsql;
+CREATE LANGUAGE
+postgres=#
+postgres=# drop schema if exists test cascade;
+NOTICE:  schema "test" does not exist, skipping
+DROP SCHEMA
+postgres=#
+postgres=# drop user if exists test;
+NOTICE:  role "test" does not exist, skipping
+DROP ROLE
+postgres=#
+postgres=# create user test;
+CREATE ROLE
+postgres=#
+postgres=# create schema test authorization test;
+CREATE SCHEMA
+postgres=#
+postgres=# \c postgres test
+You are now connected to database "postgres" as user "test".
+postgres=>
+postgres=> drop table if exists advise_index;
+NOTICE:  table "advise_index" does not exist, skipping
+DROP TABLE
+postgres=>
+postgres=> \i contrib/pg_index_adviser/advise_index.create.sql
+CREATE TABLE
+postgres=>
+postgres=> \d advise_index;
+             Table "test.advise_index"
+   Column    |           Type           | Modifiers
+-------------+--------------------------+-----------
+ reloid      | oid                      |
+ attrs       | integer[]                |
+ profit      | real                     |
+ index_size  | integer                  |
+ backend_pid | integer                  |
+ timestamp   | timestamp with time zone |
+
+postgres=>
+postgres=> \i contrib/pg_index_adviser/advise_index_show.create.sql
+CREATE FUNCTION
+postgres=>
+postgres=> select * from advise_index;
+ reloid | attrs | profit | index_size | backend_pid | timestamp
+--------+-------+--------+------------+-------------+-----------
+(0 rows)
+
+postgres=>
+postgres=> drop table if exists t, t1;
+NOTICE:  table "t" does not exist, skipping
+NOTICE:  table "t1" does not exist, skipping
+DROP TABLE
+postgres=>
+postgres=> create table t( a int, b int );
+CREATE TABLE
+postgres=>
+postgres=> insert into t select s, 99999-s from generate_series(0,99999) as s;
+INSERT 0 100000
+postgres=>
+postgres=> analyze t;
+ANALYZE
+postgres=>
+postgres=> create table t1 as select * from t;
+SELECT
+postgres=>
+postgres=> /* notice no ANALYZE for T1 */;
+postgres=>
+postgres=> select count(*) from t;
+ count
+--------
+ 100000
+(1 row)
+
+postgres=>
+postgres=> select count(*) from t1;
+ count
+--------
+ 100000
+(1 row)
+
+postgres=>
+postgres=> /* stop here if you wish to run only pg_advise_index tool */;
+postgres=>
+postgres=> -- set enable_advise_index to true;
+postgres=> /* set the client to see the log messages generated by the Adviser */
+;
+postgres=> set client_min_messages to log;
+SET
+postgres=>
+postgres=> explain select * from t where a = 100;
+LOG:  Index Adviser: Plan using estimates for suggested indexes:
+
+Index Scan using idx_adv_0 on t  (cost=0.00..8.28 rows=1 width=8)
+  Index Cond: (a = 100)
+
+                     QUERY PLAN
+----------------------------------------------------
+ Seq Scan on t  (cost=0.00..1791.00 rows=1 width=8)
+   Filter: (a = 100)
+(2 rows)
+
+postgres=>
+postgres=> explain select * from t where b = 100;
+LOG:  Index Adviser: Plan using estimates for suggested indexes:
+
+Index Scan using idx_adv_0 on t  (cost=0.00..8.28 rows=1 width=8)
+  Index Cond: (b = 100)
+
+                     QUERY PLAN
+----------------------------------------------------
+ Seq Scan on t  (cost=0.00..1791.00 rows=1 width=8)
+   Filter: (b = 100)
+(2 rows)
+
+postgres=>
+postgres=> explain select * from t where a = 100 and b = 100;
+LOG:  Index Adviser: Plan using estimates for suggested indexes:
+
+Index Scan using idx_adv_1 on t  (cost=0.00..8.28 rows=1 width=8)
+  Index Cond: (b = 100)
+  Filter: (a = 100)
+
+                     QUERY PLAN
+----------------------------------------------------
+ Seq Scan on t  (cost=0.00..2041.00 rows=1 width=8)
+   Filter: ((a = 100) AND (b = 100))
+(2 rows)
+
+postgres=>
+postgres=> explain select * from t where a = 100 or b = 100;
+LOG:  Index Adviser: Plan using estimates for suggested indexes:
+
+Bitmap Heap Scan on t  (cost=8.54..16.21 rows=2 width=8)
+  Recheck Cond: ((a = 100) OR (b = 100))
+  ->  BitmapOr  (cost=8.54..8.54 rows=2 width=0)
+        ->  Bitmap Index Scan on idx_adv_0  (cost=0.00..4.27 rows=1 width=0)
+              Index Cond: (a = 100)
+        ->  Bitmap Index Scan on idx_adv_1  (cost=0.00..4.27 rows=1 width=0)
+              Index Cond: (b = 100)
+
+                     QUERY PLAN
+----------------------------------------------------
+ Seq Scan on t  (cost=0.00..2041.00 rows=2 width=8)
+   Filter: ((a = 100) OR (b = 100))
+(2 rows)
+
+postgres=>
+postgres=> /* now we shall test with T1 */;
+postgres=>
+postgres=> explain select * from t1 where a = 100;
+                      QUERY PLAN
+-------------------------------------------------------
+ Seq Scan on t1  (cost=0.00..1852.93 rows=525 width=8)
+   Filter: (a = 100)
+(2 rows)
+
+postgres=>
+postgres=> explain select * from t1 where b = 100;
+                      QUERY PLAN
+-------------------------------------------------------
+ Seq Scan on t1  (cost=0.00..1852.93 rows=525 width=8)
+   Filter: (b = 100)
+(2 rows)
+
+postgres=>
+postgres=> explain select * from t1 where a = 100 and b = 100;
+                     QUERY PLAN
+-----------------------------------------------------
+ Seq Scan on t1  (cost=0.00..2115.31 rows=3 width=8)
+   Filter: ((a = 100) AND (b = 100))
+(2 rows)
+
+postgres=>
+postgres=> explain select * from t1 where a = 100 or b = 100;
+                       QUERY PLAN
+--------------------------------------------------------
+ Seq Scan on t1  (cost=0.00..2115.31 rows=1047 width=8)
+   Filter: ((a = 100) OR (b = 100))
+(2 rows)
+
+postgres=>
+postgres=> /* let's do some sensible join over these two tables */;
+postgres=> explain
+postgres-> select       *
+postgres-> from t,
+postgres->              t1
+postgres-> where        t.a = 100
+postgres-> and          t1.a = 100
+postgres->      or t.b = 100
+postgres->              and t1.b = 100;
+LOG:  Index Adviser: Plan using estimates for suggested indexes:
+
+Nested Loop  (cost=8.54..7395.45 rows=1050 width=16)
+  Join Filter: (((t.a = 100) AND (t1.a = 100)) OR ((t.b = 100) AND (t1.b = 100)))
+  ->  Bitmap Heap Scan on t  (cost=8.54..16.21 rows=2 width=8)
+        Recheck Cond: ((a = 100) OR (b = 100))
+        ->  BitmapOr  (cost=8.54..8.54 rows=2 width=0)
+              ->  Bitmap Index Scan on idx_adv_0  (cost=0.00..4.27 rows=1 width=0)
+                    Index Cond: (a = 100)
+              ->  Bitmap Index Scan on idx_adv_1  (cost=0.00..4.27 rows=1 width=0)
+                    Index Cond: (b = 100)
+  ->  Seq Scan on t1  (cost=0.00..1590.54 rows=104954 width=8)
+
+                                    QUERY PLAN
+-----------------------------------------------------------------------------------
+ Nested Loop  (cost=0.00..368963541.00 rows=1050 width=16)
+   Join Filter: (((t.a = 100) AND (t1.a = 100)) OR ((t.b = 100) AND (t1.b = 100)))
+   ->  Seq Scan on t  (cost=0.00..1541.00 rows=100000 width=8)
+   ->  Seq Scan on t1  (cost=0.00..1590.54 rows=104954 width=8)
+(4 rows)
+
+postgres=>
+postgres=> /* following are the contents of the advise_index table */;
+postgres=> select * from advise_index;
+ reloid | attrs |    profit    | index_size | backend_pid |           timestamp
+--------+-------+--------------+------------+-------------+-------------------------------
+  16395 | {1}   |      1782.72 |       2608 |        2272 | 2007-01-13 12:30:02.39+05:30
+  16395 | {2}   |      1782.72 |       2608 |        2272 | 2007-01-13 12:30:02.531+05:30
+  16395 | {2}   |      2032.72 |       2608 |        2272 | 2007-01-13 12:30:02.578+05:30
+  16395 | {1}   |       1012.4 |       2608 |        2272 | 2007-01-13 12:30:02.64+05:30
+  16395 | {2}   |       1012.4 |       2608 |        2272 | 2007-01-13 12:30:02.64+05:30
+  16395 | {1}   | 1.84478e+008 |       2608 |        2272 | 2007-01-13 12:30:17.984+05:30
+  16395 | {2}   | 1.84478e+008 |       2608 |        2272 | 2007-01-13 12:30:17.984+05:30
+(7 rows)
+
+postgres=>
+postgres=> /* And following is the summary of the advices generated */;
+postgres=>
+postgres=> select       E'backend_pid\n'
+postgres->              ||      E'===========\n'
+postgres->              ||      backend_pid,
+postgres->              advise_index_show( backend_pid )
+postgres-> from (select distinct backend_pid
+postgres(>              from    advise_index as adv
+postgres(>              where   adv.reloid in   (select oid
+postgres(>                                       from pg_class
+postgres(>                                       where relkind = 'r')
+postgres(>      ) as v;
+  ?column?   |                         advise_index_show
+-------------+--------------------------------------------------------------------
+ backend_pid | /* Index Adviser */
+ =========== : /* ============= */
+ 2272        :
+             : /* size: 2608 KB, benefit: 1.84483e+008, gain: 70737.3067484663 */
+             : create index idx_t_b on t(b);
+             :
+             : /* size: 2608 KB, benefit: 1.84481e+008, gain: 70736.527607362 */
+             : create index idx_t_a on t(a);
+             :
+(1 row)
+
+postgres=>
index 0a762a260bafc57919d40050140ad3a36b5aaa0a..c9137b626569fe3e61a63b2a4517999b14a116f4 100644 (file)
@@ -1,13 +1,13 @@
-\r
-create view select_index_advisory as\r
-select E'backend_pid\n'\r
-       ||  E'===========\n'\r
-       ||  backend_pid,\r
-       show_index_advisory( backend_pid )\r
-from   (select distinct backend_pid\r
-       from    index_advisory as adv\r
-       /* do not consider tables that no longer exist */\r
-       where   exists (select  oid\r
-                               from    pg_class\r
-                               where   oid = adv.reloid)\r
-       ) as v;\r
+
+create or replace view select_index_advisory as
+select E'backend_pid\n'
+       ||  E'===========\n'
+       ||  backend_pid,
+       show_index_advisory( backend_pid )
+from   (select distinct backend_pid
+       from    index_advisory as adv
+       /* do not consider tables that no longer exist */
+       where   exists (select  oid
+                               from    pg_class
+                               where   oid = adv.reloid)
+       ) as v;
index 5764a90fd6821c10be34379ba6bb5d115087cc16..aba1e612750d730e655f68d94dc6fbb5651a7f41 100644 (file)
-\r
-create function show_index_advisory(p_backend_pid index_advisory.backend_pid%type) returns text\r
-as\r
-$$\r
-declare\r
-   pid       p_backend_pid%type;\r
-   q_advice  text;\r
-   r_advice  record;\r
-   q_column  text;\r
-   r_column  record;\r
-   ret       text;\r
-\r
-   NAMEDATALEN int := 64;\r
-\r
-   collist_w_C     text;   /* Column name list with commas */\r
-   collist_w_U     text;   /* Column name list with underscores */\r
-   colidlist_w_U   text;   /* Column id list with underscores */\r
-begin\r
-   if p_backend_pid is null then\r
-       pid = pg_backend_pid();\r
-   else\r
-       pid = p_backend_pid;\r
-   end if;\r
-\r
-   ret :=  '/* Index Adviser */' || E'\n' ||\r
-           '/* ============= */' || E'\n';\r
-\r
-   q_advice := 'SELECT c.relname,\r
-                       c.oid as reloid,\r
-                       a.attrs AS colids,\r
-                       MAX( a.index_size ) AS size_in_KB,\r
-                       SUM( a.profit ) AS benefit,\r
-                       SUM( a.profit )/MAX( a.index_size ) AS gain\r
-               FROM    index_advisory a,\r
-                       pg_class c\r
-               WHERE   a.backend_pid = ' || pid || '\r
-               AND     a.reloid = c.oid\r
-               GROUP BY    c.relname, c.oid, a.attrs\r
-               ORDER BY    gain\r
-                   DESC';\r
-                   \r
-   for r_advice in execute q_advice loop\r
-\r
-       ret := ret ||\r
-               E'\n/* size: ' || r_advice.size_in_KB || ' KB, '\r
-               || 'benefit: ' || r_advice.benefit || ', '\r
-               || 'gain: ' || r_advice.gain || E' */\n';\r
-\r
-       collist_w_C     := '';\r
-       collist_w_U     := '';\r
-       colidlist_w_U   := '';\r
-\r
-       for i in array_lower( r_advice.colids, 1 )\r
-                   .. array_upper( r_advice.colids, 1 )\r
-       loop\r
-\r
-           q_column := 'SELECT a.attname as name,\r
-                               a.attnum as id\r
-                       FROM    pg_class c,\r
-                               pg_attribute a\r
-                       WHERE   c.oid = ' || r_advice.reloid || '\r
-                       AND     a.attrelid = c.oid\r
-                       AND     a.attnum = ' || r_advice.colids[i] || '\r
-                       ';\r
-\r
-           execute q_column into r_column;\r
-\r
---         if ROW_COUNT > 1 then\r
---             raise EXCEPTION 'an internal query failed';\r
---         end if;\r
-\r
-           if i <> 1 then\r
-               collist_w_C     := collist_w_C      || ', ';\r
-               collist_w_U     := collist_w_U      || '_';\r
-               colidlist_w_U   := colidlist_w_U    || '_';\r
-           end if;\r
-\r
-           collist_w_C     := collist_w_C      || r_column.name;\r
-           collist_w_U     := collist_w_U      || r_column.name;\r
-           colidlist_w_U   := colidlist_w_U    || r_column.id;\r
-\r
-       end loop;\r
-\r
-       ret := ret || 'create index ';\r
-\r
-       if (length('idx_' || r_advice.relname || '_' || collist_w_U)\r
-               <= NAMEDATALEN)\r
-       then\r
-           ret := ret || 'idx_' || r_advice.relname    || '_' || collist_w_U;\r
-       else\r
-           ret := ret || 'idx_' || r_advice.reloid     || '_' || colidlist_w_U;\r
-       end if;\r
-\r
-       ret := ret || ' on ' || r_advice.relname || '(' || collist_w_C || E');\n';\r
-\r
-   end loop;\r
-\r
-  return ret;\r
-end;\r
-$$ language plpgsql;\r
+
+create or replace function show_index_advisory() returns text as $$
+   select show_index_advisory(null);
+$$ language sql;
+
+create or replace function show_index_advisory(p_backend_pid index_advisory.backend_pid%type) returns text as $$
+declare
+   pid       p_backend_pid%type;
+   q_advice  text;
+   r_advice  record;
+   q_column  text;
+   r_column  record;
+   ret       text;
+
+   NAMEDATALEN int := 64;
+
+   collist_w_C     text;   /* Column name list with commas */
+   collist_w_U     text;   /* Column name list with underscores */
+   colidlist_w_U   text;   /* Column id list with underscores */
+begin
+   if p_backend_pid is null then
+       pid = pg_backend_pid();
+   else
+       pid = p_backend_pid;
+   end if;
+
+   ret :=  '/* Index Adviser */' || E'\n' ||
+           '/* ============= */' || E'\n';
+
+   q_advice := 'SELECT c.relname,
+                       c.oid as reloid,
+                       a.attrs AS colids,
+                       MAX( a.index_size ) AS size_in_KB,
+                       SUM( a.profit ) AS benefit,
+                       SUM( a.profit )/MAX( a.index_size ) AS gain
+               FROM    index_advisory a,
+                       pg_class c
+               WHERE   a.backend_pid = ' || pid || '
+               AND     a.reloid = c.oid
+               GROUP BY    c.relname, c.oid, a.attrs
+               ORDER BY    gain
+                   DESC';
+                   
+   for r_advice in execute q_advice loop
+
+       ret := ret ||
+               E'\n/* size: ' || r_advice.size_in_KB || ' KB, '
+               || 'benefit: ' || r_advice.benefit || ', '
+               || 'gain: ' || r_advice.gain || E' */\n';
+
+       collist_w_C     := '';
+       collist_w_U     := '';
+       colidlist_w_U   := '';
+
+       for i in array_lower( r_advice.colids, 1 )
+                   .. array_upper( r_advice.colids, 1 )
+       loop
+
+           q_column := 'SELECT a.attname as name,
+                               a.attnum as id
+                       FROM    pg_class c,
+                               pg_attribute a
+                       WHERE   c.oid = ' || r_advice.reloid || '
+                       AND     a.attrelid = c.oid
+                       AND     a.attnum = ' || r_advice.colids[i] || '
+                       ';
+
+           execute q_column into r_column;
+
+--         if ROW_COUNT > 1 then
+--             raise EXCEPTION 'an internal query failed';
+--         end if;
+
+           if i <> 1 then
+               collist_w_C     := collist_w_C      || ', ';
+               collist_w_U     := collist_w_U      || '_';
+               colidlist_w_U   := colidlist_w_U    || '_';
+           end if;
+
+           collist_w_C     := collist_w_C      || r_column.name;
+           collist_w_U     := collist_w_U      || r_column.name;
+           colidlist_w_U   := colidlist_w_U    || r_column.id;
+
+       end loop;
+
+       ret := ret || 'create index ';
+
+       if (length('idx_' || r_advice.relname || '_' || collist_w_U)
+               <= NAMEDATALEN)
+       then
+           ret := ret || 'idx_' || r_advice.relname    || '_' || collist_w_U;
+       else
+           ret := ret || 'idx_' || r_advice.reloid     || '_' || colidlist_w_U;
+       end if;
+
+       ret := ret || ' on ' || r_advice.relname || '(' || collist_w_C || E');\n';
+
+   end loop;
+
+  return ret;
+end;
+$$ language plpgsql;