En utilisant l'exemple ci-dessous, les prédicats sont les mêmes, cependant l'instruction supérieure (correctement) renvoie 0 lignes, l'instruction inférieure renvoie 1 - même si les prédicats ne correspondent PAS:
declare @barcode nchar(22)=N'RECB012ZUKI449M1VBJZ'
declare @tableId int = null
declare @total decimal(10, 2) = 5.17
SELECT 1
FROM
[dbo].[transaction] WITH (INDEX([IX_Transaction_TransactionID_PaymentStatus_DeviceID_DateTime_All]))
WHERE
Barcode = @barcode
AND StatusID = 1
AND TableID = @tableID
AND @total <= Total
SELECT 1
FROM
[dbo].[transaction]
WHERE
Barcode = @barcode
AND StatusID = 1
AND TableID = @tableID
AND @total <= Total
Pourquoi cela pourrait-il arriver?
Plus d'infos:
- L'index non groupé dans l'instruction supérieure n'est PAS filtré
- CheckDB renvoie 0 problème
- Version du serveur:
Microsoft SQL Azure (RTM) - 12.0.2000.8 Dec 19 2018 08:43:17 Copyright (C) 2018 Microsoft Corporation
Collez le lien Plan:
https://www.brentozar.com/pastetheplan/?id=S1w_rU68E
Plus d'infos:
Ont couru, dbcc checktable ([transaction]) with all_errormsgs, extended_logical_checks, data_purity
ce qui indique aucun problème.
Je peux reproduire le problème de manière fiable sur cette table lors de la restauration d'une sauvegarde de cette base de données.
sql-server
azure-sql-database
columnstore
Uberzen1
la source
la source
Réponses:
Ce bogue ne nécessite pas de supprimer ou de renommer les colonnes.
Vous verrez également le même comportement pour
statusId = 100
lequel il n'a jamais été présent dans aucune version de la colonne.Exigences
Exemple
L'un des éléments suivants évitera le bogue:
= NULL
démo db <> fiddle .
Ce bogue a été corrigé dans CU15 pour SQL Server 2017 (et CU7 pour SQL Server 2016 SP2):
CORRECTIF: requête sur la table avec à la fois l'index clusterstore columnstore et nonclustered rowstore peut renvoyer des résultats incorrects dans SQL Server 2016 et 2017
la source
Il s'agit d'un bogue avec SQL Server. Si une colonne est supprimée d'une table avec un index columnstore en cluster, puis qu'une nouvelle colonne est ajoutée avec le même nom, elle semble utiliser l'ancienne colonne supprimée pour le prédicat. Voici le MVCE:
Ce script commence par des
10000
lignes avecstatusId
de1
etstatusId2
de5
- puis supprime lastatusID
colonne et renommestatusId2
enstatusId
. Donc, à la fin, toutes les lignes doivent avoir unstatusId
5.Mais la requête suivante frappe l'index non cluster ...
... et retourne des
2
lignes (avec la sélectionstatusId
différente de celle impliquée par laWHERE
clause) ...... alors que celui-ci accède au magasin de colonnes et renvoie correctement
0
MVCE
J'ai également soulevé un problème sur le portail de commentaires Azure :
Et pour tous ceux qui rencontrent cela, la reconstruction de l'index de clustered Columnstore résout le problème:
La reconstruction de la CCI ne corrige que les données existantes. Si de nouveaux enregistrements sont ajoutés, le problème se pose à nouveau sur ces enregistrements; donc actuellement le seul correctif connu pour la table est de la recréer entièrement.
la source
and id2 = @id2
doivent garantir aucune ligne de toute façon comme@id2
est ,null
mais vous obtenez toujours le 2REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON);
le travail? Cela effacera le deltastore - le problème persiste-t-il pour les nouvelles lignes ajoutées par la suite?Sur la base des plans, il semble que l'index Columnstore a été créé avec SET ANSI_NULLS OFF. Les tables et les index conservent le paramètre tel qu'il était lors de la création de l'index. Vous pouvez vérifier en créant un index Columnstore en double tout en vous assurant que ANSI_NULLS est activé, puis en supprimant l'original ou en le désactivant.
Mais, à moins que vous n'ayez découvert un bogue SQL Server, c'est la seule façon dont les résultats peuvent se produire.
la source