mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 14:03:07 +01:00
Let's support segment-level selectivities. Amen.
This commit is contained in:
parent
e4b4b43b75
commit
f99e3373d4
@ -154,6 +154,7 @@
|
||||
#define f_seg_name 0
|
||||
#define f_seg_field 1
|
||||
#define f_seg_position 2
|
||||
#define f_seg_statistics 3
|
||||
#define f_idx_name 0
|
||||
#define f_idx_relation 1
|
||||
#define f_idx_id 2
|
||||
|
@ -160,7 +160,7 @@ static void copy_key(KEY *, KEY *);
|
||||
static CONTENTS delete_node(TDBB, WIN *, BTN);
|
||||
static void delete_tree(TDBB, USHORT, USHORT, SLONG, SLONG);
|
||||
static DSC *eval(TDBB, JRD_NOD, DSC *, bool *);
|
||||
static SLONG fast_load(TDBB, JRD_REL, IDX *, USHORT, SCB, float *);
|
||||
static SLONG fast_load(TDBB, JRD_REL, IDX *, USHORT, SCB, SelectivityList&);
|
||||
static IRT fetch_root(TDBB, WIN *, JRD_REL);
|
||||
static SLONG find_node(BTR, KEY *, bool);
|
||||
static CONTENTS garbage_collect(TDBB, WIN *, SLONG);
|
||||
@ -241,7 +241,9 @@ USHORT BTR_all(TDBB tdbb,
|
||||
void BTR_create(TDBB tdbb,
|
||||
JRD_REL relation,
|
||||
IDX * idx,
|
||||
USHORT key_length, SCB sort_handle, float *selectivity)
|
||||
USHORT key_length,
|
||||
SCB sort_handle,
|
||||
SelectivityList& selectivity)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -270,7 +272,7 @@ void BTR_create(TDBB tdbb,
|
||||
IRT root = (IRT) CCH_FETCH(tdbb, &window, LCK_write, pag_root);
|
||||
CCH_MARK(tdbb, &window);
|
||||
root->irt_rpt[idx->idx_id].irt_root = idx->idx_root;
|
||||
root->irt_rpt[idx->idx_id].irt_stuff.irt_selectivity = *selectivity;
|
||||
root->irt_rpt[idx->idx_id].irt_stuff.irt_selectivity = selectivity.back();
|
||||
root->irt_rpt[idx->idx_id].irt_flags &= ~irt_in_progress;
|
||||
|
||||
if (dbb->dbb_wal) {
|
||||
@ -1573,7 +1575,7 @@ retry:
|
||||
}
|
||||
|
||||
|
||||
float BTR_selectivity(TDBB tdbb, JRD_REL relation, USHORT id)
|
||||
void BTR_selectivity(TDBB tdbb, JRD_REL relation, USHORT id, SelectivityList& selectivity)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -1596,13 +1598,13 @@ float BTR_selectivity(TDBB tdbb, JRD_REL relation, USHORT id)
|
||||
|
||||
IRT root = fetch_root(tdbb, &window, relation);
|
||||
if (!root) {
|
||||
return 0.0;
|
||||
return;
|
||||
}
|
||||
|
||||
SLONG page = root->irt_rpt[id].irt_root;
|
||||
if (root->irt_count <= id || !page) {
|
||||
CCH_RELEASE(tdbb, &window);
|
||||
return 0.0;
|
||||
return;
|
||||
}
|
||||
window.win_flags = WIN_large_scan;
|
||||
window.win_scans = 1;
|
||||
@ -1667,15 +1669,16 @@ float BTR_selectivity(TDBB tdbb, JRD_REL relation, USHORT id)
|
||||
CCH_RELEASE_TAIL(tdbb, &window);
|
||||
|
||||
// calculate the selectivity and store it on the root page
|
||||
float selectivity = (float) ((nodes) ? 1.0 / (float) (nodes - duplicates) : 0.0);
|
||||
const USHORT count = root->irt_rpt[id].irt_keys;
|
||||
selectivity.grow(count);
|
||||
selectivity.back() =
|
||||
(float) ((nodes) ? 1.0 / (float) (nodes - duplicates) : 0.0);
|
||||
window.win_page = relation->rel_index_root;
|
||||
window.win_flags = 0;
|
||||
root = (IRT) CCH_FETCH(tdbb, &window, LCK_write, pag_root);
|
||||
CCH_MARK(tdbb, &window);
|
||||
root->irt_rpt[id].irt_stuff.irt_selectivity = selectivity;
|
||||
root->irt_rpt[id].irt_stuff.irt_selectivity = selectivity.back();
|
||||
CCH_RELEASE(tdbb, &window);
|
||||
|
||||
return selectivity;
|
||||
}
|
||||
|
||||
|
||||
@ -2449,7 +2452,9 @@ static DSC *eval(TDBB tdbb, JRD_NOD node, DSC * temp, bool *missing)
|
||||
static SLONG fast_load(TDBB tdbb,
|
||||
JRD_REL relation,
|
||||
IDX * idx,
|
||||
USHORT key_length, SCB sort_handle, float *selectivity)
|
||||
USHORT key_length,
|
||||
SCB sort_handle,
|
||||
SelectivityList& selectivity)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -2794,7 +2799,9 @@ static SLONG fast_load(TDBB tdbb,
|
||||
}
|
||||
|
||||
CCH_flush(tdbb, (USHORT) FLUSH_ALL, 0);
|
||||
*selectivity = (float) ((count) ? (1. / (double) (count - duplicates)) : 0);
|
||||
selectivity.grow(idx->idx_count);
|
||||
selectivity.back() =
|
||||
(float) ((count) ? (1. / (double) (count - duplicates)) : 0);
|
||||
|
||||
return window->win_page;
|
||||
|
||||
|
@ -27,12 +27,11 @@
|
||||
#ifndef JRD_BTR_H
|
||||
#define JRD_BTR_H
|
||||
|
||||
#include "../common/classes/array.h"
|
||||
#include "../jrd/jrd_blks.h"
|
||||
#include "../jrd/constants.h"
|
||||
#include "../include/fb_blk.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "../jrd/err_proto.h" /* Index error types */
|
||||
|
||||
/* 64 turns out not to be enough indexes */
|
||||
@ -209,5 +208,7 @@ typedef struct jrd_exp {
|
||||
|
||||
#define NEXT_EXPANDED(xxx,yyy) (BTX) ((UCHAR*) xxx->btx_data + (yyy)->btn_prefix + (yyy)->btn_length)
|
||||
|
||||
typedef Firebird::HalfStaticArray<float, 1> SelectivityList;
|
||||
|
||||
#endif /* JRD_BTR_H */
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
||||
#include "../jrd/req.h"
|
||||
|
||||
USHORT BTR_all(TDBB, jrd_rel*, idx**, idx**, str**, SLONG*);
|
||||
void BTR_create(TDBB, jrd_rel*, idx*, USHORT, scb*, float*);
|
||||
void BTR_create(TDBB, jrd_rel*, idx*, USHORT, scb*, SelectivityList&);
|
||||
void BTR_delete_index(TDBB, win*, USHORT);
|
||||
bool BTR_description(JRD_REL, irt*, idx*, SSHORT);
|
||||
void BTR_evaluate(tdbb*, irb*, sbm**);
|
||||
@ -47,7 +47,7 @@ btn* BTR_next_node(btn*, btx**);
|
||||
btn* BTR_previous_node(btn*, btx**);
|
||||
void BTR_remove(tdbb*, win*, iib*);
|
||||
void BTR_reserve_slot(TDBB, jrd_rel*, jrd_tra*, idx*);
|
||||
float BTR_selectivity(TDBB, jrd_rel*, USHORT);
|
||||
void BTR_selectivity(TDBB, jrd_rel*, USHORT, SelectivityList&);
|
||||
|
||||
#endif // JRD_BTR_PROTO_H
|
||||
|
||||
|
@ -682,7 +682,7 @@ void DFW_post_work_arg( JRD_TRA transaction, DFW work, DSC * desc, USHORT id)
|
||||
}
|
||||
|
||||
|
||||
void DFW_update_index( DFW work, USHORT id, float selectivity)
|
||||
void DFW_update_index(const TEXT* name, USHORT id, const SelectivityList& selectivity)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -702,15 +702,35 @@ void DFW_update_index( DFW work, USHORT id, float selectivity)
|
||||
tdbb = GET_THREAD_DATA;
|
||||
dbb = tdbb->tdbb_database;
|
||||
|
||||
if (dbb->dbb_ods_version >= ODS_VERSION11) {
|
||||
|
||||
request = (BLK) CMP_find_request(tdbb, irq_m_index_seg, IRQ_REQUESTS);
|
||||
|
||||
FOR(REQUEST_HANDLE request)
|
||||
SEG IN RDB$INDEX_SEGMENTS WITH SEG.RDB$INDEX_NAME EQ name
|
||||
SORTED BY SEG.RDB$FIELD_POSITION
|
||||
if (!REQUEST(irq_m_index_seg))
|
||||
REQUEST(irq_m_index_seg) = (BLK)request;
|
||||
MODIFY SEG USING
|
||||
SEG.RDB$STATISTICS =
|
||||
selectivity.getCount() ? selectivity[SEG.RDB$FIELD_POSITION] : 0.0;
|
||||
END_MODIFY;
|
||||
END_FOR;
|
||||
|
||||
if (!REQUEST(irq_m_index_seg))
|
||||
REQUEST(irq_m_index_seg) = (BLK)request;
|
||||
}
|
||||
|
||||
request = (BLK) CMP_find_request(tdbb, irq_m_index, IRQ_REQUESTS);
|
||||
|
||||
FOR(REQUEST_HANDLE request)
|
||||
IDX IN RDB$INDICES WITH IDX.RDB$INDEX_NAME EQ work->dfw_name
|
||||
IDX IN RDB$INDICES WITH IDX.RDB$INDEX_NAME EQ name
|
||||
if (!REQUEST(irq_m_index))
|
||||
REQUEST(irq_m_index) = (BLK)request;
|
||||
MODIFY IDX USING
|
||||
IDX.RDB$INDEX_ID = id + 1;
|
||||
IDX.RDB$STATISTICS = selectivity;
|
||||
IDX.RDB$STATISTICS =
|
||||
selectivity.getCount() ? selectivity.back() : 0.0;
|
||||
END_MODIFY;
|
||||
END_FOR;
|
||||
|
||||
@ -1502,7 +1522,6 @@ static bool create_index( TDBB tdbb,
|
||||
JRD_REL relation, partner_relation;
|
||||
IDX idx;
|
||||
int key_count;
|
||||
float selectivity;
|
||||
SSHORT text_type;
|
||||
SSHORT collate;
|
||||
BLK handle;
|
||||
@ -1597,12 +1616,11 @@ static bool create_index( TDBB tdbb,
|
||||
}
|
||||
if (IDX.RDB$INDEX_ID && IDX.RDB$STATISTICS < 0.0)
|
||||
{
|
||||
MODIFY IDX
|
||||
IDX.RDB$STATISTICS =
|
||||
IDX_statistics( tdbb,
|
||||
relation,
|
||||
(USHORT)(IDX.RDB$INDEX_ID - 1));
|
||||
END_MODIFY;
|
||||
SelectivityList selectivity(tdbb->tdbb_default);
|
||||
const USHORT id = IDX.RDB$INDEX_ID - 1;
|
||||
IDX_statistics(tdbb, relation, id, selectivity);
|
||||
DFW_update_index(work->dfw_name, id, selectivity);
|
||||
|
||||
EXE_unwind(tdbb, (JRD_REQ)request);
|
||||
return false;
|
||||
}
|
||||
@ -1782,15 +1800,11 @@ static bool create_index( TDBB tdbb,
|
||||
}
|
||||
|
||||
fb_assert(work->dfw_id == dbb->dbb_max_idx);
|
||||
IDX_create_index( tdbb,
|
||||
relation,
|
||||
&idx,
|
||||
(UCHAR*) work->dfw_name,
|
||||
&work->dfw_id,
|
||||
transaction,
|
||||
&selectivity);
|
||||
SelectivityList selectivity(tdbb->tdbb_default);
|
||||
IDX_create_index(tdbb, relation, &idx, (UCHAR*) work->dfw_name,
|
||||
&work->dfw_id, transaction, selectivity);
|
||||
fb_assert(work->dfw_id == idx.idx_id);
|
||||
DFW_update_index(work, idx.idx_id, selectivity);
|
||||
DFW_update_index(work->dfw_name, idx.idx_id, selectivity);
|
||||
|
||||
if (partner_relation)
|
||||
{
|
||||
|
@ -32,6 +32,6 @@ void DFW_perform_work(jrd_tra*);
|
||||
void DFW_perform_post_commit_work(jrd_tra*);
|
||||
dfw* DFW_post_work(jrd_tra*, enum dfw_t, dsc*, USHORT);
|
||||
void DFW_post_work_arg(jrd_tra*, dfw*, dsc*, USHORT);
|
||||
void DFW_update_index(dfw*, USHORT, float);
|
||||
void DFW_update_index(const TEXT*, USHORT, const SelectivityList&);
|
||||
|
||||
#endif // JRD_DFW_PROTO_H
|
||||
|
@ -169,7 +169,9 @@ void IDX_create_index(
|
||||
JRD_REL relation,
|
||||
IDX * idx,
|
||||
UCHAR * index_name,
|
||||
USHORT * index_id, JRD_TRA transaction, float *selectivity)
|
||||
USHORT * index_id,
|
||||
JRD_TRA transaction,
|
||||
SelectivityList& selectivity)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -791,7 +793,7 @@ IDX_E IDX_modify_check_constraints(TDBB tdbb,
|
||||
}
|
||||
|
||||
|
||||
float IDX_statistics(TDBB tdbb, JRD_REL relation, USHORT id)
|
||||
void IDX_statistics(TDBB tdbb, JRD_REL relation, USHORT id, SelectivityList& selectivity)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -807,7 +809,7 @@ float IDX_statistics(TDBB tdbb, JRD_REL relation, USHORT id)
|
||||
|
||||
SET_TDBB(tdbb);
|
||||
|
||||
return BTR_selectivity(tdbb, relation, id);
|
||||
BTR_selectivity(tdbb, relation, id, selectivity);
|
||||
}
|
||||
|
||||
|
||||
|
@ -32,7 +32,7 @@
|
||||
void IDX_check_access(TDBB, class Csb *, struct jrd_rel *, struct jrd_rel *,
|
||||
struct jrd_fld *);
|
||||
void IDX_create_index(TDBB, struct jrd_rel *, struct idx *, UCHAR *,
|
||||
USHORT *, class jrd_tra *, float *);
|
||||
USHORT *, class jrd_tra *, SelectivityList&);
|
||||
struct idb *IDX_create_index_block(TDBB, struct jrd_rel *, USHORT);
|
||||
void IDX_delete_index(TDBB, struct jrd_rel *, USHORT);
|
||||
void IDX_delete_indices(TDBB, struct jrd_rel *);
|
||||
@ -45,7 +45,7 @@ enum idx_e IDX_modify(struct tdbb *, struct rpb *, struct rpb *,
|
||||
enum idx_e IDX_modify_check_constraints(TDBB, struct rpb *, struct rpb *,
|
||||
class jrd_tra *, struct jrd_rel **,
|
||||
USHORT *);
|
||||
float IDX_statistics(TDBB, struct jrd_rel *, USHORT);
|
||||
void IDX_statistics(TDBB, struct jrd_rel *, USHORT, SelectivityList&);
|
||||
enum idx_e IDX_store(struct tdbb *, struct rpb *, class jrd_tra *,
|
||||
struct jrd_rel **, USHORT *);
|
||||
|
||||
|
@ -108,7 +108,8 @@
|
||||
#define irq_r_gen_id_num 72 /* lookup generator by ID. */
|
||||
#define irq_verify_role_name 73 /* ensure role exists in roles & user_privileges. */
|
||||
#define irq_l_relation_defsec 74 /* check the default sec class name against rel. */
|
||||
#define irq_m_index_seg 75 /* modify per-segment index selectivity */
|
||||
|
||||
#define irq_MAX 75
|
||||
#define irq_MAX 76
|
||||
|
||||
#endif /* JRD_IRQ_H */
|
||||
|
@ -70,7 +70,6 @@ int PCMET_expression_index(
|
||||
DBB dbb;
|
||||
JRD_REL relation;
|
||||
IDX idx;
|
||||
float selectivity;
|
||||
PLB default_pool, new_pool = NULL;
|
||||
CSB csb;
|
||||
JRD_REQ current_request;
|
||||
@ -101,12 +100,13 @@ int PCMET_expression_index(
|
||||
relation->rel_name =
|
||||
MET_save_name(tdbb, REL.RDB$RELATION_NAME);
|
||||
relation->rel_length = strlen(relation->rel_name);
|
||||
} if (IDX.RDB$INDEX_ID && IDX.RDB$STATISTICS < 0.0) {
|
||||
MODIFY IDX
|
||||
IDX.RDB$STATISTICS =
|
||||
IDX_statistics(tdbb, relation,
|
||||
IDX.RDB$INDEX_ID - 1);
|
||||
END_MODIFY;
|
||||
}
|
||||
if (IDX.RDB$INDEX_ID && IDX.RDB$STATISTICS < 0.0) {
|
||||
SelectivityList selectivity(tdbb->tdbb_default);
|
||||
const USHORT id = IDX.RDB$INDEX_ID - 1;
|
||||
IDX_statistics(tdbb, relation, id, selectivity);
|
||||
DFW_update_index(work->dfw_name, id, selectivity);
|
||||
|
||||
EXE_unwind(tdbb, REQUEST(irq_c_exp_index));
|
||||
return FALSE;
|
||||
}
|
||||
@ -174,6 +174,8 @@ int PCMET_expression_index(
|
||||
|
||||
/* Actually create the index */
|
||||
|
||||
SelectivityList selectivity(tdbb->tdbb_default);
|
||||
|
||||
current_request = tdbb->tdbb_request;
|
||||
tdbb->tdbb_request = idx.idx_expression_request;
|
||||
IDX_create_index(tdbb, relation, &idx, work->dfw_name, NULL,
|
||||
|
Loading…
Reference in New Issue
Block a user