ফিল্টার শর্তটি ক্লাস্টারড কলামস্টোর সূচীতে সঠিকভাবে প্রয়োগ করা হয়নি


10

নীচের উদাহরণটি ব্যবহার করে, পূর্বাভাসগুলি একই, তবে শীর্ষ বিবৃতি (সঠিকভাবে) 0 টি সারি দেয়, নীচের বিবৃতিটি 1 প্রদান করে - যদিও পূর্বাভাসগুলি মেলে না:

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

কেন এমন হচ্ছে?

আরও তথ্য:

  • শীর্ষ বিবৃতিতে অ ক্লাস্টারযুক্ত সূচক ফিল্টার করা হয় না
  • চেকডিবির 0 টি সমস্যা ফিরে আসে
  • সার্ভার সংস্করণ: Microsoft SQL Azure (RTM) - 12.0.2000.8 Dec 19 2018 08:43:17 Copyright (C) 2018 Microsoft Corporation

পরিকল্পনার লিঙ্কটি আটকে দিন:

https://www.brentozar.com/pastetheplan/?id=S1w_rU68E

আরও তথ্য:

দৌড়ে গেছে dbcc checktable ([transaction]) with all_errormsgs, extended_logical_checks, data_purityযা কোন ইস্যু নির্দেশ করে না।

এই ডাটাবেসের একটি ব্যাকআপ পুনরুদ্ধার করার সময় আমি নির্ভরযোগ্যভাবে এই টেবিলটির বিপরীতে সমস্যাটি পুনরুত্পাদন করতে পারি।


মন্তব্যগুলি বর্ধিত আলোচনার জন্য নয়; এই কথোপকথন চ্যাটে সরানো হয়েছে ।
জ্যাক বলছেন topanswers.xyz

উত্তর:


7

এই বাগের জন্য কলামগুলি নামার বা নামকরণের প্রয়োজন নেই।

আপনি একই আচরণটি দেখতে পাবেন statusId = 100যার জন্য কলামের কোনও সংস্করণে উপস্থিত ছিল না।

আবশ্যকতা

  • একটি ক্লাস্টার্ড কলাম স্টোর
  • অবিচ্ছিন্ন বি-গাছ সূচক
  • এমন একটি পরিকল্পনা যা কলামস্টোরের সাথে নজর রাখে
    • - দ্বীপের দোকানে লক্ষ্য সারি (গুলি)
    • একটি ঠেলাঠেলিবিহীন- SARG পূর্বাভাস
    • সমতা পরীক্ষা ব্যবহার করে NULL এর সাথে একটি তুলনা

উদাহরণ

DROP TABLE IF EXISTS dbo.Example;
GO
CREATE TABLE dbo.Example
(
    c1 integer NOT NULL,
    c2 integer NULL,

    INDEX CCS CLUSTERED COLUMNSTORE,
    INDEX IX NONCLUSTERED (c1)
);
GO
INSERT dbo.Example
    (c1, c2)
VALUES
    (1, NULL);
GO
DECLARE @c2 integer = NULL;

-- Returns one row but should not
SELECT
    E.* 
FROM dbo.Example AS E 
    WITH (INDEX(IX))
WHERE
    E.c2 = @c2;

নিম্নলিখিত যে কোনও বাগটি এড়াতে পারবেন:

  • নির্দিষ্ট করা কমপ্রেস রাউগ্রুপ বিকল্পগুলির সাথে পুনর্গঠন সহ যে কোনও পদ্ধতি ব্যবহার করে ব-দ্বীপ স্টোরের বাইরে সারি সরিয়ে নেওয়া
  • সুস্পষ্টভাবে প্রত্যাখ্যান করার জন্য প্রিডিকেট লেখা = NULL
  • প্রিকিকেটটিকে অনুসন্ধানের দিকে ঠেলাতে এড়াতে অনাবন্ধিত ট্রেস পতাকা 9130 সক্ষম করা

ডিবি <> ফিডাল ডেমো।


এই বাগটি এসকিউএল সার্ভার 2017 (এবং এসকিউএল সার্ভার 2016 এসপি 2 এর জন্য সিইউ 7) জন্য সিইউ 15 এ স্থির করা হয়েছিল :

ফিক্স: ক্লাস্টারযুক্ত কলামস্টোর সূচী এবং নন-ক্লাস্টারড রোউস্টোর সূচী উভয়ই সারণীর বিপরীতে প্রশ্ন এসকিউএল সার্ভার 2016 এবং 2017-এ ভুল ফলাফল দিতে পারে may


8

এটি এসকিউএল সার্ভার সহ একটি বাগ। যদি একটি ক্লাস্টারযুক্ত কলামস্টোর সূচী সহ কোনও কলামটি কোনও টেবিল থেকে মুছে ফেলা হয় এবং তারপরে একই নামে একটি নতুন কলাম যুক্ত করা হয়, তবে এটি প্রিডিকেটের জন্য পুরানো, মুছে ফেলা কলামটি ব্যবহার করছে বলে মনে হয়। এখানে এমভিসিই:

এই স্ক্রিপ্টটি সঙ্গে শুরু হয় বন্ধ 10000সঙ্গে সারি statusIdএর 1এবং statusId2এর 5- তারপর ড্রপ statusIDকলাম এবং renames statusId2করতে statusId। সুতরাং শেষে সমস্ত সারিতে statusId5 এর একটি হওয়া উচিত ।

তবে নীচের প্রশ্নটি ক্লাস্টারবিহীন সূচককে হিট করেছে ...

select *
from example
where statusId = 1
    and total <= @filter
    and barcode = @barcode
    and id2 = @id2

... এবং 2সারিগুলি প্রদান করে ( ক্লজ statusIdদ্বারা বর্ণিত থেকে পৃথক নির্বাচিত সহ WHERE) ...

+-------+---------+------+-------+----------+
|  id   | barcode | id2  | total | statusId |
+-------+---------+------+-------+----------+
|     5 |    5    | NULL |  5.00 |        5 |
| 10005 |    5    | NULL |  5.00 |        5 |
+-------+---------+------+-------+----------+

... যদিও এটি একটি কলামের দোকানে অ্যাক্সেস করে এবং সঠিকভাবে ফিরে আসে 0

select count(*) 
from example 
where statusId = 1

MVCE

/*Create table with clustered columnstore and non clustered rowstore*/
CREATE TABLE example
(
id        INT IDENTITY(1, 1),
barcode   CHAR(22),
id2       INT,
total     DECIMAL(10,2),
statusId  TINYINT,
statusId2 TINYINT,
INDEX cci_example CLUSTERED COLUMNSTORE,
INDEX ix_example (barcode, total)
);

/* Insert 10000 rows all with (statusId,statusId2) = (1,5) */
INSERT example
       (barcode,
        id2,
        total,
        statusId,
        statusId2)
SELECT TOP (10000) barcode = row_number() OVER (ORDER BY @@spid),
                   id2 = NULL,
                   total = row_number() OVER (ORDER BY @@spid),
                   statusId = 1,
                   statusId2 = 5
FROM   sys.all_columns c1, sys.all_columns c2;

ALTER TABLE example
  DROP COLUMN statusid
/* Now have 10000 rows with statusId2 = 5 */


EXEC sys.sp_rename
  @objname = N'dbo.example.statusId2',
  @newname = 'statusId',
  @objtype = 'COLUMN';
/* Now have 10000 rows with StatusID = 5 */

INSERT example
       (barcode,
        id2,
        total,
        statusId)
SELECT TOP (10000) barcode = row_number() OVER (ORDER BY @@spid),
                   id2 = NULL,
                   total = row_number() OVER (ORDER BY @@spid),
                   statusId = 5
FROM   sys.all_columns c1, sys.all_columns c2;
/* Now have 20000 rows with StatusID = 5 */


DECLARE @filter  DECIMAL = 5,
        @barcode CHAR(22) = '5',
        @id2     INT = NULL; 

/*This returns 2 rows from the NCI*/
SELECT *
FROM   example WITH (INDEX = ix_example)
WHERE  statusId = 1
       AND total <= @filter
       AND barcode = @barcode
       AND id2 = @id2;

/*This counts 0 rows from the Columnstore*/
SELECT COUNT(*)
FROM   example
WHERE  statusId = 1;

আমি আজুর প্রতিক্রিয়া পোর্টালেও একটি সমস্যা উত্থাপন করেছি :

এবং যার সাথে এটির মুখোমুখি হয়, ক্লাস্টারড কলামস্টোর সূচকটি পুনর্নির্মাণ সমস্যার সমাধান করে:

alter index cci_example on example rebuild

সিসিআই পুনর্নির্মাণ কেবল বিদ্যমান যে কোনও ডেটা ঠিক করে। নতুন রেকর্ড যুক্ত করা হলে, এই রেকর্ডগুলি নিয়ে আবার সমস্যা দেখা দেয়; সুতরাং বর্তমানে টেবিলের একমাত্র পরিচিত ফিক্সটি এটি সম্পূর্ণরূপে পুনরায় তৈরি করা।


1
এটি প্রডিকেটের জন্য পুরানোটিকে ব্যবহার করছে এমন সমস্যা নয়। অন্যান্য অদ্ভুত জিনিস এটি সম্পূর্ণ ভিন্ন কলাম উপর অবশিষ্ট সম্পৃক্ত ভাঙ্গে and id2 = @id2যাহাই হউক না কেন শূন্য সারি গ্যারান্টি উচিত @id2নয় nullকিন্তু আপনি এখনও 2 পেতে
মার্টিন স্মিথ

পুন: আপনার সম্পাদনা 2 REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON);কাজ করে? এটি ডেল্টাস্টোরকে সাফ করবে - সমস্যাটি কি নতুন সারিগুলির জন্য এরপরে যুক্ত হবে?
মার্টিন স্মিথ

নাহ, দুঃখের সাথে ঠিক একই পরিণতি বলে মনে হচ্ছে?
উবারজেন 1

-4

পরিকল্পনার ভিত্তিতে, দেখা যাচ্ছে যে কলামস্টোর সূচকটি সেট এএনএসআই_নুলস অফ দিয়ে তৈরি করা হয়েছিল। সারণি এবং সূচীগুলি সূচিটি তৈরি হওয়ার সময় যেমন ছিল ঠিক তেমনটি ধরে রাখে। ANSI_NULLS চালু রয়েছে তা নিশ্চিত করার পরে আপনি ডুপ্লিকেট কলামস্টোর সূচক তৈরি করে চেক করতে পারেন, তারপরে হয় আসলটি বাদ দিন বা এটি অক্ষম করুন।

তবে, যদি না আপনি কোনও এসকিউএল সার্ভার বাগ আবিষ্কার করেন, তবে ফলাফলগুলি ঘটতে পারে এমন একমাত্র উপায়।


2
আপনি কি নিশ্চিত যে 1) ফিল্টারবিহীন সূচকগুলি ANSI_NULLS সেটিংস বেস টেবিলের থেকে পৃথক রাখতে পারে এবং 2) সারণী এএনএসআই_এনএলএলএস সেটিংটি যখন এএনএসআই_এনএলএলএস অফের সাথে টেবিলটি তৈরি করা হয় তখন প্রকৃতপক্ষে তাত্পর্য সৃষ্টি করতে পারে?
ফরেস্ট

আমি এটি ভেবেছিলাম, তবে আমি যখন সিসিআইয়ের সংজ্ঞাটি স্ক্রিপ্ট করে দেখি তবে এর কোনও সেট বিকল্প নেই, এবং যদি আমি সূচক সংজ্ঞার আগে সেট এএনএসআই_এনএলএলএস দিয়ে এটি তৈরি করি তবে ফলাফলটি একই?
উবারজেন 1
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.