Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add query performance statistics #7869

Merged
merged 32 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
4b8d7b4
Fork the official pg_stat_statements extension from d5ca15ee54bf7faf0…
fantix Oct 15, 2024
6f36dca
Rename folder pg_stat_statements -> edb_stat_statements
fantix Oct 15, 2024
5eab017
Drop meson build for easier maintanence
fantix Oct 15, 2024
d363d78
Squash extension versions into 1.0
fantix Oct 15, 2024
75004d5
Rename the extension to edb_stat_statements
fantix Oct 15, 2024
21c11aa
Add editorconfig for PG extension
fantix Oct 16, 2024
3e459e2
Rename functions, views, gucs and namespaces to edb_stat_statements
fantix Oct 16, 2024
0a79cd4
Support Postgres 16, 17 and 18
fantix Oct 16, 2024
a98b33e
Build the extension in dev environment
fantix Sep 27, 2024
e3b512f
Honor EDGEDB_DEBUG=1 in building dev Postgres
fantix Oct 16, 2024
2929831
Add test to run extension installcheck
fantix Oct 16, 2024
284cbec
Add new backend capabilities for the extension
fantix Oct 4, 2024
158cc6b
Turn off stats without superuser access
fantix Oct 4, 2024
d76eb07
Main: add sys::QueryStats through edb_stat_statements
fantix Oct 16, 2024
4c5ec5f
Only show stats of the current tenant
fantix Oct 5, 2024
f1153ed
Implement the reset function
fantix Oct 5, 2024
ed36827
Track SQL queries in stats
fantix Oct 5, 2024
8e74a90
Merge remote-tracking branch 'origin/master' into query-stats-4
fantix Oct 22, 2024
44154bb
CRF: add comments and manually manage lifetime
fantix Oct 22, 2024
ac3b25e
Merge remote-tracking branch 'origin/master' into query-stats-4
fantix Oct 23, 2024
87c2c96
Merge remote-tracking branch 'origin/master' into query-stats-4
fantix Oct 24, 2024
cd5d408
Merge remote-tracking branch 'origin/master' into query-stats-4
fantix Nov 12, 2024
eb453cf
CRF: add annotations and fix test
fantix Nov 12, 2024
575517e
Merge remote-tracking branch 'origin/master' into query-stats-4
fantix Nov 15, 2024
1bc09fe
Fix merge
fantix Nov 17, 2024
f26c9c5
Allow multiple info lines in SQL
fantix Nov 17, 2024
ccaf5ac
Merge query_id and cache_key into a single `id`
fantix Nov 18, 2024
00f9cd5
Stop exposing query_id field, use id instead
fantix Nov 18, 2024
c7e861b
Merge remote-tracking branch 'origin/master' into query-stats-4
fantix Nov 19, 2024
9e1b40b
Add compilation settings as extras jsonb field
fantix Oct 7, 2024
ac41168
Don't add info JSON in DDL function body
fantix Nov 20, 2024
c5bec55
Add comments
fantix Nov 20, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ indent_style = space
indent_size = 2
indent_style = space

[ext/*.{c,cpp,h}]
indent_size = 4
[edb_stat_statements/*.{c,h,l,y,pl,pm}]
indent_style = tab
indent_size = tab
tab_width = 4
2 changes: 1 addition & 1 deletion edb/buildmeta.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
# The merge conflict there is a nice reminder that you probably need
# to write a patch in edb/pgsql/patches.py, and then you should preserve
# the old value.
EDGEDB_CATALOG_VERSION = 2024_11_12_01_00
EDGEDB_CATALOG_VERSION = 2024_11_15_00_00
EDGEDB_MAJOR_VERSION = 6


Expand Down
143 changes: 143 additions & 0 deletions edb/lib/sys.edgeql
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ CREATE SCALAR TYPE sys::VersionStage
EXTENDING enum<dev, alpha, beta, rc, final>;


CREATE SCALAR TYPE sys::QueryType
EXTENDING enum<EdgeQL, SQL>;


CREATE SCALAR TYPE sys::OutputFormat
EXTENDING enum<BINARY, JSON, JSON_ELEMENTS, NONE>;


CREATE ABSTRACT TYPE sys::SystemObject EXTENDING schema::Object;

CREATE ABSTRACT TYPE sys::ExternalObject EXTENDING sys::SystemObject;
Expand Down Expand Up @@ -86,6 +94,141 @@ ALTER TYPE sys::Role {
};


CREATE TYPE sys::QueryStats EXTENDING sys::ExternalObject {
CREATE LINK branch -> sys::Branch {
CREATE ANNOTATION std::description :=
"The branch this statistics entry was collected in.";
};
CREATE PROPERTY query -> std::str {
CREATE ANNOTATION std::description :=
"Text string of a representative query.";
};
CREATE PROPERTY query_type -> sys::QueryType {
CREATE ANNOTATION std::description :=
"Type of the query.";
};

CREATE PROPERTY compilation_config -> std::json;
CREATE PROPERTY protocol_version -> tuple<major: std::int16,
minor: std::int16>;
CREATE PROPERTY default_namespace -> std::str;
CREATE OPTIONAL PROPERTY namespace_aliases -> std::json;
CREATE OPTIONAL PROPERTY output_format -> sys::OutputFormat;
CREATE OPTIONAL PROPERTY expect_one -> std::bool;
CREATE OPTIONAL PROPERTY implicit_limit -> std::int64;
CREATE OPTIONAL PROPERTY inline_typeids -> std::bool;
CREATE OPTIONAL PROPERTY inline_typenames -> std::bool;
CREATE OPTIONAL PROPERTY inline_objectids -> std::bool;

CREATE PROPERTY plans -> std::int64 {
CREATE ANNOTATION std::description :=
"Number of times the query was planned in the backend.";
};
CREATE PROPERTY total_plan_time -> std::duration {
CREATE ANNOTATION std::description :=
"Total time spent planning the query in the backend.";
};
CREATE PROPERTY min_plan_time -> std::duration {
CREATE ANNOTATION std::description :=
"Minimum time spent planning the query in the backend. "
++ "This field will be zero if the counter has been reset "
++ "using the `sys::reset_query_stats` function "
++ "with the `minmax_only` parameter set to `true` "
++ "and never been planned since.";
};
CREATE PROPERTY max_plan_time -> std::duration {
CREATE ANNOTATION std::description :=
"Maximum time spent planning the query in the backend. "
++ "This field will be zero if the counter has been reset "
++ "using the `sys::reset_query_stats` function "
++ "with the `minmax_only` parameter set to `true` "
++ "and never been planned since.";
};
CREATE PROPERTY mean_plan_time -> std::duration {
CREATE ANNOTATION std::description :=
"Mean time spent planning the query in the backend.";
};
CREATE PROPERTY stddev_plan_time -> std::duration {
CREATE ANNOTATION std::description :=
"Population standard deviation of time spent "
++ "planning the query in the backend.";
};

CREATE PROPERTY calls -> std::int64 {
CREATE ANNOTATION std::description :=
"Number of times the query was executed.";
};
CREATE PROPERTY total_exec_time -> std::duration {
CREATE ANNOTATION std::description :=
"Total time spent executing the query in the backend.";
};
CREATE PROPERTY min_exec_time -> std::duration {
CREATE ANNOTATION std::description :=
"Minimum time spent executing the query in the backend, "
++ "this field will be zero until this query is executed "
++ "first time after reset performed by the "
++ "`sys::reset_query_stats` function with the "
++ "`minmax_only` parameter set to `true`";
};
CREATE PROPERTY max_exec_time -> std::duration {
CREATE ANNOTATION std::description :=
"Maximum time spent executing the query in the backend, "
++ "this field will be zero until this query is executed "
++ "first time after reset performed by the "
++ "`sys::reset_query_stats` function with the "
++ "`minmax_only` parameter set to `true`";
};
CREATE PROPERTY mean_exec_time -> std::duration {
CREATE ANNOTATION std::description :=
"Mean time spent executing the query in the backend.";
};
CREATE PROPERTY stddev_exec_time -> std::duration {
CREATE ANNOTATION std::description :=
"Population standard deviation of time spent "
++ "executing the query in the backend.";
};

CREATE PROPERTY rows -> std::int64 {
CREATE ANNOTATION std::description :=
"Total number of rows retrieved or affected by the query.";
};
CREATE PROPERTY stats_since -> std::datetime {
CREATE ANNOTATION std::description :=
"Time at which statistics gathering started for this query.";
};
CREATE PROPERTY minmax_stats_since -> std::datetime {
CREATE ANNOTATION std::description :=
"Time at which min/max statistics gathering started "
++ "for this query (fields `min_plan_time`, `max_plan_time`, "
++ "`min_exec_time` and `max_exec_time`).";
};
};


CREATE FUNCTION
sys::reset_query_stats(
named only branch_name: OPTIONAL std::str = {},
named only id: OPTIONAL std::uuid = {},
named only minmax_only: OPTIONAL std::bool = false,
) -> OPTIONAL std::datetime {
CREATE ANNOTATION std::description :=
'Discard query statistics gathered so far corresponding to the '
++ 'specified `branch_name` and `id`. If either of the '
++ 'parameters is not specified, the statistics that match with the '
++ 'other parameter will be reset. If no parameter is specified, '
++ 'it will discard all statistics. When `minmax_only` is `true`, '
++ 'only the values of minimum and maximum planning and execution '
++ 'time will be reset (i.e. `min_plan_time`, `max_plan_time`, '
++ '`min_exec_time` and `max_exec_time` fields). The default value '
++ 'for `minmax_only` parameter is `false`. This function returns '
++ 'the time of a reset. This time is saved to `stats_reset` or '
++ '`minmax_stats_since` field of `sys::QueryStats` if the '
++ 'corresponding reset was actually performed.';
SET volatility := 'Volatile';
USING SQL FUNCTION 'edgedb.reset_query_stats';
};


# An intermediate function is needed because we can't
# cast JSON to tuples yet. DO NOT use directly, it'll go away.
CREATE FUNCTION
Expand Down
Loading