একে অপরের বিরুদ্ধে দুটি টেবিল বৈধতা দেওয়ার দ্রুত উপায়


13

আমরা একটি ইটিএল প্রক্রিয়া করছি। যখন সমস্ত বলা হয় এবং হয়ে যায় সেখানে একগুচ্ছ টেবিল রয়েছে যা অভিন্ন হওয়া উচিত। সেই টেবিলগুলি (দুটি পৃথক পৃথক সার্ভারে) আসলে একইরকম যাচাই করার দ্রুততম উপায় কী। আমি স্কিমা এবং ডেটা উভয়ই কথা বলছি।

আমি নিজের টেবিলে একটি হ্যাশ করতে পারি যেমন এটি আমি নিজের মতো করে আলাদা আলাদা ফাইল বা ফাইলগ্রুপে সক্ষম হতে পারি - একে অপরের সাথে তুলনা করতে। আমাদের কাছে রেড-গেটের ডেটা তুলনা রয়েছে তবে যেহেতু প্রশ্নের মধ্যে থাকা টেবিলগুলিতে কয়েক মিলিয়ন সারি রয়েছে আমি কিছুটা আরও পারফরম্যান্ট চাই।

একটি পদ্ধতির যা আমাকে উদ্দীপ্ত করে তা হ'ল ইউনিয়নের বিবৃতিটির এই সৃজনশীল ব্যবহার । তবে, সম্ভব হলে আমি হ্যাশ ধারণাটি আরও কিছুটা অন্বেষণ করতে চাই।

উত্তর আপডেট করুন

ভবিষ্যতের যেকোন ভিস্টারের জন্য ... আমি গ্রহণের অবসান ঘটিয়েছিলাম সেই সঠিক পদ্ধতির। এটি এত ভাল কাজ করেছে আমরা প্রতিটি ডাটাবেজে প্রতিটি টেবিলে এটি করছি। আমাকে সঠিক দিকে নির্দেশ করার জন্য নীচের উত্তরগুলির জন্য ধন্যবাদ।

CREATE PROCEDURE [dbo].[usp_DatabaseValidation]
    @TableName varchar(50)

AS
BEGIN

    SET NOCOUNT ON;

    -- parameter = if no table name was passed do them all, otherwise just check the one

    -- create a temp table that lists all tables in target database

    CREATE TABLE #ChkSumTargetTables ([fullname] varchar(250), [name] varchar(50), chksum int);
    INSERT INTO #ChkSumTargetTables ([fullname], [name], [chksum])
        SELECT DISTINCT
            '[MyDatabase].[' + S.name + '].['
            + T.name + ']' AS [fullname],
            T.name AS [name],
            0 AS [chksum]
        FROM MyDatabase.sys.tables T
            INNER JOIN MyDatabase.sys.schemas S ON T.schema_id = S.schema_id
        WHERE 
            T.name like IsNull(@TableName,'%');

    -- create a temp table that lists all tables in source database

    CREATE TABLE #ChkSumSourceTables ([fullname] varchar(250), [name] varchar(50), chksum int)
    INSERT INTO #ChkSumSourceTables ([fullname], [name], [chksum])
        SELECT DISTINCT
            '[MyLinkedServer].[MyDatabase].[' + S.name + '].['
            + T.name + ']' AS [fullname],
            T.name AS [name],
            0 AS [chksum]
        FROM [MyLinkedServer].[MyDatabase].sys.tables T
            INNER JOIN [MyLinkedServer].[MyDatabase].sys.schemas S ON 
            T.schema_id = S.schema_id
        WHERE
            T.name like IsNull(@TableName,'%');;

    -- build a dynamic sql statement to populate temp tables with the checksums of each table

    DECLARE @TargetStmt VARCHAR(MAX)
    SELECT  @TargetStmt = COALESCE(@TargetStmt + ';', '')
            + 'UPDATE #ChkSumTargetTables SET [chksum] = (SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*)) FROM '
            + T.FullName + ') WHERE [name] = ''' + T.Name + ''''
    FROM    #ChkSumTargetTables T

    SELECT  @TargetStmt

    DECLARE @SourceStmt VARCHAR(MAX)
    SELECT  @SourceStmt = COALESCE(@SourceStmt + ';', '')
            + 'UPDATE #ChkSumSourceTables SET [chksum] = (SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*)) FROM '
            + S.FullName + ') WHERE [name] = ''' + S.Name + ''''
    FROM    #ChkSumSourceTables S

    -- execute dynamic statements - populate temp tables with checksums

    EXEC (@TargetStmt);
    EXEC (@SourceStmt);

    --compare the two databases to find any checksums that are different

    SELECT  TT.FullName AS [TABLES WHOSE CHECKSUM DOES NOT MATCH]
    FROM #ChkSumTargetTables TT
    LEFT JOIN #ChkSumSourceTables ST ON TT.Name = ST.Name
    WHERE IsNull(ST.chksum,0) <> IsNull(TT.chksum,0)

    --drop the temp tables from the tempdb

    DROP TABLE #ChkSumTargetTables;
    DROP TABLE #ChkSumSourceTables;

END

এসএসআইএস কি বিকল্প? এক টেবিলে পড়া এবং অন্যটির বিরুদ্ধে নজর রাখা মোটামুটি সহজ।
কেভিন

1
এটি একটি বিকল্প, এটিটি ইটিএল প্রক্রিয়াটির জন্য ব্যবহৃত হচ্ছে, তবে উপরের গোঁফগুলি এসএসআইএস ব্যবহার করে এটি কার্যকর হয়েছে কিনা তা নিয়ে একটি দ্বিতীয় মতামত চায়, এসএসআইএস এটি সঠিকভাবে পেয়েছে তা চেকসাম বা মত অভিনব শব্দ বাদ দেওয়ার মতো বিশ্বাসযোগ্য নয় এমডি 5 হ্যাশ
টমাস

উত্তর:


18

আমি এর আগে যা করেছি তা এখানে:

(SELECT 'TableA', * FROM TableA
EXCEPT
SELECT 'TableA', * FROM TableB)
UNION ALL
(SELECT 'TableB', * FROM TableB
EXCEPT
SELECT 'TableB', * FROM TableA)

এটি প্রায় ১,০০,০০০ সারি টেবিলগুলিতে যথেষ্ট পরিমাণে কাজ করেছে তবে আমি নিশ্চিত নই যে এটি অত্যন্ত বড় টেবিলগুলিতে কতটা ভাল কাজ করবে।

যোগ করা হয়েছে:

আমি আমার সিস্টেমের বিরুদ্ধে ক্যোয়ারী চালিয়েছি যা এসকিউএল সার্ভার ২০০ 2005 চলমান একই সার্ভারের সাথে সংযুক্ত দুটি পৃথক ডাটাবেসে 21 টি ক্ষেত্রের নিয়মিত ক্ষেত্রের সাথে দুটি টেবিলের সাথে তুলনা করে The টেবিলটিতে প্রায় 3 মিলিয়ন সারি রয়েছে এবং প্রায় 25000 সারি আলাদা। টেবিলের প্রাথমিক কীটি অদ্ভুত, যদিও এটি 10 ​​টি ক্ষেত্রের সম্মিলিত কী (এটি একটি নিরীক্ষার টেবিল)।

প্রশ্নগুলির জন্য কার্যকর করার পরিকল্পনাগুলির জন্য 184.25879 UNIONএবং 184.22983 এর জন্য মোট ব্যয় রয়েছে UNION ALL। গাছের দাম কেবল সারিগুলি ফেরানোর আগে শেষ ধাপে পৃথক হয়, সমবেত হয়।

প্রকৃতপক্ষে কোয়েরি কার্যকর করতে সারিগুলি সঞ্চারিত করতে প্রায় 42s প্লাস প্রায় 3s লাগে takes দুটি প্রশ্নের মধ্যে সময় অভিন্ন।

দ্বিতীয় সংযোজন:

এটি প্রকৃতপক্ষে অত্যন্ত দ্রুত, প্রত্যেকে প্রায় ২.৫ সেকেন্ডে 3 মিলিয়ন সারির বিপরীতে চলে:

SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*)) FROM TableA

SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*)) FROM TableB

যদি এর ফলাফলগুলি মেলে না, আপনি জানেন যে টেবিলগুলি আলাদা। যাইহোক, যদি ফলাফল না ম্যাচ, আপনি করছেন না নিশ্চিত যে টেবিল [অত্যন্ত অসম্ভাব্য] চেকসাম দুর্ঘটনায় সম্ভাবনা কারণ অভিন্ন।

আমি নিশ্চিত না কীভাবে টেবিলগুলির মধ্যে ডেটাটাইপ পরিবর্তনের ফলে এই গণনাটি প্রভাবিত হবে। আমি systemভিউ বা information_schemaমতামতের বিপরীতে ক্যোরি চালাব ।

আমি 5 মিলিয়ন সারি দিয়ে অন্য টেবিলের বিপরীতে ক্যোরিটি চেষ্টা করেছি এবং এটি প্রায় 5s-তে চলেছিল, সুতরাং এটি বেশিরভাগ ক্ষেত্রে O (n) বলে মনে হয়।


8

এখানে বেশ কয়েকটি ধারণা যা সহায়তা করতে পারে:

  1. বিভিন্ন ডেটা ডিফ ডিভাইস ব্যবহার করে দেখুন - আপনি কি ইডেরার এসকিউএল তুলনা সরঞ্জামসেট বা অ্যাপেক্সএসকিউএল ডেটা ডিফ চেষ্টা করেছেন ? আমি বুঝতে পারি যে আপনি ইতিমধ্যে আরজির জন্য অর্থ প্রদান করেছেন কিন্তু আপনি এগুলি এখনও কাজটি সম্পন্ন করার জন্য ট্রায়াল মোডে ব্যবহার করতে পারেন;)।

  2. ভাগ করুন এবং বিজয় করুন - 10 টি ছোট টেবিলগুলিতে বিভক্ত টেবিলগুলি কীভাবে কিছু বাণিজ্যিক ডেটা তুলনা সরঞ্জাম দ্বারা পরিচালিত হতে পারে?

  3. নিজেকে কেবল কয়েকটি কলামে সীমাবদ্ধ করুন - আপনার কি সমস্ত কলামে ডেটা তুলনা করার দরকার আছে?


7

আমি বিশ্বাস করি আপনার BINARY_CHECKSUM টি তদন্ত করা উচিত, যদিও আমি রেড গেট সরঞ্জামটি বেছে নেব:

http://msdn.microsoft.com/en-us/library/ms173784.aspx

এটার মতো কিছু:

SELECT BINARY_CHECKSUM(*) from myTable;

এটি কি টেবিলগুলির স্কিমা (বিভিন্ন কলামের নাম বা ডেটাটাইপ) এর পার্থক্য সনাক্ত করবে?
ypercubeᵀᴹ

@ ইয়পারক्यूब ᵀᴹ হ্যাঁ, আমি এটি নিশ্চিত করতে পারি। আমি CHECKSUM_AGG(BINARY_CHECKSUM(*))দুটি অভিন্ন টেবিলের মধ্যে পরীক্ষা করছিলাম যেখানে চেকসাম মিলছে। আমি একটি সারণীতে একটি কলাম যুক্ত করার পরে, চেকসাম মানগুলি আর অভিন্ন ছিল না।
জেফ মার্জারার

3

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

SELECT
   ID = IsNull(A.ID, B.ID),
   AValue = A.Value,
   BValue = B.Value
FROM
   dbo.TableA A
   FULL JOIN dbo.TableB B
      ON A.ID = B.ID
WHERE
   EXISTS (
      SELECT A.*
      EXCEPT SELECT B.*
   );

এটি একটি স্ক্লাফিল্ডে দেখুন

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.