J'ai un problème avec une requête générée par Hibernate qui n'utilise pas d'index. L'accès à la base de données est fait à partir de Java en utilisant JTDS et la version du serveur est SQL Server , dernier service pack. Le champ est nullable et est une clé étrangère qui, dans certains scénarios spécifiques, peut être complètement nulle, la colonne est indexée via un index non cluster mais l'index n'est jamais utilisé lorsque la colonne est entièrement nulle, créant un grand nombre des analyses de table complètes et des problèmes de performance.Problème lors de l'utilisation d'index avec SQL Server 2005 et Hibernate
La situation pourrait être vérifiée aussi en utilisant l'analyseur de requête standard avec le code SQL suivant:
Créer une table et des index
CREATE TABLE [dbo].[TestNulls](
[PK] [varchar](36) NOT NULL,
[DATA] [varchar](36) NULL,
[DATANULL] [varchar](36) NULL,
CONSTRAINT [PK_TestNulls] PRIMARY KEY NONCLUSTERED
(
[PK] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE NONCLUSTERED INDEX [IDX_DATA] ON [dbo].[TestNulls]
(
[DATA] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF,
IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [IDX_DATANULL] ON [dbo].[TestNulls]
(
[DATANULL] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF,
IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
Remplissez-le avec des données aléatoires en utilisant la fonction newid
declare @i as int
set @i = 0
while (@i < 500000)
begin
set nocount on
insert into TestNulls values(NEWID(), NEWID(), null)
insert into TestNulls values(NEWID(), null, null)
insert into TestNulls values(NEWID(), null, null)
set @i = (@i + 1)
set nocount on
end;
Cette requête effectue un balayage de table complet
declare @p varchar(36)
set @p = NEWID()
select PK, DATA, DATANULL from TestNulls
where DATANULL = @p
Si je complète la requête avec un "et DATANULL IS NOT NULL" la requête utilise maintenant l'index.
Besoin d'aide:
- Comment puis-je forcer la combinaison JTDS/Hibernate pour utiliser l'index (le sendStringParametersAsUnicode est déjà définie sur false par défaut)?
- Existe-t-il un moyen d'ajouter "et column is not null" pour toutes les requêtes hibernate qui utilisent un champ Nullable?
- Une explication de ce problème?
Cordialement Massimo
Problème dans votre approche est que nous utilisons Hibernete pour générer des requêtes et donc nous ne voulons pas utiliser SP. En plus de cela SQL2008 n'a pas ce problème et l'ajout n'est pas nul le résout, donc nous cherchons un moyen simple de forcer la partie "n'est pas nulle" dans la requête sql de hibernate – massimogentilini
Qu'en est-il: Critères critères = session .createCriteria (TestNulls.class); criteria.add (Expression.isNotNull ("DATANULL")); – garik