README.md in pgdexter-0.4.3 vs README.md in pgdexter-0.5.0

- old
+ new

@@ -16,32 +16,32 @@ cd hypopg-1.3.1 make make install # may need sudo ``` -> Note: If you have issues, make sure `postgresql-server-dev-*` is installed. +And enable it in databases where you want to use Dexter: -Enable logging for slow queries in your Postgres config file. - -```ini -log_min_duration_statement = 10 # ms +```sql +CREATE EXTENSION hypopg; ``` -And install the command line tool with: +See the [installation notes](#hypopg-installation-notes) if you run into issues. +Then install the command line tool with: + ```sh gem install pgdexter ``` The command line tool is also available with [Docker](#docker), [Homebrew](#homebrew), or as a [Linux package](guides/Linux.md). ## How to Use -Dexter needs a connection to your database and a log file to process. +Dexter needs a connection to your database and a source of queries (like [pg_stat_statements](https://www.postgresql.org/docs/current/pgstatstatements.html)) to process. ```sh -tail -F -n +1 <log-file> | dexter <connection-options> +dexter -d dbname --pg-stat-statements ``` This finds slow queries and generates output like: ``` @@ -51,11 +51,10 @@ Index found: public.genres_movies (movie_id) Index found: public.movies (title) Index found: public.ratings (movie_id) Index found: public.ratings (rating) Index found: public.ratings (user_id) -Processing 12 new query fingerprints ``` To be safe, Dexter will not create indexes unless you pass the `--create` flag. In this case, you’ll see: ``` @@ -82,76 +81,121 @@ ``` host=localhost port=5432 dbname=mydb ``` +Always make sure your [connection is secure](https://ankane.org/postgres-sslmode-explained) when connecting to a database over a network you don’t fully trust. + ## Collecting Queries -There are many ways to collect queries. For real-time indexing, pipe your logfile: +Dexter can collect queries from a number of sources. +- [Query stats](#query-stats) +- [Live queries](#live-queries) +- [Log files](#log-file) +- [SQL files](#sql-files) + +### Query Stats + +Enable [pg_stat_statements](https://www.postgresql.org/docs/current/pgstatstatements.html) in your database. + +```psql +CREATE EXTENSION pg_stat_statements; +``` + +And use: + ```sh -tail -F -n +1 <log-file> | dexter <connection-options> +dexter <connection-options> --pg-stat-statements ``` -Pass a single statement with: +### Live Queries +Get live queries from the [pg_stat_activity](https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-ACTIVITY-VIEW) view with: + ```sh -dexter <connection-options> -s "SELECT * FROM ..." +dexter <connection-options> --pg-stat-activity ``` -or pass files: +### Log Files +Enable logging for slow queries in your Postgres config file. + +```ini +log_min_duration_statement = 10 # ms +``` + +And use: + ```sh -dexter <connection-options> <file1> <file2> +dexter <connection-options> postgresql.log ``` -or collect running queries with: +Supports `stderr`, `csvlog`, and `jsonlog` formats. +For real-time indexing, pipe your logfile: + ```sh -dexter <connection-options> --pg-stat-activity +tail -F -n +1 postgresql.log | dexter <connection-options> --stdin ``` -### Collection Options +And pass `--input-format csvlog` or `--input-format jsonlog` if needed. -To prevent one-off queries from being indexed, specify a minimum number of calls before a query is considered for indexing +### SQL Files +Pass a SQL file with: + ```sh -dexter --min-calls 100 +dexter <connection-options> queries.sql ``` -You can do the same for total time a query has run +Pass a single query with: ```sh -dexter --min-time 10 # minutes +dexter <connection-options> -s "SELECT * FROM ..." ``` -Specify the format +## Collection Options +To prevent one-off queries from being indexed, specify a minimum number of calls before a query is considered for indexing + ```sh -dexter --input-format csv +dexter --min-calls 100 ``` +You can do the same for total time a query has run + +```sh +dexter --min-time 10 # minutes +``` + When streaming logs, specify the time to wait between processing queries ```sh dexter --interval 60 # seconds ``` ## Examples -Ubuntu with PostgreSQL 12 +Postgres package on Ubuntu 22.04 ```sh -tail -F -n +1 /var/log/postgresql/postgresql-12-main.log | sudo -u postgres dexter dbname +sudo -u postgres dexter -d dbname /var/log/postgresql/postgresql-14-main.log ``` -Homebrew on Mac +Homebrew Postgres on Mac ARM ```sh -tail -F -n +1 /usr/local/var/postgres/server.log | dexter dbname +dexter -d dbname /opt/homebrew/var/log/postgresql@14.log ``` +Homebrew Postgres on Mac x86-64 + +```sh +dexter -d dbname /usr/local/var/log/postgresql@14.log +``` + ## Analyze For best results, make sure your tables have been recently analyzed so statistics are up-to-date. You can ask Dexter to analyze tables it comes across that haven’t been analyzed in the past hour with: ```sh @@ -188,10 +232,34 @@ - Amazon RDS - follow the instructions on [this page](https://aws.amazon.com/rds/postgresql/faqs/) - Google Cloud SQL - vote or comment on [this page](https://issuetracker.google.com/issues/69250435) - DigitalOcean Managed Databases - vote or comment on [this page](https://ideas.digitalocean.com/app-framework-services/p/support-hypopg-for-postgres) +## HypoPG Installation Notes + +### Postgres Location + +If your machine has multiple Postgres installations, specify the path to [pg_config](https://www.postgresql.org/docs/current/app-pgconfig.html) with: + +```sh +export PG_CONFIG=/Applications/Postgres.app/Contents/Versions/latest/bin/pg_config +``` + +Then re-run the installation instructions (run `make clean` before `make` if needed) + +### Missing Header + +If compilation fails with `fatal error: postgres.h: No such file or directory`, make sure Postgres development files are installed on the server. + +For Ubuntu and Debian, use: + +```sh +sudo apt-get install postgresql-server-dev-15 +``` + +Note: Replace `15` with your Postgres server version + ## Additional Installation Methods ### Docker Get the [Docker image](https://hub.docker.com/r/ankane/dexter) with: @@ -211,16 +279,16 @@ ### Homebrew With Homebrew, you can use: ```sh -brew install ankane/brew/dexter +brew install dexter ``` ## Future Work -[Here are some ideas](https://github.com/ankane/dexter/issues/1) +[Here are some ideas](https://github.com/ankane/dexter/issues/45) ## Upgrading Run: @@ -233,12 +301,22 @@ ```sh gem install specific_install gem specific_install https://github.com/ankane/dexter.git ``` +## Upgrade Notes + +### 0.5.0 + +The `--stdin` option is now required to read queries from stdin. + +```sh +tail -F -n +1 postgresql.log | dexter <connection-options> --stdin +``` + ## Thanks -This software wouldn’t be possible without [HypoPG](https://github.com/HypoPG/hypopg), which allows you to create hypothetical indexes, and [pg_query](https://github.com/lfittl/pg_query), which allows you to parse and fingerprint queries. A big thanks to Dalibo and Lukas Fittl respectively. +This software wouldn’t be possible without [HypoPG](https://github.com/HypoPG/hypopg), which allows you to create hypothetical indexes, and [pg_query](https://github.com/lfittl/pg_query), which allows you to parse and fingerprint queries. A big thanks to Dalibo and Lukas Fittl respectively. Also, thanks to YugabyteDB for [this article](https://dev.to/yugabyte/explain-from-pgstatstatements-normalized-queries-how-to-always-get-the-generic-plan-in--5cfi) on how to explain normalized queries. ## Research This is known as the Index Selection Problem (ISP).