Movatterモバイル変換


[0]ホーム

URL:



Facebook
Postgres Pro
Facebook
Downloads
F.3. aqo
Prev UpAppendix F. Additional Supplied Modules and Extensions Shipped inpostgrespro-std-14-contribHome Next

F.3. aqo

Theaqo module is aPostgres Pro Standard extension for cost-based query optimization. Using machine learning methods, more precisely, a modification of the k-NN algorithm,aqo improves cardinality estimation, which can optimize execution plans and, consequently, speed up query execution.

Theaqo module can collect statistics on all the executed queries, excluding the queries that access system relations. The collected statistics is classified by query class. If the queries differ in their constants only, they belong to the same class. For each query class,aqo stores the cardinality quality, planning time, execution time, and execution statistics for machine learning. Based on this data,aqo builds a new query plan and uses it for the next query of the same class.aqo test runs have shown significant performance improvements for complex queries.

Important

Query optimization using theaqo module is not supported on standby.

aqo saves all the learning data (aqo_data), queries (aqo_query_texts), query settings (aqo_queries), and query execution statistics (aqo_query_stat) to files. Whenaqo starts, it loads this data to shared memory. You can accessaqo data through functions and views.

Warning

Be aware thataqo may not work correctly right after extension upgrades that change its kernel and afterPostgres Pro upgrades. Therefore, after eachPostgres Pro upgrade, callaqo_reset() and runDROP EXTENSION aqo. However, afterPostgres Pro minor release upgrades to versions to 13.11/14.8/15.3 or higher a call toaqo_reset() is not needed asaqo is reset automatically if required.

After a minor release upgrade, also runALTER EXTENSION aqo UPDATE and keep in mind thataqo downgrade is impossible.

In the event of an automaticaqo reset or manually callingaqo_reset(), all the machine learning data gets lost, and new learning will be needed for futureaqo use. Therefore, if some data, such as query texts, may help inaqo learning, back up this data in advance.

F.3.1. Installation and Setup

Theaqo extension is included intoPostgres Pro Standard. Once you havePostgres Pro Standard installed, complete the following steps to enableaqo:

  1. Addaqo to theshared_preload_libraries parameter in thepostgresql.conf file:

    shared_preload_libraries = 'aqo'

    Theaqo library must be preloaded at the server startup, since adaptive query optimization needs to be enabled per cluster.

  2. Create theaqo extension using the following query:

    CREATE EXTENSION aqo;

Once the extension is created, you can start optimizing queries.

The command

DROP EXTENSION aqo;

will only removeaqo interface at the cluster level.aqo will still be running on all the backends while it is listed inshared_preload_libraries and at the server restart, will continue working in the operation mode specified inpostgresql.conf. Besides,aqo will retain its internal state after consequent execution ofDROP EXTENSION ->CREATE EXTENSION.

To remove all the data from theaqo storage, including the collected statistics, callaqo_reset():

SELECT aqo_reset();

To actually disableaqo at the cluster level, do the following:

ALTER SYSTEM SET aqo.mode = 'disabled';SELECT pg_reload_conf();DROP EXTENSION aqo;

If you do not wantaqo to be loaded at the server restart, remove the line

shared_preload_libraries = 'aqo'

from thepostgresql.conf file.

F.3.1.1. Configuration

With the default operation mode (controlled),aqo does not affect query performance. Depending on your database usage model, you should choose between the following modes:

  • intelligent — this mode auto-tunes your queries based on statistics collected per query class. See the description of theauto_tuning flag of theaqo_queries view for more details.

  • forced — this mode collects statistics for all queries altogether without any classification.

  • controlled — this mode uses the default planner for all new queries, but continues using the previously specified planning settings for already known query classes, if any.

  • learn — this mode collects statistics on all the executed queries and updates the data for query classes without auto-tuning queries.

  • frozen — this mode reads the collected statistics for already known query classes but does not collect any new data. You can use this mode to reduce the impact ofaqo on query planning and execution.

  • disabled — this mode disablesaqo for all queries, even for the known query classes. The collected statistics andaqo settings are saved and can be used in the future. You can use this mode to temporarily disableaqo without losing the collected statistics and configuration.

To dynamically change theaqo mode in your current session, run the following command:

ALTER SYSTEM SET aqo.mode = 'mode';SELECT pg_reload_conf();

wheremode is the name of the operation mode to use.

F.3.2. Usage

F.3.2.1. Choosing Operation Mode for Query Optimization

If you often run queries of the same class, for example, your application limits the number of possible query classes, you can use theintelligent mode to improve planning for these queries. In this mode,aqo analyzes each query execution and stores statistics. Statistics on queries of different classes is stored separately. If performance is not improved after 50 iterations, theaqo extension falls back to the default query planner.

Note

You can view the current query plan using the standardPostgres ProEXPLAIN command with theANALYZE option. For details, see theSection 14.1.

Since theintelligent mode tries to learn separately for different query classes,aqo may fail to provide performance improvements if queries in the workload are of multiple different classes or if the classes of the queries in the workload are constantly changing. For such workloads, reset theaqo extension to thecontrolled mode, or try using theforced mode.

In theforced mode,aqo does not classify the collected statistics by query classes and tries to optimize all queries together. Therefore,aqo_query_texts,aqo_queries andaqo_query_stat views do not get updated. Machine learning data collected in any other modes is inapplicable for theforced mode and vice versa. This mode can help you optimize workloads with multiple different query classes, and it consumes less memory than the intelligent mode. However, since theforced mode lacks intelligent tuning, performance may decrease for some queries. If you see performance issues in this mode, switchaqo to thecontrolled mode.

In thecontrolled mode,aqo does not collect statistics for new query classes, so they will not be optimized. For known query classes,aqo will continue collecting statistics and using optimized planning algorithms. So use thecontrolled mode only afteraqo learned in thelearn orintelligent mode. As there are no query classes in theforced mode, switching from it to thecontrolled mode actually means disablingaqo.

Thelearn mode collects statistics from all the executed queries and updates the data for query classes. This mode is similar to theintelligent mode, except that it does not provide intelligent tuning.

If you want to reduce the impact ofaqo on query planning and execution, you can use it in thefrozen mode. In this mode,aqo only reads the collected statistics for already known query classes but does not collect any new data.

Switching to thedisabled mode is the only way to actually disableaqo without losing the statistics andaqo settings, which are saved and can be used in the future. Queries in this mode will be executed as though there were noaqo at all.

F.3.2.2. Fine-Tuning aqo

You must have superuser rights to accessaqo views and configure advanced query settings.

When run in theintelligent orlearn mode,aqo assigns a unique hash value to each query class to separate the collected statistics. If you switch to theforced mode, the statistics for all untracked query classes is stored in a common query class with hash 0. You can view all the processed query classes and their corresponding hash values in theaqo_query_texts view:

SELECT * FROM aqo_query_texts;

To find out the class, that is, hash, of a query and aqo mode, enableaqo.show_hash andaqo.show_details environment variables and execute the query. The output will contain something like this:

...Planning Time: 23.538 ms...Execution Time: 249813.875 ms...Using aqo: true...AQO mode: LEARN...Query hash: -2439501042637610315

Each query class has an associated separate space, calledfeature space, in which the statistics for this query class is collected. Each feature space has associatedfeature subspaces, where the information about selectivity and cardinality for each query plan node is collected.

Each query class has its own optimization settings. These settings are shown in theaqo_queries view:

SELECT * FROM aqo_queries;

The settings available are listed in theaqo_queries View table.

You can manually change these settings to adjust optimization for a particular query class. For example:

 -- Add a new query class into the aqo_queries view:SET aqo.mode='intelligent';SELECT * FROM a, b WHERE a.id=b.id;SET aqo.mode='controlled'; -- Disable auto_tuning, enable both learn_aqo and use_aqo  -- for this query class:SELECT count(*) FROM (SELECT queryid FROM aqo_queries) AS q1,  LATERAL aqo_queries_update(q1.queryid, NULL, true, true, false) AS q2  WHERE queryid = (SELECT queryid FROM aqo_query_texts   WHERE query_text LIKE 'SELECT * FROM a, b WHERE a.id=b.id;'); -- Run EXPLAIN ANALYZE until the plan changes:EXPLAIN ANALYZE SELECT * FROM a, b WHERE a.id=b.id;EXPLAIN ANALYZE SELECT * FROM a, b WHERE a.id=b.id; -- Disable learning to stop statistics collection  -- and use the optimized plan: SELECT count(*) FROM (SELECT queryid FROM aqo_queries) AS q1,  LATERAL aqo_queries_update(q1.queryid, NULL, false, true, false) AS q2   WHERE queryid = (SELECT queryid FROM aqo_query_texts   WHERE query_text LIKE 'SELECT * FROM a, b WHERE a.id=b.id;');

To stop intelligent tuning for a particular query class, disable theauto_tuning setting:

SELECT count(*) FROM (SELECT queryid FROM aqo_queries) AS q1,  LATERAL aqo_queries_update(q1.queryid, NULL, true, true, false) AS q2  WHERE queryid = 'hash');

wherehash is the hash value for this query class. As a result,aqo disables automatic change of thelearn_aqo anduse_aqo settings.

To disable further learning for a particular query class, use the following command:

SELECT count(*) FROM (SELECT queryid FROM aqo_queries) AS q1,  LATERAL aqo_queries_update(q1.queryid, NULL, false, true, false) AS q2  WHERE queryid = 'hash');

wherehash is the hash value for this query class.

To fully disableaqo for all queries and use the defaultPostgres Pro query planner, run:

SELECT count(*) FROM (SELECT queryid FROM aqo_queries) AS q1,  LATERAL aqo_queries_update(q1.queryid, NULL, false, false, false) AS q2  WHERE queryid IN (SELECT queryid FROM aqo_query_texts);

F.3.3. Reference

F.3.3.1. Configuration Parameters

aqo.mode (text)

Defines theaqo operation mode. Possible values are listed inSection F.3.1.1.

Default:controlled.

aqo.show_hash (boolean)

Show a hash value that is computed from a query tree and uniquely identifies the class of queries or class of plan nodes. Starting withPostgres Pro 14,aqo uses the native query ID to identify a query class for consistency with other extensions, such aspg_stat_statements. So, the query ID can be taken from theQuery Identifier field inEXPLAIN ANALYZE output of a query.

Default:off.

aqo.show_details (boolean)

Add some details toEXPLAIN output of a query, such as the prediction or feature-subspace hash, and show some additionalaqo-specific on-screen information.

Default:off.

aqo.join_threshold (integer)

Ignore queries that contain smaller number of joins, which means that statistics for such queries will not be collected.

Default:3.

aqo.statement_timeout (integer)

Defines the initial value of thesmart statement timeout, in milliseconds, which is needed to limit the execution time when manually trainingaqo on special queries with a poor cardinality forecast.aqo can dynamically change the value of the smart statement timeout during this training. When the cardinality estimation error on nodes exceeds 0.1, the value ofaqo.statement_timeout is automatically incremented exponentially, but remains not greater thanstatement_timeout.

Default:0.

aqo.force_collect_stat (boolean)

Gather statistics on query executions even in thedisabled mode. Although no predictions are made, some overhead will be added.

Default:off.

aqo.dsm_size_max (integer)

Defines the maximum size of dynamic shared memory, in MB, thataqo can allocate to store learning data. When this number is exceeded, an attempt to load theaqo_data view will fail without of memory error.

Default:100.

aqo.fs_max_items (integer)

Defines the maximum number of feature spaces thataqo can operate with. When this number is exceeded, learning on new query classes will no longer occur, and they will not appear in the views accordingly.

Default:10000.

aqo.fss_max_items (integer)

Defines the maximum number of feature subspaces thataqo can operate with. When this number is exceeded, the selectivity and cardinality for new query plan nodes will no longer be collected, and new feature subspaces will not appear in theaqo_data view accordingly.

Default:100000.

aqo.wide_search (boolean)

Enables searching neighbors with the same feature subspace among different query classes.

Default:off.

aqo.querytext_max_size (integer)

Defines the maximum size of the query in theaqo_query_texts view.

Default:1000.

aqo.min_neighbors_for_predicting (integer)

Defines the minimum number of neighbors needed for the cardinality prediction. If there are fewer of them,aqo will not make any prediction.

Default:3.

aqo.predict_with_few_neighbors (boolean)

Enablesaqo to make predictions with fewer neighbors than were found.

Default:on.

F.3.3.2. Views

F.3.3.2.1. aqo_query_texts

Theaqo_query_texts view classifies all the query classes processed byaqo. For each query class, the view shows the text of the first analyzed query of this class.

Table F.2. aqo_query_texts View

Column NameDescription
queryidStores the query ID, that is, the feature-space hash, that uniquely identifies the query class.
query_textProvides the text of the first analyzed query of the given class.

F.3.3.2.2. aqo_queries

Theaqo_queries view shows optimization settings for different query classes.

Table F.3. aqo_queries View

SettingDescription
queryidStores the query ID that uniquely identifies the query class.
learn_aqoEnables statistics collection for this query class.
use_aqoEnables theaqo cardinality prediction for the next execution of this query class. If the cost estimation model is inaccurate, this may slow down query execution.
fspace_hashProvides a unique identifier of the separate space in which the statistics for this query class is collected. By default,fspace_hash is equal toqueryid. You can change this setting to a differentqueryid to optimize different query classes together. It may decrease the amount of memory for models and even improve query execution performance. However, changing this setting may cause unexpectedaqo behavior, so make sure to use it only if you know what you are doing.
auto_tuning

Shows whetheraqo can dynamically changeuse_aqo andlearn_aqo settings for this query class. By default, auto-tuning is only enabled in theintelligent mode.

In more detail, whenauto_tuning is on, if for several successive executions of a query for whichuse_aqo is off, the cardinality error remains sufficiently small and stable,aqo turns onuse_aqo.

For queries withlearn_aqo=true (it is so for new queries), several first executions are done both usingaqo and without it. The faster the query is executed compared to the execution with the standard planner, the more likelyaqo will be used for the next query execution. If after a certain number of executions the execution time withaqo appears to be worse than with the standard planner,aqo will never be used for this query class:auto_tuning,use_aqo andlearn_aqo are set tooff.

smart_timeoutShows the value of smart statement timeout for this query class.
count_increase_timeoutShows how many times the smart statement timeout increased for this query class.

F.3.3.2.3. aqo_data

Theaqo_data view shows machine learning data for cardinality estimation refinement. To forget all the collected statistics for a particular query class, you can delete all rows fromaqo_data with the correspondingfs.

Table F.4. aqo_data View

DataDescription
fsFeature-space hash.
fssFeature-subspace hash.
nfeaturesFeature-subspace size for the query plan node.
featuresLogarithm of the selectivity which the cardinality prediction is based on.
targetsCardinality logarithm for the query plan node.
reliabilityEquals:
  • 1 — indicates data obtained after normal execution of a query

  • 0.1 — indicates data obtained from a partially executed node (not needed as unreliable)

  • 0.9 — indicates data obtained from a finished node, but from a partially executed statement

oidsList of IDs of tables that were involved in the prediction for this node.

F.3.3.2.4. aqo_query_stat

Theaqo_query_stat view shows statistics on query execution, by query class. Theaqo extension uses this data when theauto_tuning option is enabled for a particular query class.

Table F.5. aqo_query_stat View

DataDescription
execution_time_with_aqoExecution time for queries run withaqo enabled.
execution_time_without_aqoExecution time for queries run withaqo disabled.
planning_time_with_aqoPlanning time for queries run withaqo enabled.
planning_time_without_aqoPlanning time for queries run withaqo disabled.
cardinality_error_with_aqoCardinality estimation error in the selected query plans withaqo enabled.
cardinality_error_without_aqoCardinality estimation error in the selected query plans withaqo disabled.
executions_with_aqoNumber of queries run withaqo enabled.
executions_without_aqoNumber of queries run withaqo disabled.

F.3.3.3. Functions

aqo adds several functions toPostgres Pro catalog.

F.3.3.3.1. Storage Management Functions

Important

Functionsaqo_queries_update,aqo_query_texts_update,aqo_query_stat_update, andaqo_data_update modify data files underlyingaqo views. Therefore, call these functions only if you understand the logic of adaptive query optimization.

aqo_cleanup() →setof integer

Removes data related to query classes that are linked (may be partially) with removed relations. Returns the number of removed feature spaces (classes) and feature subspaces. Insensitive to removing other objects.

aqo_enable_class (queryidbigint) →void

Setslearn_aqo,use_aqo andauto_tuning (only in theintelligent mode) to true for a given query class.

aqo_disable_class (queryidbigint) →void

Setslearn_aqo,use_aqo andauto_tuning (only in theintelligent mode) to false for a given query class.

aqo_drop_class (queryidbigint) →integer

Removes all data related to a given query class from theaqo storage. Returns the number of records removed from theaqo storage.

aqo_reset() →bigint

Removes data from theaqo storage: machine learning data, query texts, statistics and query class preferences. Returns the number of records removed from theaqo storage.

aqo_queries_update (queryidbigint,fsbigint,learn_aqoboolean,use_aqoboolean,auto_tuningboolean) →boolean

Assigns new values to the following settings in theaqo_queries view for a given query class:fspace_hash,learn_aqo,use_aqo andauto_tuning. NULL value meansleave as is.

aqo_query_texts_update (queryidbigint,query_texttext) →boolean

Updates or inserts a record in a data file underlying theaqo_query_texts view for a givenqueryid.

aqo_query_stat_update (queryidbigint,execution_time_with_aqodouble precision[],execution_time_without_aqodouble precision[],planning_time_with_aqodouble precision[],planning_time_without_aqodouble precision[],cardinality_error_with_aqodouble precision[],cardinality_error_without_aqodouble precision[],executions_with_aqobigint[],executions_without_aqobigint[]) →boolean

Updates or inserts a record in a data file underlying theaqo_query_stat view for a givenqueryid.

aqo_data_update (fsbigint,fssinteger,nfeaturesinteger,featuresdouble precision[][],targetsdouble precision[],reliabilitydouble precision[],oidsoid[]) →boolean

Updates or inserts a record in a data file underlying theaqo_data view for givenfs andfss.

F.3.3.3.2. Memory Management Functions
aqo_memory_usage () →setof record

Displays sizes ofaqo memory contexts and hash tables.

F.3.3.3.3. Analytics Functions
aqo_cardinality_error (controlledboolean) →setof record

Shows the cardinality error for each query class. Ifcontrolled is true, shows the error of the last execution withaqo enabled. Ifcontrolled is false, returns the average cardinality error for all logged executions withaqo disabled.

aqo_execution_time (controlledboolean) →setof record

Shows the execution time for each query class. Ifcontrolled is true, shows the execution time of the last execution withaqo enabled. Ifcontrolled is false, returns the average execution time for all logged executions withaqo disabled.

F.3.4. Examples

Example F.1. Learning on a Query

Consider optimization of a query usingaqo.

When the query is executed for the first time, it is missing in tables underlyingaqo views. So there is no data for predicting withaqo for each plan node, andAQO not used lines appear in theEXPLAIN output:

postgres=# EXPLAIN (ANALYZE, SUMMARY OFF, TIMING OFF) select count(*) from score join course on score.cno=course.cno join student on score.sno=student.sno where degree<90 and test_preparation = 0;                                                QUERY PLAN---------------------------------------------------------------------------------------------------------- Aggregate  (cost=308.28..308.29 rows=1 width=8) (actual rows=1 loops=1)   AQO not used, fss=0   ->  Hash Join  (cost=124.80..299.47 rows=3526 width=0) (actual rows=3649 loops=1)         AQO not used, fss=2128507884         Hash Cond: (score.sno = student.sno)         ->  Hash Join  (cost=16.30..181.70 rows=3526 width=4) (actual rows=3649 loops=1)               AQO not used, fss=-303037802               Hash Cond: (score.cno = course.cno)               ->  Seq Scan on score  (cost=0.00..156.00 rows=3526 width=8) (actual rows=3649 loops=1)                     AQO not used, fss=-636613046                     Filter: ((degree < 90) AND (test_preparation = 0))                     Rows Removed by Filter: 1351               ->  Hash  (cost=12.80..12.80 rows=280 width=4) (actual rows=10 loops=1)                     Buckets: 1024  Batches: 1  Memory Usage: 9kB                     ->  Seq Scan on course  (cost=0.00..12.80 rows=280 width=4) (actual rows=10 loops=1)                           AQO not used, fss=-1076069505         ->  Hash  (cost=71.00..71.00 rows=3000 width=4) (actual rows=3000 loops=1)               Buckets: 4096  Batches: 1  Memory Usage: 138kB               ->  Seq Scan on student  (cost=0.00..71.00 rows=3000 width=4) (actual rows=3000 loops=1)                     AQO not used, fss=-1838231581 Using aqo: true AQO mode: LEARN Query hash: -727505571757520766 JOINS: 2(24 rows)

If there is no information on a certain node in theaqo_data view,aqo will add the appropriate record there for future learning and predictions except for nodes withfss=0 in theEXPLAIN output. As each offeatures andtargets in theaqo_data view is a logarithm to basee, to get the actual value, raisee to this power. For example: exp(0):

         fs          |     fss     | nfeatures |                                      features                                      |       targets       | reliability |        oids---------------------+-------------+-----------+------------------------------------------------------------------------------------+---------------------+-------------+--------------------- -727505571757520766 |  2128507884 |         4 | {{-0.03438753143452488,-5.634789603169249,-0.3149847743198556,-8.006367567650246}} | {8.202208436436448} | {1}         | {16579,16555,16563} -727505571757520766 | -1076069505 |         0 |                                                                                    | {2.302585092994046} | {1}         | {16555} -727505571757520766 | -1838231581 |         0 |                                                                                    | {8.006367567650246} | {1}         | {16563} -727505571757520766 |  -303037802 |         3 | {{-0.03438753143452488,-5.634789603169249,-0.3149847743198556}}                    | {8.202208436436448} | {1}         | {16579,16555} -727505571757520766 |  -636613046 |         2 | {{-0.03438753143452488,-0.3149847743198556}}                                       | {8.202208436436448} | {1}         | {16579}(6 rows)

When the query is executed for the second time,aqo recognizes the query and makes a prediction. Pay attention to the cardinality predicted byaqo and the value ofaqo error (error=0%).

postgres=# EXPLAIN (ANALYZE, SUMMARY OFF, TIMING OFF) select count(*) from score join course on score.cno=course.cno join student on score.sno=student.sno where degree<90 and test_preparation = 0;                                               QUERY PLAN--------------------------------------------------------------------------------------------------------- Aggregate  (cost=305.86..305.87 rows=1 width=8) (actual rows=1 loops=1)   AQO not used, fss=0   ->  Hash Join  (cost=121.42..296.74 rows=3649 width=0) (actual rows=3649 loops=1)         AQO: rows=3649, error=0%, fss=2128507884         Hash Cond: (score.sno = student.sno)         ->  Hash Join  (cost=12.93..178.65 rows=3649 width=4) (actual rows=3649 loops=1)               AQO: rows=3649, error=0%, fss=-303037802               Hash Cond: (score.cno = course.cno)               ->  Seq Scan on score  (cost=0.00..156.00 rows=3649 width=8) (actual rows=3649 loops=1)                     AQO: rows=3649, error=0%, fss=-636613046                     Filter: ((degree < 90) AND (test_preparation = 0))                     Rows Removed by Filter: 1351               ->  Hash  (cost=12.80..12.80 rows=10 width=4) (actual rows=10 loops=1)                     Buckets: 1024  Batches: 1  Memory Usage: 9kB                     ->  Seq Scan on course  (cost=0.00..12.80 rows=10 width=4) (actual rows=10 loops=1)                           AQO: rows=10, error=0%, fss=-1076069505         ->  Hash  (cost=71.00..71.00 rows=3000 width=4) (actual rows=3000 loops=1)               Buckets: 4096  Batches: 1  Memory Usage: 138kB               ->  Seq Scan on student  (cost=0.00..71.00 rows=3000 width=4) (actual rows=3000 loops=1)                     AQO: rows=3000, error=0%, fss=-1838231581 Using aqo: true AQO mode: LEARN Query hash: -727505571757520766 JOINS: 2(24 rows)

In case of an error, values offeatures andtargets must change, but as there was no error above, they did not change.

         fs          |     fss     | nfeatures |                                      features                                      |       targets       | reliability |        oids---------------------+-------------+-----------+------------------------------------------------------------------------------------+---------------------+-------------+--------------------- -727505571757520766 |  2128507884 |         4 | {{-0.03438753143452488,-5.634789603169249,-0.3149847743198556,-8.006367567650246}} | {8.202208436436448} | {1}         | {16579,16555,16563} -727505571757520766 | -1076069505 |         0 |                                                                                    | {2.302585092994046} | {1}         | {16555} -727505571757520766 | -1838231581 |         0 |                                                                                    | {8.006367567650246} | {1}         | {16563} -727505571757520766 |  -303037802 |         3 | {{-0.03438753143452488,-5.634789603169249,-0.3149847743198556}}                    | {8.202208436436448} | {1}         | {16579,16555} -727505571757520766 |  -636613046 |         2 | {{-0.03438753143452488,-0.3149847743198556}}                                       | {8.202208436436448} | {1}         | {16579}(6 rows)

Let's change a constant in the query, and you will notice that the prediction is made with an error:

    postgres=# EXPLAIN (ANALYZE, SUMMARY OFF, TIMING OFF) select count(*) from score join course on score.cno=course.cno join student on score.sno=student.sno where degree<80 and test_preparation = 0;                                                   QUERY PLAN--------------------------------------------------------------------------------------------------------- Aggregate  (cost=305.86..305.87 rows=1 width=8) (actual rows=1 loops=1)   AQO not used, fss=0   ->  Hash Join  (cost=121.42..296.74 rows=3649 width=0) (actual rows=3551 loops=1)         AQO: rows=3649, error=3%, fss=2128507884         Hash Cond: (score.sno = student.sno)         ->  Hash Join  (cost=12.93..178.65 rows=3649 width=4) (actual rows=3551 loops=1)               AQO: rows=3649, error=3%, fss=-303037802               Hash Cond: (score.cno = course.cno)               ->  Seq Scan on score  (cost=0.00..156.00 rows=3649 width=8) (actual rows=3551 loops=1)                     AQO: rows=3649, error=3%, fss=-636613046                     Filter: ((degree < 80) AND (test_preparation = 0))                     Rows Removed by Filter: 1449               ->  Hash  (cost=12.80..12.80 rows=10 width=4) (actual rows=10 loops=1)                     Buckets: 1024  Batches: 1  Memory Usage: 9kB                     ->  Seq Scan on course  (cost=0.00..12.80 rows=10 width=4) (actual rows=10 loops=1)                           AQO: rows=10, error=0%, fss=-1076069505         ->  Hash  (cost=71.00..71.00 rows=3000 width=4) (actual rows=3000 loops=1)               Buckets: 4096  Batches: 1  Memory Usage: 138kB               ->  Seq Scan on student  (cost=0.00..71.00 rows=3000 width=4) (actual rows=3000 loops=1)                     AQO: rows=3000, error=0%, fss=-1838231581 Using aqo: true AQO mode: LEARN Query hash: -727505571757520766 JOINS: 2(24 rows)

However, instead of recalculatingfeatures andtargets,aqo added new values of selectivity and cardinality for this query toaqo_data:

         fs          |     fss     | nfeatures |                                                                               features                                                                               |                targets                | reliability |        oids---------------------+-------------+-----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------+-------------+--------------------- -727505571757520766 |  1141621836 |         0 |                                                                                                                                                                      | {0}                                   | {1}         | {16579,16555,16563} -727505571757520766 |  2128507884 |         4 | {{-0.030949078292235133,-5.634789603169249,-0.3149847743198556,-8.006367567650246},{-0.34221288089027607,-5.634789603169249,-0.3149847743198556,-8.006367567650246}} | {8.202208436436448,8.174984532943087} | {1,1}       | {16579,16555,16563} -727505571757520766 | -1076069505 |         0 |                                                                                                                                                                      | {2.302585092994046}                   | {1}         | {16555} -727505571757520766 | -1838231581 |         0 |                                                                                                                                                                      | {8.006367567650246}                   | {1}         | {16563} -727505571757520766 |  -303037802 |         3 | {{-0.030949078292235133,-5.634789603169249,-0.3149847743198556},{-0.34221288089027607,-5.634789603169249,-0.3149847743198556}}                                       | {8.202208436436448,8.174984532943087} | {1,1}       | {16579,16555} -727505571757520766 |  -636613046 |         2 | {{-0.030949078292235133,-0.3149847743198556},{-0.34221288089027607,-0.3149847743198556}}

Now the prediction has no error:

postgres=# EXPLAIN (ANALYZE, SUMMARY OFF, TIMING OFF) select count(*) from score join course on score.cno=course.cno join student on score.sno=student.sno where degree<80 and test_preparation = 0;                                               QUERY PLAN--------------------------------------------------------------------------------------------------------- Aggregate  (cost=305.10..305.11 rows=1 width=8) (actual rows=1 loops=1)   AQO not used, fss=0   ->  Hash Join  (cost=121.42..296.22 rows=3551 width=0) (actual rows=3551 loops=1)         AQO: rows=3551, error=0%, fss=2128507884         Hash Cond: (score.sno = student.sno)         ->  Hash Join  (cost=12.93..178.39 rows=3551 width=4) (actual rows=3551 loops=1)               AQO: rows=3551, error=0%, fss=-303037802               Hash Cond: (score.cno = course.cno)               ->  Seq Scan on score  (cost=0.00..156.00 rows=3551 width=8) (actual rows=3551 loops=1)                     AQO: rows=3551, error=0%, fss=-636613046                     Filter: ((degree < 80) AND (test_preparation = 0))                     Rows Removed by Filter: 1449               ->  Hash  (cost=12.80..12.80 rows=10 width=4) (actual rows=10 loops=1)                     Buckets: 1024  Batches: 1  Memory Usage: 9kB                     ->  Seq Scan on course  (cost=0.00..12.80 rows=10 width=4) (actual rows=10 loops=1)                           AQO: rows=10, error=0%, fss=-1076069505         ->  Hash  (cost=71.00..71.00 rows=3000 width=4) (actual rows=3000 loops=1)               Buckets: 4096  Batches: 1  Memory Usage: 138kB               ->  Seq Scan on student  (cost=0.00..71.00 rows=3000 width=4) (actual rows=3000 loops=1)                     AQO: rows=3000, error=0%, fss=-1838231581 Using aqo: true AQO mode: LEARN Query hash: -727505571757520766 JOINS: 2(24 rows)


Example F.2. Using theaqo_query_stat View

Theaqo_query_stats view shows statistics on the query planning time, query execution time and cardinality error. Based on this data you can make a decision whether to useaqo predictions for different query classes.

Let's query theaqo_query_stats view:

select queryid, cardinality_error_with_aqo, cardinality_error_without_aqo,execution_time_with_aqo, execution_time_without_aqo, planning_time_with_aqo, planning_time_without_aqo from aqo_query_stat \gx-[ RECORD 1 ]-----------------+------------------------------------------------------------------------------------------------------------queryid                       | 8041624334006338922cardinality_error_with_aqo    | {0.14932737556062836,0,0.507421202801325,0.00040469447777891077}cardinality_error_without_aqo | {0.1493979460962751,0.018403615483185476}execution_time_with_aqo       | {0.004760108,0.008743075,0.006608304,0.012392751}execution_time_without_aqo    | {0.005775926,0.012730316}planning_time_with_aqo        | {0.006927997,0.004247339,0.005005022,0.004169717}planning_time_without_aqo     | {0.001783542,0.001706121}

The retrieved data is for the query fromExample F.1, which was executed once withoutaqo for each of the parametersdegree<80 anddegree<90 and twice withaqo for each of these parameters. It is clear that withaqo, the cardinality error decreases to 0.0004, while the minimum cardinality error withoutaqo is 0.15. Besides, the execution time withaqo is lower than without it. So the conclusion is thataqo learns well on this query, and the prediction can be used for this query class.


F.3.5. Author

Oleg Ivanov


Prev Up Next
F.2. amcheck Home F.4. auth_delay
pdfepub
Go to Postgres Pro Standard 14
By continuing to browse this website, you agree to the use of cookies. Go toPrivacy Policy.

[8]ページ先頭

©2009-2025 Movatter.jp