Un plan fixe est une fonctionnalité d'optimisation du moteur d'exécution propre à Hologres. Cette rubrique décrit les prérequis et la configuration des paramètres nécessaires pour qu'une instruction SQL puisse bénéficier d'un plan fixe.
Contexte
Le plan fixe constitue une méthode d'optimisation du moteur d'exécution exclusive à Hologres. L'exécution traditionnelle d'une requête SQL fait intervenir plusieurs composants, tels que l'optimiseur, le coordinateur, le moteur de requête et le moteur de stockage. À l'inverse, un plan fixe emprunte un chemin direct qui contourne l'optimiseur, le coordinateur et certaines parties du moteur de requête, réduisant ainsi la surcharge de traitement. Le frontal fixe se connecte directement au moteur de requête fixe, ce qui améliore considérablement l'efficacité de l'exécution SQL. Cette optimisation clé permet d'assurer des écritures en temps réel à haut débit et des requêtes à forte concurrence. Pour plus d'informations sur les plans fixes, consultez architecture du produit.
Dans Hologres, les plans fixes sont utilisés par défaut dans les scénarios suivants :
Écritures en temps réel vers Hologres via Flink.
Écritures en temps réel vers Hologres via Data Integration de DataWorks.
Écritures vers Hologres via Holo Client.
Pour les autres scénarios d'écriture, vous pouvez configurer vos instructions SQL afin qu'elles utilisent un plan fixe. Consultez les sections suivantes pour plus de détails.
Dans ces scénarios, Hologres utilise par défaut des plans fixes pour les instructions SQL éligibles. Toutefois, toutes les instructions SQL de ces scénarios ne sont pas nécessairement éligibles.
Paramètres GUC associés
-
Liste des paramètres GUC
Les paramètres suivants servent à configurer Fixed Plan. La valeur de chaque paramètre peut être on ou off. Tous les paramètres sont activés par défaut dans Holo Client et s'appliquent au niveau de la session.
Paramètre
Description
Valeur par défaut
Historique des modifications
hg_experimental_enable_fixed_dispatcher
Contrôle l'activation de la fonctionnalité de plan fixe pour l'instance.
Prend en charge les plans fixes pour les opérations
INSERT,UPDATE,DELETEetPrefixScanportant sur une seule ligne.on
S.O.
hg_experimental_enable_fixed_dispatcher_for_multi_values
Détermine si un plan fixe doit être utilisé pour les opérations
INSERTmulti-lignes.RemarqueL'atomicité n'est pas garantie. Pour les insertions multi-lignes, une opération réussie signifie que toutes les lignes ont été insérées. En cas d'erreur, le système renvoie un seul message pouvant indiquer soit une insertion partielle, soit un échec complet. Il incombe à l'application cliente de retenter l'insertion des lignes ayant échoué.
on
À partir de Hologres V1.3.35, ce paramètre GUC permet aux opérations
INSERT,UPDATEetDELETEmulti-lignes d'utiliser des plans fixes.hg_experimental_enable_fixed_dispatcher_autofill_series
Prend en charge les plans fixes pour les écritures dans les tables contenant des colonnes de type
SERIAL. Nous recommandons d'activer ce paramètre au niveau de la session.on
La valeur par défaut est passée à
ondans Hologres V1.3.25.hg_experimental_enable_fixed_dispatcher_for_update
Prend en charge les plans fixes pour les opérations
UPDATE. Nous recommandons d'activer ce paramètre au niveau de la session.off
À partir de Hologres V1.3.25, le paramètre
hg_experimental_enable_fixed_dispatcher_for_updateest obsolète. Les instructions UPDATE éligibles utilisent un plan fixe par défaut. Toutefois, pour mettre à jour plusieurs lignes, vous devez configurerset hg_experimental_enable_fixed_dispatcher_for_multi_values = on.hg_experimental_enable_fixed_dispatcher_for_delete
Prend en charge les plans fixes pour les opérations
DELETE. Nous recommandons d'activer ce paramètre au niveau de la session.off
À partir de Hologres V1.3.25, le paramètre
hg_experimental_enable_fixed_dispatcher_for_deleteest obsolète. Les instructions DELETE éligibles utilisent un plan fixe par défaut. Toutefois, pour supprimer plusieurs lignes, vous devez configurerset hg_experimental_enable_fixed_dispatcher_for_multi_values = on.hg_experimental_enable_fixed_dispatcher_for_scan
Prend en charge les plans fixes pour les requêtes
PrefixScan.RemarqueUne requête
PrefixScaninterroge une table dotée d'une clé primaire composite, où les conditions de la requête ne spécifient que les premières colonnes de la clé primaire. Les plans fixes pour les requêtesPrefixScansur des tables orientées colonne ne sont actuellement pas pris en charge.off
Hologres V1.3.35 ou version ultérieure recommandé.
hg_experimental_enable_bhclient_cache_on_session
Contrôle le mode de mise en cache. Deux modes sont disponibles.
-
on : Utilise le mode
cached on session. -
off : Utilise le mode
cached on fe.
RemarqueLa liste suivante compare les modes
cached on sessionetcached on fe.-
cached on session: Chaque session dispose de son propre writer et reader. Ce mode offre un débit plus élevé par session, mais le démarrage est plus lent, car le writer et le reader nécessitent une initialisation avant la première opération sur chaque table. -
cached on fe: Toutes les sessions d'un nœud FE partagent les mêmes writers et readers. Les writers et readers ne sont pas fermés à la fin d'une session, ce qui élimine le temps de démarrage.
off
S.O.
hg_experimental_disable_fixed_planner_conflict_pk_check
Détermine si la colonne spécifiée dans la syntaxe
INSERT INTO <table_name> VALUES (...) ON CONFLICT(<column>)peut être une colonne non liée à la clé primaire.-
false : Non pris en charge.
-
true : Pris en charge.
RemarqueSi ce paramètre GUC est défini sur
true, vous pouvez spécifier une colonne non liée à la clé primaire. Toutefois, l'instruction INSERT ON CONFLICT continue de traiter les données en fonction de la duplication de la clé primaire, comme siON CONFLICT(pk)avait été spécifié.
false
-
Dans les versions de Hologres allant de la V1.3 à la V2.1.28, la colonne spécifiée dans
ON CONFLICT(<column>)doit être une colonne de clé primaire. -
Ce paramètre est disponible uniquement dans Hologres V2.1.29 et les versions ultérieures de la série V2.1.x. Il détermine si la colonne dans
ON CONFLICT(<column>)peut être une colonne non liée à la clé primaire. Ce paramètre est supprimé dans la V3.0 et les versions ultérieures ; aucune configuration n'est alors requise.
-
-
Utilisation des paramètres GUC
-
Vérifier la valeur d'un paramètre GUC
Utilisez la commande
SHOWpour vérifier la valeur d'un paramètre GUC.SHOW <GUC_name>;Exemple :
-- Check whether the fixed plan feature is enabled at the instance level. SHOW hg_experimental_enable_fixed_dispatcher; -
Définir un paramètre GUC
-
Définir un paramètre GUC au niveau de la session
Vous pouvez utiliser la commande
SETpour configurer un paramètre GUC au niveau de la session. Le paramétrage s'applique uniquement à la session actuelle et est ignoré lors de sa fermeture. Nous vous recommandons d'inclure cette commande avant votre instruction SQL.SET <GUC_name> = <values>;GUC_name indique le nom du paramètre GUC, et values indique la valeur du paramètre.
Exemple :
-- Enable fixed plan for multi-row INSERT ON CONFLICT statements. SET hg_experimental_enable_fixed_dispatcher_for_multi_values = on; -
Définir un paramètre GUC au niveau de la base de données
Utilisez la commande
ALTER DATABASE ... SET ...pour définir un paramètre GUC au niveau de la base de données. Le paramétrage s'applique à l'ensemble de la base de données. Pour appliquer la modification à la session actuelle, vous devez vous reconnecter. Ce paramétrage ne s'applique pas aux nouvelles bases de données ; vous devez le configurer manuellement pour chacune d'elles.ALTER DATABASE <db_name> SET <GUC_name> = <values>;db_name indique le nom de la base de données, GUC_name indique le nom du paramètre GUC, et values indique la valeur du paramètre.
Exemple :
-- Enable the fixed plan feature at the database level. ALTER DATABASE <db_name> SET hg_experimental_enable_fixed_dispatcher = on;
-
-
Exigences relatives aux types de données
Les colonnes d'une table ne peuvent pas être de type
MONEYniMONEY ARRAY.-
Les types de données suivants sont pris en charge pour les colonnes utilisées dans les opérations DML (
INSERT,UPDATEetDELETE) etSELECT. Pour les instructionsSELECT, cette exigence s'applique à la fois aux colonnes cibles et aux colonnes figurant dans la clauseWHERE.BOOLEAN(alias :BOOL)SMALLINTINTEGER(alias :INT,INT4)BIGINT(alias :INT8)FLOAT(alias :FLOAT4)DOUBLE PRECISION(alias :FLOAT8)CHAR(n)VARCHAR(n)(Dans Hologres V1.1.79 et versions ultérieures,VARCHARpeut utiliser Fixed Plan.)BYTEAJSONetJSONBTEXT(alias :VARCHAR)TIMESTAMP WITH TIME ZONE(alias :TIMESTAMPTZ)DATETIMESTAMPDECIMAL(alias :NUMERIC)ROARINGBITMAPTIME(pris en charge dans Hologres V2.2 et versions ultérieures)TIMETZ(pris en charge dans Hologres V2.2 et versions ultérieures)-
Types tableau
boolean[]smallint[]int4[]int8[]float4[]float8[]char(n)[]varchar(n)[]text[]
Scénarios d'insertion
À partir de Hologres V3.2, vous pouvez utiliser la clause RETURNING dans une instruction INSERT qui utilise un plan fixe pour écrire dans une table dotée d'une clé primaire.
-
Instruction INSERT
Un plan fixe peut être utilisé avec les instructions INSERT suivantes.
-- Write a single row. INSERT INTO TABLE(col1,col2,col3..) VALUES(?,?,?..) ON conflict xxx; -- Write multiple rows. INSERT INTO TABLE(col1,col2,col3..) VALUES(?,?,?..),(?,?,?..) ON conflict xxx;RemarqueVous pouvez utiliser l'instruction INSERT pour écrire des données dans des tables internes, mais pas dans des tables externes.
Vous pouvez utiliser l'instruction INSERT pour écrire des données dans une table partitionnée. Hologres V1.3 et versions ultérieures prennent également en charge l'écriture dans une table partitionnée parente.
Le mot-clé
RETURNINGn'est pas pris en charge dans les instructions INSERT des versions de Hologres antérieures à la V3.2. Il est pris en charge à partir de Hologres V3.2.
-
INSERT ON CONFLICT mono-ligne
-
Les scénarios suivants sont pris en charge :
Une instruction INSERT sans clause
ON CONFLICT.Une instruction INSERT avec une clause
ON CONFLICT DO NOTHING.Une instruction INSERT avec une clause
ON CONFLICT DO UPDATE. Pour utiliser un plan fixe, vous devez mettre à jour toutes les colonnes non liées à la clé primaire (non-PK) spécifiées dans l'instruction INSERT. Vous pouvez éventuellement mettre à jour les colonnes de clé primaire (PK). La mise à jour doit utiliser le formatcol = excluded.col. Dans Hologres V1.3 et versions ultérieures, vous pouvez mettre à jour un sous-ensemble de colonnes non-PK, mais le formatcol = excluded.colreste requis.
-
Exemple :
BEGIN; CREATE TABLE test_insert_oneline ( pk1 INT, pk2 INT, col1 INT, col2 INT, PRIMARY KEY (pk1, pk2) ); COMMIT; -- Update all non-PK columns. A Fixed Plan can be used. INSERT INTO test_insert_oneline VALUES (1, 2, 3, 4) ON CONFLICT (pk1, pk2) DO UPDATE SET col1 = excluded.col1, col2 = excluded.col2; -- Update all columns, including PK and non-PK columns. A Fixed Plan can be used. INSERT INTO test_insert_oneline VALUES (1, 2, 3, 4) ON CONFLICT (pk1, pk2) DO UPDATE SET col1 = excluded.col1, col2 = excluded.col2, pk1 = excluded.pk1, pk2 = excluded.pk2; -- A Fixed Plan requires updating all non-PK columns specified in the INSERT statement. Because col2 is omitted, this statement is supported only in Hologres V1.3 and later. INSERT INTO test_insert_oneline VALUES (1, 2, 3, 4) ON CONFLICT (pk1, pk2) DO UPDATE SET col1 = excluded.col1; -- A Fixed Plan is not supported because the update uses a literal value instead of the required 'col = excluded.col' format. INSERT INTO test_insert_oneline VALUES (1, 2, 3, 4) ON CONFLICT (pk1, pk2) DO UPDATE SET col1 = excluded.col1, col2 = 5;
-
-
INSERT ON CONFLICT multi-lignes
-
Pour les opérations INSERT ON CONFLICT multi-lignes, utilisez la syntaxe suivante :
SET hg_experimental_enable_fixed_dispatcher_for_multi_values = ON; INSERT INTO TABLE (col1, col2, col3..) VALUES (?, ?, ?..), (?, ?, ?..) ON CONFLICT xxx;Vous devez définir le paramètre GUC
hg_experimental_enable_fixed_dispatcher_for_multi_values = on;. Dans Hologres V1.3.35 et versions ultérieures, ce paramètre est défini suronpar défaut.Ces opérations ne garantissent pas l'atomicité. Une opération réussie écrit toutes les lignes. En cas d'erreur, certaines lignes ou aucune ligne n'auront peut-être été écrites.
-
Vous pouvez également utiliser la syntaxe suivante pour écrire plusieurs lignes :
SET hg_experimental_enable_fixed_dispatcher_for_multi_values = ON; INSERT INTO TABLE SELECT unnest(ARRAY[TRUE, FALSE, TRUE]::bool[]), unnest(ARRAY[1, 2, 3]::int4[]), unnest(ARRAY[1.11, 2.222, 3]::float4[]) ON CONFLICT xxx;Vous devez définir le paramètre GUC
hg_experimental_enable_fixed_dispatcher_for_multi_values=on;.Vous ne pouvez pas écrire de données dans des colonnes de type tableau.
Les tableaux dans la fonction
unnestdoivent être explicitement convertis (cast) vers les types tableau des colonnes correspondantes.
Exemple :
BEGIN; CREATE TABLE test_insert_multiline ( pk1 int8, col1 float4, PRIMARY KEY (pk1) ); COMMIT; -- A Fixed Plan is supported. SET hg_experimental_enable_fixed_dispatcher_for_multi_values = ON; INSERT INTO test_insert_multiline SELECT unnest(ARRAY[1, 2, 3]::int8[]), unnest(ARRAY[1.11, 2.222, 3]::float4[]) ON CONFLICT DO NOTHING; -- The ARRAY in the unnest function is not explicitly cast. A Fixed Plan is not supported. INSERT INTO test_insert_multiline SELECT unnest(ARRAY[1, 2, 3]), unnest(ARRAY[1.11, 2.222, 3]) ON CONFLICT DO NOTHING; -- The first column is of the int8 type, so the array should be cast to int8[]. -- In this example, it is cast to int4[], so a Fixed Plan is not supported. INSERT INTO test_insert_multiline SELECT unnest(ARRAY[1, 2, 3]::int4[]), unnest(ARRAY[1.11, 2.222, 3]::float4[]) ON CONFLICT DO NOTHING;
-
-
Scénarios de mise à jour partielle
Hologres prend en charge la mise à jour de colonnes spécifiques d'une table à l'aide de la clé primaire. Un plan fixe peut également être utilisé pour les mises à jour partielles si les conditions suivantes sont remplies :
Le nombre et l'ordre des colonnes dans la liste INSERT doivent correspondre à ceux de la liste UPDATE.
La mise à jour doit utiliser le format
col = excluded.col.
-
UPSERT conditionnel
Pour gérer les données amont arrivant dans le désordre pour les lignes partageant la même clé primaire, Hologres propose une fonctionnalité similaire à l'opération CheckAndPut de HBase. Vous pouvez utiliser un Fixed Plan pour les instructions
INSERTouUPDATEavec une clause conditionnelle si les conditions suivantes sont remplies :Cette fonctionnalité est prise en charge pour les insertions de ligne unique. Pour les insertions multi-lignes, vous devez définir le paramètre GUC
set hg_experimental_enable_fixed_dispatcher_for_multi_values=on;.La clause
WHEREne doit contenir qu'une seule colonne non-PK, et l'opérateur de comparaison doit être l'un des suivants :=, <>, >, >=, <, <=, IS NULL, or IS NOT NULL. Vous pouvez utiliser la fonctioncoalescesur cette colonne non-PK.
Exemple :
BEGIN; CREATE TABLE test_check_and_insert ( pk INT, col INT, scn INT, PRIMARY KEY (pk) ); COMMIT; -- A Fixed Plan is supported. -- Compare the existing column value with a constant. INSERT INTO test_check_and_insert AS old VALUES (1, 1, 1) ON CONFLICT (pk) DO UPDATE SET col = excluded.col, scn = excluded.scn WHERE old.scn > 0; -- Compare the existing column value with the new value being inserted. INSERT INTO test_check_and_insert AS old VALUES (1, 1, 1) ON CONFLICT (pk) DO UPDATE SET col = excluded.col, scn = excluded.scn WHERE old.scn > excluded.scn; -- If the existing value might be NULL, use coalesce. INSERT INTO test_check_and_insert AS old VALUES (1, 1, 1) ON CONFLICT (pk) DO UPDATE SET col = excluded.col, scn = excluded.scn WHERE coalesce(old.scn, 3) > 2; INSERT INTO test_check_and_insert AS old VALUES (1, 1, 1) ON CONFLICT (pk) DO UPDATE SET col = excluded.col, scn = excluded.scn WHERE coalesce(old.scn, 3) > excluded.scn; -- A Fixed Plan is supported. SET hg_experimental_enable_fixed_dispatcher_for_multi_values = ON; -- Compare the existing column value with a constant. INSERT INTO test_check_and_insert AS old VALUES (1, 1, 1), (2, 3, 4) ON CONFLICT (pk) DO UPDATE SET col = excluded.col, scn = excluded.scn WHERE old.scn > 3; -- The unnest syntax is also supported. INSERT INTO test_check_and_insert AS old SELECT unnest(ARRAY[5, 6, 7]::int[]), unnest(ARRAY[1, 1, 1]::int[]), unnest(ARRAY[1, 1, 1]::int[]) ON CONFLICT (pk) DO UPDATE SET col = excluded.col, scn = excluded.scn WHERE old.scn > 3; -
Colonnes par défaut
Vous pouvez utiliser un Fixed Plan pour écrire dans une table contenant une colonne avec une valeur DEFAULT si les conditions suivantes sont remplies :
Cette fonctionnalité est prise en charge pour les insertions de ligne unique. Pour les insertions multi-lignes, votre instance Hologres doit être en version V1.1.36 ou ultérieure. Si votre instance utilise une version antérieure, effectuez une mise à niveau. Vous devez également définir le paramètre GUC
set hg_experimental_enable_fixed_dispatcher_for_multi_values=on;.Hologres V1.3 et les versions ultérieures prennent en charge le Fixed Plan pour la clause
Insert on conflictsur les tables disposant d'une colonne Default. Dans les instances de versions antérieures, le Fixed Plan n'est pas pris en charge pour la clauseInsert on conflictsur les tables disposant d'une colonne Default.
Exemple :
BEGIN; CREATE TABLE test_insert_default ( pk1 INT, col1 INT DEFAULT 99, PRIMARY KEY (pk1) ); COMMIT; -- A Fixed Plan is supported. INSERT INTO test_insert_default (pk1) VALUES (1); -- This requires Hologres V1.1.36 or later. SET hg_experimental_enable_fixed_dispatcher_for_multi_values = ON; INSERT INTO test_insert_default (pk1) VALUES (1), (2), (3); -
Colonnes SERIAL
Vous pouvez utiliser un Fixed Plan pour les écritures de ligne unique ou multi-lignes dans une table dotée d'une colonne SERIAL à incrémentation automatique si les conditions suivantes sont remplies :
Vous devez définir le paramètre GUC
set hg_experimental_enable_fixed_dispatcher_autofill_series=on;. Dans Hologres V1.3.25 et les versions ultérieures, la valeur par défaut de ce paramètre eston.Pour les insertions multi-lignes, vous devez également définir le paramètre GUC
set hg_experimental_enable_fixed_dispatcher_for_multi_values=on;.
Exemple :
BEGIN; CREATE TABLE test_insert_serial ( pk1 INT, col1 SERIAL, PRIMARY KEY (pk1) ); COMMIT; -- A Fixed Plan is supported. SET hg_experimental_enable_fixed_dispatcher_autofill_series = ON; INSERT INTO test_insert_serial (pk1) VALUES (1); -- A Fixed Plan is supported. SET hg_experimental_enable_fixed_dispatcher_autofill_series = ON; SET hg_experimental_enable_fixed_dispatcher_for_multi_values = ON; INSERT INTO test_insert_serial (pk1) VALUES (1), (2), (3);
Scénarios de mise à jour
-
Instruction UPDATE
Une instruction
UPDATEcomportant les clauses suivantes peut utiliser un fixed plan.SET hg_experimental_enable_fixed_dispatcher_for_update = ON; UPDATE TABLE SET col1 = ?,col2 = ? WHERE pk1 = ? AND pk2 = ?; -
Remarques d'utilisation
Une instruction
UPDATEpeut utiliser un fixed plan si les conditions suivantes sont remplies :Vous pouvez mettre à jour des tables internes et des tables partitionnées enfants, mais pas des tables externes ou des tables partitionnées parentes. La table doit disposer d'une clé primaire (PK).
Vous devez exécuter la commande
SET hg_experimental_enable_fixed_dispatcher_for_update = ON;. À partir de Hologres V1.3.25, ce paramètre est obsolète. Les instructionsUPDATEéligibles utilisent automatiquement un fixed plan. Toutefois, pour mettre à jour plusieurs lignes simultanément, vous devez exécuter la commandeSET hg_experimental_enable_fixed_dispatcher_for_multi_values = ON;.Les colonnes spécifiées dans la clause
SETne peuvent pas être des colonnes de clé primaire.La clause
WHEREdoit spécifier toutes les colonnes de clé primaire. Dans Hologres V1.3 et les versions ultérieures, la dernière condition de la clauseWHEREpeut porter sur une colonne non-clé primaire et utiliser les opérateurs de comparaison=, <>, >, >=, <, <=, IS NULL, and IS NOT NULLou la fonctioncoalesce.Vous pouvez utiliser
pk in (?,?,?) or pk = ANY(...)pour mettre à jour plusieurs lignes dans une seule instruction. Par exemple,pk1 in (1,2) and pk2 = any('{3,4}') and pk3 = 5met à jour les quatre lignes :(1,3,5), (1,4,5), (2,3,5), and (2,4,5).Chaque colonne de la clause
WHEREne peut avoir qu'une seule condition. Les conditions identiques sont traitées comme une seule condition.
Exemples :
BEGIN; CREATE TABLE test_update ( pk1 INT, pk2 INT, col1 INT, col2 INT, PRIMARY KEY (pk1, pk2) ); COMMIT; -- Fixed plan supported. SET hg_experimental_enable_fixed_dispatcher_for_update = ON; UPDATE test_update SET col1 = 1, col2 = 2 WHERE pk1 = 3 AND pk2 = 4; -- Fixed plan supported. SET hg_experimental_enable_fixed_dispatcher_for_update = ON; UPDATE test_update SET col1 = 1 WHERE pk1 = 3 AND pk2 = 4; -- Fixed plan supported (Hologres V1.3+, WHERE clause with a non-primary key column). SET hg_experimental_enable_fixed_dispatcher_for_update = ON; UPDATE test_update SET col1 = 1 WHERE pk1 = 3 AND pk2 = 4 AND col1 > 3; -- Fixed plan supported (Hologres V1.3+, WHERE clause with a non-primary key column and coalesce). SET hg_experimental_enable_fixed_dispatcher_for_update = ON; UPDATE test_update SET col1 = 1 WHERE pk1 = 3 AND pk2 = 4 AND coalesce(col1, 4) <> 1; -- Fixed plan supported. SET hg_experimental_enable_fixed_dispatcher_for_update = ON; UPDATE test_update SET col1 = 1, col2 = 2 WHERE pk1 IN (1, 2) AND pk2 = ANY ('{3,4}'); -- Fixed plan supported (Hologres V1.3+, WHERE clause with a non-primary key column). SET hg_experimental_enable_fixed_dispatcher_for_update = ON; UPDATE test_update SET col1 = 1 WHERE pk1 IN (1, 2) AND pk2 = ANY('{3,4}') AND col1 > 3; -- Fixed plan not supported (multiple conditions on pk1). UPDATE test_update SET col1 = 1, col2 = 2 WHERE pk1 = 3 AND pk1 = 4; -- Fixed plan not supported (multiple conditions on pk1). UPDATE test_update SET col1 = 1, col2 = 2 WHERE pk1 IN (1, 2) AND pk1 = 1; -- Fixed plan supported (multiple identical conditions on pk1). SET hg_experimental_enable_fixed_dispatcher_for_update = ON; UPDATE test_update SET col1 = 1, col2 = 2 WHERE pk1 IN (1, 2) AND pk1 IN (1, 2) AND pk2 = 4;
Scénarios de suppression
-
Instruction DELETE
L'instruction suivante montre comment utiliser un fixed plan pour une opération
DELETE:SET hg_experimental_enable_fixed_dispatcher_for_delete = ON; DELETE FROM TABLE WHERE pk1 = ? AND pk2 = ? AND pk3 = ?; -
Remarques d'utilisation
Une opération
DELETEpeut utiliser un fixed plan si elle respecte les conditions suivantes :L'opération doit cibler une table interne ou une table enfant, et non une table externe ou une table partitionnée parente. La table doit également disposer d'une clé primaire (PK).
Vous devez définir le paramètre GUC
hg_experimental_enable_fixed_dispatcher_for_delete=on;. Dans Hologres V1.3.25 et les versions ultérieures, ce paramètre est obsolète. Les instructionsDELETEéligibles utilisent un fixed plan par défaut. Toutefois, pour supprimer plusieurs lignes, vous devez exécuter la commandeset hg_experimental_enable_fixed_dispatcher_for_multi_values =on.La clause
WHEREdoit spécifier des conditions pour toutes les colonnes de clé primaire. À partir de Hologres V1.3, la dernière condition de la clauseWHEREpeut s'appliquer à un champ non-clé primaire, qui prend en charge les opérateurs de comparaison=, <>, >, >=, <, <=, IS NULL, and IS NOT NULL, ainsi que la fonctioncoalesce.Vous pouvez utiliser
pk in (?,?,?) or pk = ANY()pour supprimer plusieurs lignes en une seule opération. Par exemple,pk1 in (1,2) and pk2 = any('{3,4}') and pk3 = 5supprime les quatre lignes :(1,3,5), (1,4,5), (2,3,5), and (2,4,5).Chaque colonne ne peut avoir qu'une seule condition dans la clause
WHERE. Les conditions en double sont traitées comme une seule condition.
Exemple :
BEGIN; CREATE TABLE test_delete ( pk1 INT, pk2 INT, col1 INT, col2 INT, PRIMARY KEY (pk1, pk2) ); COMMIT; -- This DELETE statement uses a fixed plan. For more scenarios, see the examples for the UPDATE statement. SET hg_experimental_enable_fixed_dispatcher_for_delete = ON; DELETE FROM test_delete WHERE pk1 = 1 AND pk2 = 2;
Scénarios SELECT
-
Instructions SELECT
Un fixed plan est pris en charge pour les instructions SELECT contenant des clauses spécifiques.
SELECT col1, col2, col3, ... FROM TABLE WHERE pk1 = ? AND pk2 = ? AND pk3 = ?;La requête doit cibler une table interne, et non une table externe.
La requête doit cibler une table partitionnée enfant, et non une table partitionnée parente.
La table doit disposer d'une clé primaire (PK).
-
Scénarios de requête ponctuelle (clé/valeur)
Les conditions suivantes s'appliquent aux requêtes ponctuelles utilisant un fixed plan.
La clause
WHEREdoit contenir toutes les colonnes de la clé primaire, et uniquement celles-ci.Vous pouvez utiliser
pk in (?,?,?) or pk = ANY()pour interroger plusieurs lignes simultanément. Par exemple,pk1 in (1,2) and pk2 = any('{3,4}') and pk3 = 5interroge quatre lignes :(1,3,5),(1,4,5),(2,3,5),(2,4,5).Chaque colonne ne peut avoir qu'une seule condition. Les conditions en double sont traitées comme une seule.
Si une clause
LIMITest incluse, sa valeur doit être>0.
Exemple :
BEGIN; CREATE TABLE test_select ( pk1 INT, pk2 INT, col1 INT, col2 INT, PRIMARY KEY (pk1, pk2) ); CALL set_table_property ('test_select', 'orientation', 'row'); COMMIT; --A fixed plan is supported for this query. SELECT * FROM test_select WHERE pk1 = 1 AND pk2 = 2; -
Scénarios PrefixScan
-
Clauses PrefixScan
Un PrefixScan s'applique aux requêtes sur des tables dotées d'une clé primaire composite. Ces requêtes utilisent le principe de correspondance du préfixe le plus à gauche pour filtrer sur un préfixe des colonnes de clé primaire. Le code suivant présente des exemples de telles clauses :
SET hg_experimental_enable_fixed_dispatcher_for_scan = on; SELECT col1,col2,col3,... FROM TABLE WHERE pk1 = ? AND pk2 = ?; SELECT col1,col2,col3,... FROM TABLE WHERE pk1 = ? AND pk2 < ?;--From Hologres V1.1.48, the last column of the PK prefix can be a range condition. SELECT col1,col2,col3,... FROM TABLE WHERE pk1 = ? AND pk2 BETWEEN ? AND ?;--From Hologres V1.1.48, the last column of the PK prefix can be a range condition. -
Utilisation de PrefixScan
Les conditions suivantes doivent être remplies pour utiliser PrefixScan :
Le paramètre GUC
hg_experimental_enable_fixed_dispatcher_for_scan=on;doit être défini et l'instance Hologres doit être en version V1.3.35 ou ultérieure.La table doit disposer d'une clé de distribution et la clause
WHEREdoit inclure toutes les colonnes de la clé de distribution.-
La clause
WHEREne peut contenir qu'un préfixe de la clé primaire. Dans Hologres V1.1.48 et les versions ultérieures, une condition de plage (avec une borne supérieure et inférieure) peut également être spécifiée pour la dernière colonne du préfixe de clé primaire.RemarqueDéfinition d'un préfixe : Si une clé primaire est
(pk1,pk2,pk3), alors(pk1)et(pk1,pk2)en sont des préfixes. Seules les tables orientées ligne et hybrides ligne-colonne prennent en charge PrefixScan.
Chaque colonne ne peut avoir qu'une seule condition. Les conditions en double sont traitées comme une seule.
Si une clause
LIMITest incluse, sa valeur doit être > 0.
RemarqueUn PrefixScan renvoie toutes les lignes de résultat en une seule fois. Si la taille totale en octets des résultats dépasse la valeur de
hg_experimental_fixed_scan_bytesize_limit, une erreur est renvoyée :scan result size larger than fixed scan size limit. Vous pouvez configurer le paramètrehg_experimental_fixed_scan_bytesize_limitavec une valeur adaptée à votre scénario. La valeur par défaut est 1 048 576 (1 Mo).Par exemple, supposons que la clé primaire d'une table soit
(pk1,pk2,pk3,pk4)et que sa clé de distribution soitpk1,pk3.BEGIN; CREATE TABLE test_select_prefix ( pk1 INT, pk2 INT, pk3 INT, pk4 INT, PRIMARY KEY (pk1, pk2, pk3, pk4) ); CALL set_table_property ('test_select_prefix', 'orientation', 'row'); CALL set_table_property ('test_select_prefix', 'distribution_key', 'pk1,pk3'); COMMIT; --Does not include all distribution key columns. A fixed plan cannot be used. SELECT * FROM test_select_prefix WHERE pk1 = ? AND pk2 = ?; --Not a prefix of the primary key. A fixed plan cannot be used. SELECT * FROM test_select_prefix WHERE pk1 = ? AND pk3 = ?; --A fixed plan can be used. SET hg_experimental_enable_fixed_dispatcher_for_scan = ON; SELECT * FROM test_select_prefix WHERE pk1 = ? AND pk2 = ? AND pk3 = ?;Vous pouvez utiliser
pk in (?,?,?)oupk = ANY()pour interroger plusieurs lignes simultanément, comme illustré dans les exemples suivants.pk1 IN (1,2) AND pk2 = 3 --Equivalent to scanning two key groups: (1,3) and (2,3). pk2 =any('{3,4}') AND pk1 IN (1,2) --Equivalent to scanning four key groups: (1,3), (1,4), (2,3), and (2,4). -
Exemple d'utilisation
BEGIN; CREATE TABLE test_scan ( pk1 INT, pk2 INT, pk3 INT, col1 INT, PRIMARY KEY (pk1, pk2, pk3) ); CALL set_table_property ('test_scan', 'orientation', 'row'); CALL set_table_property ('test_scan', 'distribution_key', 'pk1,pk2'); COMMIT; INSERT INTO test_scan VALUES (1, 2, 3, 4); --A fixed plan is supported. SET hg_experimental_enable_fixed_dispatcher_for_scan = ON; SELECT * FROM test_scan WHERE pk1 = 1 AND pk2 = 2; --A fixed plan is supported. SET hg_experimental_enable_fixed_dispatcher_for_scan = ON; SELECT * FROM test_scan WHERE pk1 = 1 AND pk2 IN (2, 3); --A fixed plan is supported. SET hg_experimental_enable_fixed_dispatcher_for_scan = ON; SELECT * FROM test_scan WHERE pk1 = ANY ('{3,4}') AND pk2 IN (2, 3); --A fixed plan is supported. The last column of the PK is a range condition. Requires Hologres V1.1.48 or later. SET hg_experimental_enable_fixed_dispatcher_for_scan = ON; SELECT * FROM test_scan WHERE pk1 = 1 AND pk2 = 1 AND pk3 > 1 AND pk3 < 4; --A fixed plan is supported. The last column of the PK is a range condition. Requires Hologres V1.1.48 or later. SET hg_experimental_enable_fixed_dispatcher_for_scan = ON; SELECT * FROM test_scan WHERE pk1 = 1 AND pk2 = 1 AND pk3 BETWEEN 1 AND 4; --Does not include all distribution key columns. A fixed plan is not supported. SELECT * FROM test_scan WHERE pk1 = 1; --Does not match a primary key prefix. A fixed plan is not supported. SELECT * FROM test_scan WHERE pk2 = 2;
-
-
Scénarios de pagination
Dans Hologres V3.2 et les versions ultérieures, le fixed plan prend en charge les requêtes PrefixScan utilisant la pagination.
RemarquePar défaut, les résultats d'un PrefixScan sont triés par ordre croissant de la clé primaire. Dans l'exemple SQL suivant, un PrefixScan sur
pk1etpk2renvoie des résultats triés par ordre croissant depk3.Pour spécifier l'ordre de tri, vous pouvez définir l'ordre des colonnes dans la clustering key et définir le paramètre GUC correspondant dans votre requête, ce qui trie les résultats selon la clustering key. Les colonnes de la clustering key doivent être identiques aux colonnes de la clé primaire. Dans l'exemple SQL suivant, pour trier les résultats par ordre décroissant, vous pouvez définir la dernière colonne de la clustering key sur
pk3:desc.
-
Ordre croissant
-- Create a table. CREATE TABLE test_scan( pk1 INT, pk2 INT, pk3 INT, col1 INT, PRIMARY KEY(pk1, pk2, pk3) ) WITH ( orientation = 'row', distribution_key = 'pk1,pk2', clustering_key = 'pk1:asc,pk2:asc,pk3:asc' ); -- Insert data. INSERT INTO test_scan VALUES (1,2,3,4),(1,2,5,6),(1,2,7,8); -- `offset + limit` is supported. Based on PrefixScan, this query returns a specified number of rows starting from a specified offset. SET hg_experimental_enable_fixed_dispatcher_for_scan = on; -- By default, the results are sorted in ascending order of pk3. SELECT * FROM test_scan WHERE pk1 = 1 AND pk2 = 2 OFFSET 1 limit 2; -
Ordre décroissant
-- Create a table. CREATE TABLE test_scan( pk1 INT, pk2 INT, pk3 INT, col1 INT, PRIMARY KEY(pk1, pk2, pk3) ) WITH ( orientation = 'row', distribution_key = 'pk1,pk2', clustering_key = 'pk1:asc,pk2:asc,pk3:desc' ); -- Insert data. INSERT INTO test_scan VALUES (1,2,3,4),(1,2,5,6),(1,2,7,8); -- Enable both of the following GUC parameters to sort the results in descending order of pk3. SET hg_experimental_enable_fixed_dispatcher_for_scan = on; SET hg_experimental_enable_fixed_dispatcher_for_clustering_key_scan = on; SELECT * FROM test_scan WHERE pk1 = 1 AND pk2 = 2 OFFSET 1 limit 2;
Scénarios d'utilisation de COPY
À partir de la version V1.3.17 de Hologres, l'instruction COPY peut utiliser un plan fixe, une fonctionnalité appelée Fixed Copy. Pour comparer les instructions COPY et Fixed Copy, consultez la rubrique Bonnes pratiques pour l'écriture par lots.
Pour plus d'informations sur les paramètres de Fixed Copy, consultez la section COPY. Voici un exemple :
COPY table_name (column0, column1, column2)
FROM
STDIN WITH (
format BINARY,
stream_mode TRUE,
on_conflict UPDATE);
Lorsque vous omettez des colonnes dans une instruction COPY, le comportement est le suivant :
-
Si l'instruction
COPYspécifie un sous-ensemble des colonnes de la table, elle effectue une mise à jour partielle. Par exemple :CREATE TABLE t0 ( id INT NOT NULL, name TEXT, age INT, PRIMARY KEY (id) ); COPY t0 (id, name) FROM STDIN WITH (stream_mode TRUE, on_conflict UPDATE); -- The COPY statement above is equivalent to the following INSERT INTO statement: INSERT INTO t0 (id, name) VALUES (?, ?) ON CONFLICT (id) DO UPDATE SET id = excluded.id, name = excluded.name; -
Si les colonnes omises possèdent une valeur par défaut, l'instruction
COPYse comporte comme suit :CREATE TABLE t0 ( id INT NOT NULL, name TEXT, age INT DEFAULT 0, PRIMARY KEY (id) ); COPY t0 (id, name) FROM STDIN WITH (stream_mode TRUE, on_conflict UPDATE); -- The COPY statement above is equivalent to the following INSERT INTO statement: -- If the ID does not exist, a new row is inserted, and the age column is set to its default value. -- If the ID already exists, the row is updated, and the age column remains unchanged. INSERT INTO t0 (id, name, age) VALUES (?, ?, DEFAULT) ON CONFLICT (id) DO UPDATE SET id = excluded.id, name = excluded.name;
Expressions dans les plans fixes
À partir de la version V3.2 de Hologres, la fonctionnalité Fixed Plan prend en charge les expressions dans les instructions SQL. Pour plus d'informations sur les expressions dans PostgreSQL, consultez la documentation Expressions. Les scénarios pris en charge incluent :
-
Instructions INSERT :
Clause VALUES
Clause INSERT ON CONFLICT DO UPDATE
Condition de filtre dans la clause INSERT ON CONFLICT WHERE
Clause RETURNING
-
Instructions SELECT :
Liste SELECT
Limites
Seules les expressions et fonctions scalaires sont prises en charge. Les fonctions d'agrégation, les fonctions de fenêtrage et les sous-requêtes ne sont pas prises en charge.
Pour les instructions INSERT, les expressions et fonctions utilisées dans les clauses autres que la clause VALUES doivent être prises en charge par HQE.
Pour les instructions SELECT, Fixed Plan prend uniquement en charge les expressions et fonctions IMMUTABLE qui acceptent un argument constant.
-
Pour utiliser cette fonctionnalité, vous devez activer le paramètre suivant :
-- Enable at the session level SET hg_experimental_enable_fixed_plan_expression = on; -- Enable at the database level ALTER DATABASE <db_name> SET hg_experimental_enable_fixed_plan_expression = on;
Exemples
-
Utilisation d'expressions dans les quatre clauses prises en charge d'une instruction INSERT
-- Create a table. CREATE TABLE test_t ( id INT PRIMARY KEY, col INT, ts TIMESTAMP ) WITH ( orientation = 'row', distribution_key = 'id' ); -- Enable the GUC parameter. SET hg_experimental_enable_fixed_plan_expression = ON; -- Use an expression in the VALUES clause. INSERT INTO test_t VALUES (1, 1, now()); -- Use an expression in the ON CONFLICT DO UPDATE clause. INSERT INTO test_t AS old VALUES (1, 1, now()) ON CONFLICT (id) DO UPDATE SET col = excluded.col + old.col, ts = excluded.ts; -- Use an expression in the ON CONFLICT WHERE clause. INSERT INTO test_t AS old VALUES (1, 1, now()) ON CONFLICT (id) DO UPDATE SET col = excluded.col + old.col, ts = excluded.ts WHERE excluded.ts > old.ts; -- Use an expression in the RETURNING clause. INSERT INTO test_t AS old VALUES (1, 1, now()) ON CONFLICT (id) DO UPDATE SET col = excluded.col + old.col, ts = excluded.ts WHERE excluded.ts > old.ts RETURNING 2 * col, ts; -
Utilisation d'expressions dans la liste SELECT d'une instruction SELECT
-
Requête ponctuelle utilisant une clé primaire complète : cet exemple extrait la valeur d'une clé d'une colonne JSONB.
-- Create a table. CREATE TABLE test_t ( id int PRIMARY KEY, ts TIMESTAMP NOT NULL, col JSONB ) WITH ( orientation = 'row', distribution_key = 'id' ); -- Use expressions in the SELECT list. JSONB operators are supported. SELECT (col ->> 'b')::int + (col ->> 'a')::int, date_trunc('day', ts) FROM test_t WHERE id = 1; -
PrefixScan utilisant un préfixe de clé primaire.
-- Create a table. CREATE TABLE test_t ( id INT, ts TIMESTAMP NOT NULL, col JSONB, PRIMARY KEY (id, ts) ) WITH ( orientation = 'row', distribution_key = 'id' ); -- Enable the GUC parameter. SET hg_experimental_enable_fixed_dispatcher_for_scan = TRUE; -- Use expressions in the SELECT list. SELECT (col ->> 'b')::int + (col ->> 'a')::int, date_trunc('day', ts) FROM test_t WHERE id = 1;
-
-
Une instruction SELECT ne peut pas être optimisée par Fixed Plan si elle contient des fonctions non IMMUTABLE ou des fonctions qui n'acceptent pas d'argument constant.
-- Create a table. CREATE TABLE test_t ( id INT PRIMARY KEY, ts TIMESTAMP NOT NULL, col JSONB ) WITH ( orientation = 'row', distribution_key = 'id' ); -- The random() function is not immutable and is not supported by Fixed Plan. SELECT id + random() FROM test_t WHERE id = 1; -- The toString function does not accept a constant argument and is not supported by Fixed Plan. SELECT toString (id) FROM test_t WHERE id = 1;
Vérification d'un plan fixe
Dans la console, les instructions
INSERT,UPDATEetDELETEexécutées à l'aide d'un plan fixe apparaissent comme de type SDK dans le panneau Real-time Import (RPS). Nous vous recommandons d'utiliser des plans fixes pour ces opérations d'écriture en temps réel afin d'améliorer l'efficacité des mises à jour de données.
Pour afficher le plan d'exécution SQL, exécutez une instruction
EXPLAIN. Si le plan d'exécution renvoyé contientFixedXXXNode, un plan fixe a été déclenché, comme illustré dans la figure suivante. Si le plan d'exécution ne contient pasFixedXXXNode, vérifiez les conditions de prise en charge décrites dans les sections précédentes et assurez-vous que votre instruction respecte les exigences.
Optimisation des performances
Si vous devez encore optimiser les performances avec un plan fixe activé, vous pouvez utiliser les méthodes suivantes.
Analysez le plan d'exécution pour identifier les goulots d'étranglement. Exécutez
EXPLAINsur une instruction SQL pour visualiser le temps consommé à chaque étape et localiser les goulots d'étranglement.Les versions 1.1.49 et ultérieures de Hologres sont optimisées pour les requêtes ponctuelles utilisant un plan fixe, ce qui améliore le débit de plus de 30 % dans les scénarios à grande échelle. Pour bénéficier de cette amélioration, mettez à niveau votre instance vers la version V1.1.49 ou une version ultérieure.
Utilisez le regroupement côté client avec une taille de lot de 512 ou un multiple de 512. Holo Client gère automatiquement le regroupement.
FAQ
-
Symptôme : Lorsque vous tentez de vous connecter à Hologres, l'erreur suivante se produit :
role/database does not exist.Cause : L'utilisateur ou la base de données spécifié(e) n'existe pas.
-
Solution : Vérifiez vos informations de connexion et assurez-vous que le nom d'utilisateur et le nom de la base de données sont corrects.
Connectez-vous à la console Hologres. Trouvez l'instance cible et cliquez sur Manage dans la colonne Actions. Cliquez sur Database Management. Vous pouvez ensuite vérifier le nom d'utilisateur sur la page Users et le nom de la base de données sur la page Database Authorization.
-
Symptôme : Lors d'une opération d'écriture de données, l'erreur suivante se produit :
the requested table name: xxx (id: xx, version: xx) mismatches the version of the table (id: xx, version: xx) from server.Cause : Les métadonnées de la table changent pendant l'opération d'écriture de données (par exemple, une colonne est ajoutée), ce qui modifie la version de la table.
Solution : Rétablissez la connexion. Le plan fixe récupère alors les nouvelles métadonnées de la table pour terminer l'opération d'écriture.