J'ai une requête qui rejoint deux tables:
DATA CODE> a une colonne TIMESTAMP LI>
- TABLEAU 2
COMMANDES CODE> A Démarrer et mettre fin à des colonnes horodaques li>
ul> sur la table 1 J'ai un index sur la colonne TIMESTAMP et sur la table 2, j'ai un index sur Démarrer | Fin (dans cet ordre). Tout fonctionne bien et est rapide lorsque je les rejoints simplement comme de d joink o sur d.timestamp> O.Start_ts et d.timetamp <= o.end_ts code> p> Le problème est que lorsqu'une commande n'est pas terminée, le end_ts code> est NULL, donc j'ai besoin de modifier ma jointure à d.timestamp <= coalesce (o.end_ts, null) code>, de la Expliquez que je peux voir que maintenant l'analyse de l'index inclut une section code> filtre code> qui rend la course plus lente (de 1 à 14 ans). p> La requête que j'utilise actuellement est la suivante: p> xxx pré> L'expliquer est p> xxx pré> p>
3 Réponses :
Merci à et modifier la requête en Incognito Code> sur IRC J'ai trouvé une solution viable, créez un index comme celui-ci:
PD. horodatage <= coalesce (o.end_time, "infini") code>.
De cette façon, j'ai toujours la valeur nullable et j'ai une valeur indexée que je peux utiliser, car je ne pouvais pas indexer le
maintenant () code> car il est variable p> p>
Cela n'est pas équivalent aux exigences énoncées. Plus de rangées pourraient être retournées.
@Serg pourquoi? Dans mon cas, lorsque l'ordre final est NULL signifie qu'il n'est pas terminé, alors l'infini fonctionnerait car c'est toujours plus grand que maintenant ()
"Infinity .. toujours plus grand que maintenant ()" signifie que plus de rangées pourraient être retournées. Vous devez probablement affiner la question concernant votre utilisation de maintenant () code>. Était-ce une requête ou autre chose?
@Sserg Je pense que c'est juste parce que la table code> code> n'a jamais contient des données de l'avenir, il n'y aura donc pas de données avec un horodatage supérieur à maintenant () code>
Ceci est l'un des cas où Types de gamme est utile comme Ils traitent correctement les valeurs nulles.
Créer un index sur la plage: p> puis utilisez la même plage définition dans la condition de jointure p> non liée, mais: j'utiliserais
pd.timetamp <'2019-09-22 22:00:00' code> au lieu d'un
<= code > Opérateur avec un horodatage qui est quelques millisecondes avant 22h00:00 p> p>
Je suis d'accord sur la partie non liée, concernant l'index, pourquoi gist?
@ Alex88: Seul un index GIST prend en charge l'opérateur <@ code> sur les gammes
Votre start_time code>,
end_time code> peut être remplacé par une colonne à une seule gamme, de cette façon, vous n'auriez jamais besoin de vous inquiéter de la manière de représenter des gammes "sans bornes" comme cela fait partie de la valeur de colonne elle-même.
cela aurait un sens, j'ai juste besoin de vérifier comment la bibliothèque de la DB utilisée le soutient
Je pense que le seul inconvénient de cela, c'est que nous ne pouvons pas facilement modifier l'inclusion / exclusion des limites sur la requête sans changer l'index
@ Alex88: Mais ne veut-ils pas toujours dire la même chose? Cela me semble étrange que la règle des limites inclusives / exclusives change de manière aléatoire. Mais si vous avez besoin de cela, une colonne à une seule gamme où ces informations sont stockées avec la valeur elle-même résoudraient le problème. L'index n'a alors besoin que de mentionner la colonne, et non de créer une nouvelle gamme.
Il ne change en fait que lorsque de l'autre côté de la relation la valeur est un agrégat et est lié à la minute précédente ou suivante, mais c'est juste une question de normalisation
Vous pouvez éviter la manipulation spéciale des NULLS en utilisant non (nié_condition) code>. (Mais la solution
Infinity code> est plus propre, IMO)
SELECT *
FROM data pd
JOIN orders o ON pd.timestamp > o.start_time
AND NOT(pd.timestamp > o.end_time )
WHERE pd.machine_id = 19
AND pd.name = 'somevalue'
AND pd.timestamp > '2019-09-15 22:00:00'
AND pd.timestamp <= '2019-09-22 21:59:59.999'
;
Cela a l'air bien aussi, je n'ai pas encore essayé de voir comment la requête explique le gère, mais cela pourrait éviter d'avoir des fonctions dans l'index
S'il vous plaît Modifier B> Votre question et ajoutez le plan d'exécution généré à l'aide d'utiliser
Expliquer (analyser, tampon, texte de format) code> < / b> ( pas i> juste une "simple" expliquer) comme texte formaté et assurez-vous d'empêcher la indentation du plan. Collez le texte, puis mettez
`` ` code> sur la ligne avant le plan et sur une ligne après le plan. Veuillez également inclure les instructions complètes
Créer index code> pour tous les index.
@Belisto Le même résultat, les timings et expliquer sont les mêmes
Essayez
.. sur d.timestamp> O.Start_ts et d.TimeStamp <= o.end_ts Union Tout .. sur PD.TMESTAMP> O.Start_time et O.end_time est null code>
@Sserg qui fonctionne parfaitement pour une simple requête comme celle-ci, mais dans une requête avec des jointures et des clauses de groupe, un syndicat rendrait la requête beaucoup plus longue