2009-10-27 6 views
1

J'ai une table avec une colonne InTime et une colonne OutTime.Indexer les performances nulles par rapport aux données fictives

Normalement, lorsque j'insère des données dans cette table, je définis l'InTime sur un DateTime et l'OutTime sur null. Lorsque les données sont supprimées, une valeur OutTime est définie.

Quand je reçois des données pour un moment donné, j'utiliser quelque chose comme:

where InTime < sometime and OutTime is > sometime or OutTime is null 

Ma question est, en termes d'amélioration des performances des requêtes/index dois-je mettre une certaine valeur dans OutTime comme le max datetime et rendre le champ non nullable?

Alors ma question devient

where InTime < sometime and OutTime is > sometime 
+1

La base de données elle-même vous donnera la meilleure réponse à cette question. Utilisez EXPLAIN sur diverses requêtes et voyez quels index ils utilisent et comment ils exécutent le qery. –

Répondre

2

Laissez le NULL champ. N'utilisez pas OU, utilisez UNION ALL:

select ... from ... where InTime < sometime and OutTime is > sometime 
union all 
select ... from ... where InTime < sometime and OutTime is null 

L'utilisation de valeurs magiques au lieu de NULL est une recette pour un désastre. À tout le moins, il utilise plus de stockage. Plus précisément, il brise la sémantique de NULL lors de l'application des contraintes de base de données, lors du calcul des agrégats et dans les applications. L'utilisation de OU dans les requêtes pose des problèmes de performance. L'optmizer va probablement transformer n'importe quelle gamme d'index en balayages. L'utilisation de UNION est généralement préférable, car l'optimiseur créera deux plans, l'un optimal pour les NULLs un otpimal pour les non-NULL, et les union. Si vous n'avez aucun index sur Intime et/ou OutTime alors la requête sera de toute façon un scan et l'UNION sera moins performant qu'un OR, mais ce n'est pas un scénario qui vaut la peine d'être évoqué. La question est, bien sûr, comment optimiser une requête sur correctement de stockage conçu.

+0

Si vous affichez le plan d'exécution de la requête d'origine avec l'union toutes les requêtes. L'union est de 67% par rapport au lot. – Spruce

+1

@Spruce: qu'en est-il des E/S et du processeur et de la durée? Le% relatif est parfois trompeur. – gbn

+0

J'ai essayé ceci avec quelques requêtes maintenant, une avec un balayage d'index et une avec une recherche d'index. Dans les deux cas, l'instruction union all exécute la requête deux fois, puis concatène les résultats qui sont reflétés dans le% coût par rapport au lot. Comme vous vous en doutez, les E/S et le CPU sont doubles pour l'union toutes les requêtes car elles doivent être exécutées deux fois. Est-ce que je manque quelque chose? – Spruce

Questions connexes