MySQL 8.4.2
Source Code Documentation
|
Code used for calculating and manipulating table statistics. More...
#include "my_dbug.h"
#include <mysql_com.h>
#include <algorithm>
#include <map>
#include <vector>
#include <scope_guard.h>
#include "dict0stats.h"
#include "dyn0buf.h"
#include "ha_prototypes.h"
#include "lob0lob.h"
#include "m_string.h"
#include "pars0pars.h"
#include "row0sel.h"
#include "trx0trx.h"
#include "univ.i"
#include "ut0new.h"
#include "ut0rnd.h"
#include "ut0ut.h"
Classes | |
struct | n_diff_data_t |
Input data that is used to calculate dict_index_t::stat_n_diff_key_vals[] for each n-columns prefix (n from 1 to n_uniq). More... | |
struct | index_fetch_t |
Aux struct used to pass a table and a boolean to dict_stats_fetch_index_stats_step(). More... | |
Macros | |
#define | TABLE_STATS_NAME "mysql/innodb_table_stats" |
#define | TABLE_STATS_NAME_PRINT "mysql.innodb_table_stats" |
#define | INDEX_STATS_NAME "mysql/innodb_index_stats" |
#define | INDEX_STATS_NAME_PRINT "mysql.innodb_index_stats" |
#define | DEBUG_PRINTF(fmt, ...) /* noop */ |
#define | N_SAMPLE_PAGES(index) |
#define | N_DIFF_REQUIRED(index) (N_SAMPLE_PAGES(index) * 10) |
#define | INDEX_EQ(i1, i2) |
#define | PFX "n_diff_pfx" |
#define | PFX_LEN 10 |
Typedefs | |
typedef std::vector< uint64_t, ut::allocator< uint64_t > > | boundaries_t |
typedef ut::allocator< std::pair< const char *const, dict_index_t * > > | index_map_t_allocator |
Allocator type used for index_map_t. More... | |
typedef std::map< const char *, dict_index_t *, ut_strcmp_functor, index_map_t_allocator > | index_map_t |
Auxiliary map used for sorting indexes by name in dict_stats_save(). More... | |
Enumerations | |
enum | page_scan_method_t { COUNT_ALL_NON_BORING_AND_SKIP_DEL_MARKED , QUIT_ON_FIRST_NON_BORING , COUNT_ALL_NON_BORING_INCLUDE_DEL_MARKED } |
aux enum for controlling the behavior of dict_stats_scan_page() More... | |
Functions | |
static bool | dict_stats_should_ignore_index (const dict_index_t *index) |
Checks whether an index should be ignored in stats manipulations: More... | |
static dberr_t | dict_stats_exec_sql (pars_info_t *pinfo, const char *sql, trx_t *trx) |
Executes a given SQL statement using the InnoDB internal SQL parser. More... | |
static dict_table_t * | dict_stats_table_clone_create (const dict_table_t *table) |
Duplicate a table object and its indexes. More... | |
static void | dict_stats_table_clone_free (dict_table_t *t) |
Free the resources occupied by an object returned by dict_stats_table_clone_create(). More... | |
static void | dict_stats_empty_index (dict_index_t *index) |
Write all zeros (or 1 where it makes sense) into an index statistics members. More... | |
static void | dict_stats_empty_table (dict_table_t *table) |
Write all zeros (or 1 where it makes sense) into a table and its indexes' statistics members. More... | |
static void | dict_stats_assert_initialized_index (const dict_index_t *index[[maybe_unused]]) |
Check whether index's stats are initialized (assert if they are not). More... | |
static void | dict_stats_assert_initialized (const dict_table_t *table) |
Check whether table's stats are initialized (assert if they are not). More... | |
static void | dict_stats_copy (dict_table_t *dst, const dict_table_t *src) |
Copy table and index statistics from one table to another, including index stats. More... | |
static dict_table_t * | dict_stats_snapshot_create (dict_table_t *table) |
Duplicate the stats of a table and its indexes. More... | |
static void | dict_stats_snapshot_free (dict_table_t *t) |
Free the resources occupied by an object returned by dict_stats_snapshot_create(). More... | |
static void | dict_stats_update_transient_for_index (dict_index_t *index) |
Calculates new estimates for index statistics. More... | |
static void | dict_stats_update_transient (dict_table_t *table) |
Calculates new estimates for table and index statistics. More... | |
static bool | dict_stats_index_long_waiters (dict_index_t *index, std::chrono::steady_clock::time_point &wait_start_time) |
Confirms long waiters for the index lock exist. More... | |
static bool | dict_stats_analyze_index_level (dict_index_t *index, ulint level, uint64_t *n_diff, uint64_t *total_recs, uint64_t *total_pages, boundaries_t *n_diff_boundaries, std::chrono::steady_clock::time_point &wait_start_time, mtr_t *mtr) |
Find the total number and the number of distinct keys on a given level in an index. More... | |
static ulint * | dict_stats_scan_page (const rec_t **out_rec, ulint *offsets1, ulint *offsets2, const dict_index_t *index, const page_t *page, ulint n_prefix, page_scan_method_t scan_method, uint64_t *n_diff, uint64_t *n_external_pages) |
Scan a page, reading records from left to right and counting the number of distinct records (looking only at the first n_prefix columns) and the number of external pages pointed by records from this page. More... | |
static void | dict_stats_analyze_index_below_cur (const btr_cur_t *cur, ulint n_prefix, uint64_t *n_diff, uint64_t *n_external_pages) |
Dive below the current position of a cursor and calculate the number of distinct records on the leaf page, when looking at the fist n_prefix columns. More... | |
static bool | dict_stats_analyze_index_for_n_prefix (dict_index_t *index, ulint n_prefix, const boundaries_t *boundaries, n_diff_data_t *n_diff_data, std::chrono::steady_clock::time_point &wait_start_time, mtr_t *mtr) |
Estimate the number of different key values in an index when looking at the first n_prefix columns. More... | |
static void | dict_stats_index_set_n_diff (const n_diff_data_t *n_diff_data, dict_index_t *index) |
Set dict_index_t::stat_n_diff_key_vals[] and stat_n_sample_sizes[]. More... | |
static bool | dict_stats_analyze_index_low (uint64_t &n_sample_pages, dict_index_t *index) |
Calculates new statistics for a given index and saves them to the index members stat_n_diff_key_vals[], stat_n_sample_sizes[], stat_index_size and stat_n_leaf_pages, based on the specified n_sample_pages. More... | |
static void | dict_stats_analyze_index (dict_index_t *index) |
Calculates new statistics for a given index and saves them to the index members stat_n_diff_key_vals[], stat_n_sample_sizes[], stat_index_size and stat_n_leaf_pages. More... | |
static dberr_t | dict_stats_update_persistent (dict_table_t *table) |
Calculates new estimates for table and index statistics. More... | |
static dberr_t | dict_stats_save_index_stat (dict_index_t *index, lint last_update, const char *stat_name, uint64_t stat_value, uint64_t *sample_size, const char *stat_description, trx_t *trx) |
Save an individual index's statistic into the persistent statistics storage. More... | |
static dberr_t | dict_stats_save (dict_table_t *table_orig, const index_id_t *only_for_index, trx_t *trx) |
Save the table's statistics into the persistent statistics storage. More... | |
static bool | dict_stats_fetch_table_stats_step (void *node_void, void *table_void) |
Called for the row that is selected by SELECT ... FROM mysql.innodb_table_stats WHERE table='...' The second argument is a pointer to the table and the fetched stats are written to it. More... | |
static bool | dict_stats_fetch_index_stats_step (void *node_void, void *arg_void) |
Called for the rows that are selected by SELECT ... FROM mysql.innodb_index_stats WHERE table='...' The second argument is a pointer to the table and the fetched stats are written to its indexes. More... | |
static dberr_t | dict_stats_fetch_from_ps (dict_table_t *table) |
Read table's statistics from the persistent statistics storage. More... | |
void | dict_stats_update_for_index (dict_index_t *index) |
Fetches or calculates new estimates for index statistics. More... | |
dberr_t | dict_stats_update (dict_table_t *table, dict_stats_upd_option_t stats_upd_option, trx_t *trx) |
Calculates new estimates for table and index statistics. More... | |
dberr_t | dict_stats_drop_index (const char *db_and_table, const char *iname, char *errstr, ulint errstr_sz) |
Removes the information for a particular index's stats from the persistent storage if it exists and if there is data stored for this index. More... | |
static dberr_t | dict_stats_delete_from_table_stats (const char *database_name, const char *table_name) |
Executes DELETE FROM mysql.innodb_table_stats WHERE database_name = '...' AND table_name = '...'; Creates its own transaction and commits it. More... | |
static dberr_t | dict_stats_delete_from_index_stats (const char *database_name, const char *table_name) |
Executes DELETE FROM mysql.innodb_index_stats WHERE database_name = '...' AND table_name = '...'; Creates its own transaction and commits it. More... | |
dberr_t | dict_stats_drop_table (const char *db_and_table, char *errstr, ulint errstr_sz) |
Removes the statistics for a table and all of its indexes from the persistent statistics storage if it exists and if there is data stored for the table. More... | |
static dberr_t | dict_stats_rename_table_in_table_stats (const char *old_dbname_utf8mb3, const char *old_tablename_utf8mb3, const char *new_dbname_utf8mb3, const char *new_tablename_utf8mb3) |
Executes UPDATE mysql.innodb_table_stats SET database_name = '...', table_name = '...' WHERE database_name = '...' AND table_name = '...'; Creates its own transaction and commits it. More... | |
static dberr_t | dict_stats_rename_table_in_index_stats (const char *old_dbname_utf8mb3, const char *old_tablename_utf8mb3, const char *new_dbname_utf8mb3, const char *new_tablename_utf8mb3) |
Executes UPDATE mysql.innodb_index_stats SET database_name = '...', table_name = '...' WHERE database_name = '...' AND table_name = '...'; Creates its own transaction and commits it. More... | |
dberr_t | dict_stats_rename_table (const char *old_name, const char *new_name, char *errstr, size_t errstr_sz) |
Renames a table in InnoDB persistent stats storage. More... | |
dberr_t | dict_stats_rename_index (const dict_table_t *table, const char *old_index_name, const char *new_index_name) |
Renames an index in InnoDB persistent stats storage. More... | |
Code used for calculating and manipulating table statistics.
Created Jan 06, 2010 Vasil Dimov
#define DEBUG_PRINTF | ( | fmt, | |
... | |||
) | /* noop */ |
#define INDEX_EQ | ( | i1, | |
i2 | |||
) |
#define INDEX_STATS_NAME "mysql/innodb_index_stats" |
#define INDEX_STATS_NAME_PRINT "mysql.innodb_index_stats" |
#define N_DIFF_REQUIRED | ( | index | ) | (N_SAMPLE_PAGES(index) * 10) |
#define N_SAMPLE_PAGES | ( | index | ) |
#define PFX "n_diff_pfx" |
#define PFX_LEN 10 |
#define TABLE_STATS_NAME "mysql/innodb_table_stats" |
#define TABLE_STATS_NAME_PRINT "mysql.innodb_table_stats" |
typedef std::vector<uint64_t, ut::allocator<uint64_t> > boundaries_t |
typedef std::map<const char *, dict_index_t *, ut_strcmp_functor, index_map_t_allocator> index_map_t |
Auxiliary map used for sorting indexes by name in dict_stats_save().
typedef ut::allocator<std::pair<const char *const, dict_index_t *> > index_map_t_allocator |
Allocator type used for index_map_t.
enum page_scan_method_t |
|
static |
Calculates new statistics for a given index and saves them to the index members stat_n_diff_key_vals[], stat_n_sample_sizes[], stat_index_size and stat_n_leaf_pages.
This function could be slow.
index | in/out: index to analyze |
|
static |
Dive below the current position of a cursor and calculate the number of distinct records on the leaf page, when looking at the fist n_prefix columns.
Also calculate the number of external pages pointed by records on the leaf page.
[in] | cur | cursor |
[in] | n_prefix | look at the first n_prefix columns when comparing records |
[out] | n_diff | number of distinct records |
[out] | n_external_pages | number of external pages |
|
static |
Estimate the number of different key values in an index when looking at the first n_prefix columns.
For a given level in an index select n_diff_data->n_leaf_pages_to_analyze records from that level and dive below them to the corresponding leaf pages, then scan those leaf pages and save the sampling results in n_diff_data->n_diff_all_analyzed_pages.
[in] | index | Index |
[in] | n_prefix | Look at first 'n_prefix' columns when comparing records |
[in] | boundaries | A vector that contains n_diff_data->n_diff_on_level integers each of which represents the index (on level 'level', counting from left/smallest to right/biggest from 0) of the last record from each group of distinct keys |
[in,out] | n_diff_data | n_diff_all_analyzed_pages and n_external_pages_sum in this structure will be set by this function. The members level, n_diff_on_level and n_leaf_pages_to_analyze must be set by the caller in advance - they are used by some calculations inside this function |
[in,out] | wait_start_time | last known time index lock wasn't awaited. |
[in,out] | mtr | Mini-transaction |
|
static |
Find the total number and the number of distinct keys on a given level in an index.
Each of the 1..n_uniq prefixes are looked up and the results are saved in the array n_diff[0] .. n_diff[n_uniq - 1]. The total number of records on the level is saved in total_recs. Also, the index of the last record in each group of equal records is saved in n_diff_boundaries[0..n_uniq - 1], records indexing starts from the leftmost record on the level and continues cross pages boundaries, counting from 0.
index | in: index |
level | in: level |
n_diff | out: array for number of distinct keys for all prefixes |
total_recs | out: total number of records |
total_pages | out: total number of pages |
n_diff_boundaries | out: boundaries of the groups of distinct keys |
wait_start_time | in/out: last known time index lock wasn't awaited. |
mtr | in/out: mini-transaction |
|
static |
Calculates new statistics for a given index and saves them to the index members stat_n_diff_key_vals[], stat_n_sample_sizes[], stat_index_size and stat_n_leaf_pages, based on the specified n_sample_pages.
[in,out] | n_sample_pages | number of leaf pages to sample. and suggested next value to retry if aborted. |
[in,out] | index | index to analyze. |
|
static |
Check whether table's stats are initialized (assert if they are not).
table | in: table |
|
static |
Check whether index's stats are initialized (assert if they are not).
|
static |
Copy table and index statistics from one table to another, including index stats.
Extra indexes in src are ignored and extra indexes in dst are initialized to correspond to an empty index.
dst | in/out: destination table |
src | in: source table |
|
inlinestatic |
Executes DELETE FROM mysql.innodb_index_stats WHERE database_name = '...' AND table_name = '...'; Creates its own transaction and commits it.
database_name | in: database name, e.g. 'db' |
table_name | in: table name, e.g. 'table' |
|
inlinestatic |
Executes DELETE FROM mysql.innodb_table_stats WHERE database_name = '...' AND table_name = '...'; Creates its own transaction and commits it.
database_name | in: database name, e.g. 'db' |
table_name | in: table name, e.g. 'table' |
dberr_t dict_stats_drop_index | ( | const char * | db_and_table, |
const char * | iname, | ||
char * | errstr, | ||
ulint | errstr_sz | ||
) |
Removes the information for a particular index's stats from the persistent storage if it exists and if there is data stored for this index.
This function creates its own trx and commits it. A note from Marko why we cannot edit user and sys_* tables in one trx: marko: The problem is that ibuf merges should be disabled while we are rolling back dict transactions. marko: If ibuf merges are not disabled, we need to scan the *.ibd files. But we shouldn't open *.ibd files before we have rolled back dict transactions and opened the SYS_* records for the *.ibd files.
db_and_table | in: db and table, e.g. 'db/table' |
iname | in: index name |
errstr | out: error message if != DB_SUCCESS is returned |
errstr_sz | in: size of the errstr buffer |
Removes the statistics for a table and all of its indexes from the persistent statistics storage if it exists and if there is data stored for the table.
Removes the statistics for a table and all of its indexes from the persistent storage if it exists and if there is data stored for the table.
This function creates its own transaction and commits it.
db_and_table | in: db and table, e.g. 'db/table' |
errstr | out: error message if != DB_SUCCESS is returned |
errstr_sz | in: size of errstr buffer |
|
static |
Write all zeros (or 1 where it makes sense) into an index statistics members.
The resulting stats correspond to an empty index. The caller must own index's table stats latch in X mode (dict_table_stats_lock(table, RW_X_LATCH))
index | in/out: index |
|
static |
Write all zeros (or 1 where it makes sense) into a table and its indexes' statistics members.
The resulting stats correspond to an empty table.
table | in/out: table |
|
static |
Executes a given SQL statement using the InnoDB internal SQL parser.
This function will free the pinfo object.
[in,out] | pinfo | pinfo to pass to que_eval_sql() must already have any literals bound to it |
[in] | sql | SQL string to execute |
[in,out] | trx | in case of NULL the function will allocate and free the trx object. |
|
static |
Read table's statistics from the persistent statistics storage.
table | in/out: table |
|
static |
Called for the rows that are selected by SELECT ... FROM mysql.innodb_index_stats WHERE table='...' The second argument is a pointer to the table and the fetched stats are written to its indexes.
Let a table has N indexes and each index has Ui unique columns for i=1..N, then mysql.innodb_index_stats will have SUM(Ui) i=1..N rows for that table. So this function will be called SUM(Ui) times where SUM(Ui) is of magnitude N*AVG(Ui). In each call it searches for the currently fetched index into table->indexes linearly, assuming this list is not sorted. Thus, overall, fetching all indexes' stats from mysql.innodb_index_stats is O(N^2) where N is the number of indexes. This can be improved if we sort table->indexes in a temporary area just once and then search in that sorted list. Then the complexity will be O(N*log(N)). We assume a table will not have more than 100 indexes, so we go with the simpler N^2 algorithm.
node_void | in: select node |
arg_void | out: table + a flag that tells if we modified anything |
|
static |
Called for the row that is selected by SELECT ... FROM mysql.innodb_table_stats WHERE table='...' The second argument is a pointer to the table and the fetched stats are written to it.
node_void | in: select node |
table_void | out: table |
|
static |
Confirms long waiters for the index lock exist.
Wait time estimation is based on the last call of this function when not exist.
[in] | index | index |
[in,out] | wait_start_time | last known time index lock wasn't awaited. Can be updated by this function if no waiter found now. |
|
inlinestatic |
Set dict_index_t::stat_n_diff_key_vals[] and stat_n_sample_sizes[].
[in] | n_diff_data | input data to use to derive the results |
[in,out] | index | index whose stat_n_diff_key_vals[] to set |
dberr_t dict_stats_rename_index | ( | const dict_table_t * | table, |
const char * | old_index_name, | ||
const char * | new_index_name | ||
) |
Renames an index in InnoDB persistent stats storage.
This function creates its own transaction and commits it.
table | in: table whose index is renamed |
old_index_name | in: old index name |
new_index_name | in: new index name |
dberr_t dict_stats_rename_table | ( | const char * | old_name, |
const char * | new_name, | ||
char * | errstr, | ||
size_t | errstr_sz | ||
) |
Renames a table in InnoDB persistent stats storage.
This function creates its own transaction and commits it.
old_name | in: old name, e.g. 'db/table' |
new_name | in: new name, e.g. 'db/table' |
errstr | out: error string if != DB_SUCCESS is returned |
errstr_sz | in: errstr size |
|
inlinestatic |
Executes UPDATE mysql.innodb_index_stats SET database_name = '...', table_name = '...' WHERE database_name = '...' AND table_name = '...'; Creates its own transaction and commits it.
old_dbname_utf8mb3 | in: database name, e.g. 'olddb' |
old_tablename_utf8mb3 | in: table name, e.g. 'oldtable' |
new_dbname_utf8mb3 | in: database name, e.g. 'newdb' |
new_tablename_utf8mb3 | in: table name, e.g. 'newtable' |
|
inlinestatic |
Executes UPDATE mysql.innodb_table_stats SET database_name = '...', table_name = '...' WHERE database_name = '...' AND table_name = '...'; Creates its own transaction and commits it.
old_dbname_utf8mb3 | in: database name, e.g. 'olddb' |
old_tablename_utf8mb3 | in: table name, e.g. 'oldtable' |
new_dbname_utf8mb3 | in: database name, e.g. 'newdb' |
new_tablename_utf8mb3 | in: table name, e.g. 'newtable' |
|
static |
Save the table's statistics into the persistent statistics storage.
[in] | table_orig | table whose stats to save |
[in] | only_for_index | if this is non-NULL, then stats for indexes that are not equal to it will not be saved, if NULL, then all indexes' stats are saved |
[in] | trx | Save stats using this transaction. If nullptr, then create a transaction and use that. |
|
static |
Save an individual index's statistic into the persistent statistics storage.
[in] | index | index to be updated |
[in] | last_update | timestamp of the stat |
[in] | stat_name | name of the stat |
[in] | stat_value | value of the stat |
[in] | sample_size | n pages sampled or NULL |
[in] | stat_description | description of the stat |
[in,out] | trx | in case of NULL the function will allocate and free the trx object. If it is not NULL then it will be rolled back only in the case of error, but not freed. |
|
inlinestatic |
Scan a page, reading records from left to right and counting the number of distinct records (looking only at the first n_prefix columns) and the number of external pages pointed by records from this page.
If scan_method is QUIT_ON_FIRST_NON_BORING then the function will return as soon as it finds a record that does not match its neighbor to the right, which means that in the case of QUIT_ON_FIRST_NON_BORING the returned n_diff can either be 0 (empty page), 1 (the whole page has all keys equal) or 2 (the function found a non-boring record and returned).
[out] | out_rec | record, or NULL |
[out] | offsets1 | rec_get_offsets() working space (must be big enough) |
[out] | offsets2 | rec_get_offsets() working space (must be big enough) |
[in] | index | index of the page |
[in] | page | the page to scan |
[in] | n_prefix | look at the first n_prefix columns |
[in] | scan_method | scan to the end of the page or not |
[out] | n_diff | number of distinct records encountered |
[out] | n_external_pages | if this is non-NULL then it will be set to the number of externally stored pages which were encountered |
|
inlinestatic |
Checks whether an index should be ignored in stats manipulations:
index | in: index |
|
static |
Duplicate the stats of a table and its indexes.
This function creates a dummy dict_table_t object and copies the input table's stats into it. The returned table object is not in the dictionary cache and cannot be accessed by any other threads. In addition to the members copied in dict_stats_table_clone_create() this function initializes the following: dict_table_t::stat_initialized dict_table_t::stat_persistent dict_table_t::stat_n_rows dict_table_t::stat_clustered_index_size dict_table_t::stat_sum_of_other_index_sizes dict_table_t::stat_modified_counter dict_index_t::stat_n_diff_key_vals[] dict_index_t::stat_n_sample_sizes[] dict_index_t::stat_n_non_null_key_vals[] dict_index_t::stat_index_size dict_index_t::stat_n_leaf_pages The returned object should be freed with dict_stats_snapshot_free() when no longer needed.
[in] | table | table whose stats to copy |
|
static |
Free the resources occupied by an object returned by dict_stats_snapshot_create().
t | in: dummy table object to free |
|
static |
Duplicate a table object and its indexes.
This function creates a dummy dict_table_t object and initializes the following table and index members: dict_table_t::id (copied) dict_table_t::heap (newly created) dict_table_t::name (copied) dict_table_t::corrupted (copied) dict_table_t::indexes<> (newly created) dict_table_t::magic_n for each entry in dict_table_t::indexes, the following are initialized: (indexes that have DICT_FTS set in index->type are skipped) dict_index_t::id (copied) dict_index_t::name (copied) dict_index_t::table_name (points to the copied table name) dict_index_t::table (points to the above semi-initialized object) dict_index_t::type (copied) dict_index_t::to_be_dropped (copied) dict_index_t::online_status (copied) dict_index_t::n_uniq (copied) dict_index_t::fields[] (newly created, only first n_uniq, only fields[i].name) dict_index_t::indexes<> (newly created) dict_index_t::stat_n_diff_key_vals[] (only allocated, left uninitialized) dict_index_t::stat_n_sample_sizes[] (only allocated, left uninitialized) dict_index_t::stat_n_non_null_key_vals[] (only allocated, left uninitialized) dict_index_t::magic_n The returned object should be freed with dict_stats_table_clone_free() when no longer needed.
table | in: table whose stats to copy |
|
static |
Free the resources occupied by an object returned by dict_stats_table_clone_create().
t | in: dummy table object to free |
dberr_t dict_stats_update | ( | dict_table_t * | table, |
dict_stats_upd_option_t | stats_upd_option, | ||
trx_t * | trx = nullptr |
||
) |
Calculates new estimates for table and index statistics.
The statistics are used in query optimization.
[in] | table | table for which statistics are to be updated. |
[in] | stats_upd_option | statistics update option (persistent, etc). |
[in] | trx | statistics update will be done as part of this transaction. if null, a new transaction will be internally created. |
void dict_stats_update_for_index | ( | dict_index_t * | index | ) |
Fetches or calculates new estimates for index statistics.
in/out: index
index | in/out: index |
|
static |
Calculates new estimates for table and index statistics.
This function is relatively slow and is used to calculate persistent statistics that will be saved on disk.
table | in/out: table |
|
static |
Calculates new estimates for table and index statistics.
This function is relatively quick and is used to calculate transient statistics that are not saved on disk. This was the only way to calculate statistics before the Persistent Statistics feature was introduced.
table | in/out: table |
|
static |
Calculates new estimates for index statistics.
This function is relatively quick and is used to calculate transient statistics that are not saved on disk. This was the only way to calculate statistics before the Persistent Statistics feature was introduced.
index | in/out: index |