วิธีที่ดีที่สุดในการรีเฟรชเพียงไม่กี่ตารางในฐานข้อมูลทดสอบจากการผลิตคืออะไร


12

ฉันมีฐานข้อมูลการผลิตขนาดใหญ่มากและฐานข้อมูลสภาพแวดล้อมการทดสอบขนาดใหญ่มากใน SQL Server 2008R2 ฐานข้อมูลทั้งสองมีโครงสร้างตารางที่คล้ายกัน แต่ผู้ใช้ / การเข้าสู่ระบบ / สิทธิ์ / บทบาทที่แตกต่างกัน

ฉันต้องการรีเฟรชเพียงไม่กี่ตารางในฐานข้อมูลการทดสอบเป็นระยะ ๆ จากการผลิตประมาณเดือนละครั้ง

วิธีปัจจุบันที่ฉันวางแผนจะทำคือ

  1. ใช้ยูทิลิตี้ BCP เพื่อทำการส่งออกตารางที่ฉันต้องการจากการผลิต
  2. คัดลอกไฟล์ส่งออก bcp ไปยังเซิร์ฟเวอร์ทดสอบ
  3. ปิดการใช้งานดัชนีและข้อ จำกัด ในตารางทั้งหมดที่ฉันรีเฟรชในการทดสอบ
  4. ตัดทอนตารางฐานข้อมูลทดสอบ
  5. โหลดข้อมูลกลับเข้าไปในตารางฐานข้อมูลทดสอบโดยใช้ BCP
  6. สร้างดัชนีใหม่และเปิดใช้งานข้อ จำกัด ในการทดสอบอีกครั้ง

ทั้งหมดนี้ดูเหมือนจะซับซ้อนเกินไปสำหรับงานเล็ก ๆ น้อย ๆ ดูเหมือนว่าจะสร้างการทำซ้ำจำนวนมาก (ใน t-log) มีวิธีที่ดีกว่าในการทำเช่นนี้หรือไม่?

อีกวิธีที่ฉันคิดว่าทำเช่นนี้คือการคืนค่าการสำรองข้อมูลจากการผลิตสู่สภาพแวดล้อมการทดสอบ - แต่ปัญหาที่ฉันมีคือการสำรองข้อมูลเต็มรูปแบบจะมีขนาดค่อนข้างใหญ่และฉันไม่ต้องการให้ทุกตารางทำการรีเฟรช - และผู้ใช้และความปลอดภัยในฐานข้อมูลการผลิตแตกต่างจากการทดสอบ ที่จะถูกเขียนทับโดยการตั้งค่าความปลอดภัยในฐานข้อมูลการผลิตถ้าฉันคืนค่าฐานข้อมูลทั้งหมด


วิธีนี้อาจคุ้มค่าที่จะตรวจสอบ: sqlperformance.com/2012/08/t-sql-queries/ ......และsqlperformance.com/2013/04/t-sql-queries/…
Aaron Bertrand

คำตอบ:


4

มี 2 ​​วิธีที่เหมาะกับความต้องการของคุณ:

(หมายเหตุ: หากตารางถูกอ้างอิงโดย foreign key คุณจะไม่สามารถใช้งานTRUNCATEได้คุณต้องลบเป็น chunksหรือคุณสามารถลบดัชนีทั้งหมด + foreign keys และโหลดข้อมูลแล้วสร้างใหม่)

  • BCP OUT และเป็นกลุ่มฐานข้อมูลปลายทาง

    • ตรวจสอบให้แน่ใจว่าคุณใส่ฐานข้อมูลทดสอบในโหมดการกู้คืนแบบง่าย / บันทึกจำนวนมาก
    • เปิดใช้งานการติดตามค่าสถานะ 610 - แทรกข้อมูลน้อยที่สุดลงในตารางที่จัดทำดัชนี

      /************************************************************************************************************************************************
      Author      :   KIN SHAH    *********************************************************************************************************************
      Purpose     :   Move data from one server to another*********************************************************************************************
      DATE        :   05-28-2013  *********************************************************************************************************************
      Version     :   1.0.0   *************************************************************************************************************************
      RDBMS       :   MS SQL Server 2008R2 and 2012   *************************************************************************************************
      *************************************************************************************************************************************************/
      
      -- save below output in a bat file by executing below in SSMS in TEXT mode
      -- clean up: create a bat file with this command --> del D:\BCP_OUT\*.dat 
      
      select '"C:\Program Files\Microsoft SQL Server\100\Tools\Binn\bcp.exe" '-- path to BCP.exe
              +  QUOTENAME(DB_NAME())+ '.'                                    -- Current Database
              +  QUOTENAME(SCHEMA_NAME(SCHEMA_ID))+'.'            
              +  QUOTENAME(name)  
              +  ' out D:\BCP_OUT\'                                           -- Path where BCP out files will be stored
              +  REPLACE(SCHEMA_NAME(schema_id),' ','') + '_' 
              +  REPLACE(name,' ','') 
              + '.dat -T -E -SSERVERNAME\INSTANCE -n'                         -- ServerName, -E will take care of Identity, -n is for Native Format
      from sys.tables
      where is_ms_shipped = 0 and name <> 'sysdiagrams'                       -- sysdiagrams is classified my MS as UserTable and we dont want it
      and schema_name(schema_id) <> 'some_schema_exclude'                     -- Optional to exclude any schema 
      order by schema_name(schema_id)                         
      
      
      
      --- Execute this on the destination server.database from SSMS.
      --- Make sure the change the @Destdbname and the bcp out path as per your environment.
      
      declare @Destdbname sysname
      set @Destdbname = 'destination_database_Name'               -- Destination Database Name where you want to Bulk Insert in
      select 'BULK INSERT '                                       -- Remember Tables **must** be present on destination Database
              +  QUOTENAME(@Destdbname)+ '.'
              +  QUOTENAME(SCHEMA_NAME(SCHEMA_ID))+'.' 
              +  QUOTENAME(name) 
              + ' from ''D:\BCP_OUT\'                             -- Change here for bcp out path
              +  REPLACE(SCHEMA_NAME(schema_id),' ','') + '_'
              +  REPLACE(name,' ','') 
              +'.dat'' 
              with (
              KEEPIDENTITY,
              DATAFILETYPE = ''native'',  
              TABLOCK
              )'  + char(10) 
              + 'print ''Bulk insert for '+REPLACE(SCHEMA_NAME(schema_id),' ','') + '_'+  REPLACE(name,' ','')+' is done... '''+ char(10)+'go' 
      from sys.tables
      where is_ms_shipped = 0 and name <> 'sysdiagrams'           -- sysdiagrams is classified my MS as UserTable and we dont want it
      and schema_name(schema_id) <> 'some_schema_exclude'         -- Optional to exclude any schema 
      order by schema_name(schema_id)

-

  • วิธีที่ 2: SSIS - วิธีที่ฉันชอบในกรณีนี้

    • ไม่ต้องใช้การจัดเตรียมดิสก์ การประมวลผลทั้งหมดจะทำในหน่วยความจำ
    • คุณสามารถกำหนดตารางเวลาแพคเกจ SSIS โดยใช้งานตัวแทนของ sql ทุกเดือนเพื่อทำการรีเฟรชตารางโดยอัตโนมัติจากเซิร์ฟเวอร์ PROD ถึง TEST
    • เลือกตัวเลือก " โหลดเร็ว "
    • ตรวจสอบให้แน่ใจว่าคุณเลือกแถวที่ดีต่อหมายเลขชุดงาน (ถ้าคุณเลือกสูงเกินไปจะมีการเพิ่มระดับล็อค - เก็บไว้ต่ำกว่า 5K)

การอ้างอิง: คู่มือประสิทธิภาพการโหลดข้อมูลและคำตอบของฉันสำหรับ - แทรกลงในตารางเลือก * จากตารางเทียบกับการเพิ่มจำนวนมาก


1
SSIS เป็นวิธีที่จะไปที่นี่อย่างแน่นอน การปั๊มข้อมูลเป็นสิ่งที่ออกแบบมาให้ทำ
Steve Mangiameli

3

ไม่จำเป็นต้องทำการสำรองข้อมูลและเรียกคืนหรือโทร / ประสานงานกระบวนการภายนอก (เช่น BCP) หรือแม้แต่ยุ่งกับ SSIS (ทรงพลังมากเจ๋งมาก แต่ถ้าฉันสามารถหลีกเลี่ยงได้ฉันจะ :) แน่นอน คุณสามารถจัดการทั้งหมดนี้ได้อย่างสะดวกสบายจาก T-SQL ในขั้นตอนการจัดเก็บที่คุณสามารถกำหนดเวลาผ่านตัวแทนของ SQL หรือสคริปต์ที่คุณเรียกใช้เดือนละครั้ง วิ่ง). อย่างไร? โดยการใช้ SQLCLR เพื่อเข้าถึงSqlBulkCopyClass ใน. NET เนื่องจากเป็น BCP เป็นหลักโดยไม่ต้องวุ่นวายกับการเรียก BCP คุณสามารถเขียนโค้ดนี้ด้วยตัวเอง: ไม่มีการตั้งค่าที่ซับซ้อนสุด ๆ หรืออะไรอย่างนั้นSqlBulkCopyคลาสจะดูแลเกือบทุกอย่างสำหรับคุณ (คุณสามารถกำหนดขนาดแบทช์ไม่ว่าจะเรียกใช้ทริกเกอร์หรือไม่ก็ตาม) หรือถ้าคุณไม่ต้องการยุ่งกับการคอมไพล์และปรับใช้แอสเซมบลีคุณสามารถใช้ SQLCLR กระบวนงานที่เก็บไว้ล่วงหน้าเช่นDB_BulkCopyซึ่งเป็นส่วนหนึ่งของไลบรารีSQL # SQLCLR (ซึ่งฉันเป็นผู้เขียน แต่สิ่งนี้ถูกเก็บไว้ ขั้นตอนอยู่ในรุ่นฟรี) ฉันอธิบายรายละเอียดเพิ่มเติมรวมถึงตัวอย่างของการใช้DB_BulkCopyในคำตอบต่อไปนี้:

นำเข้าข้อมูลจากฐานข้อมูลหนึ่งไปยังสคริปต์อื่น

หากยังไม่ชัดเจนว่าจะวางที่ใดในแผนปัจจุบันของคุณคุณจะทำสิ่งต่อไปนี้:

  • ลบขั้นตอนที่ 1 และ 2 (woo hoo!)
  • แทนที่ขั้นตอนที่ 5 ที่มีEXECของDB_BulkCopyหรือสิ่งที่คุณเรียกมันว่าถ้าคุณรหัสมันด้วยตัวคุณเองที่เพิ่งย้ายข้อมูลจากจุด A ไปยังจุด B

นอกจากนี้ควรชี้ให้เห็นว่าSqlBulkCopyและDB_BulkCopy :

  • สามารถยอมรับชุดผลลัพธ์ใด ๆ : ไม่สำคัญว่าจะเป็น SELECT หรือ EXEC ของกระบวนงานที่เก็บไว้
  • ง่ายต่อการอัพเดตเมื่อทำการเปลี่ยนแปลง schema ของตารางเหล่านี้ เพียงแค่เปลี่ยนแบบสอบถามในกระบวนงานที่เก็บไว้ซึ่งเรียก SQLCLR กระบวนงานที่เก็บไว้นี้
  • อนุญาตให้ทำการแมปฟิลด์อีกครั้งหากจำเป็น

ปรับปรุงเกี่ยวกับการดำเนินการบันทึกเล็กน้อยผ่าน SqlBulkCopy

เป็นไปได้ที่จะได้รับการบันทึกที่น้อยที่สุด แต่คุณควรรู้

  • คุณต้องใช้ตัวเลือกการคัดลอกจำนวนมากของTableLock
  • การทำเช่นนี้สำหรับตารางที่มีดัชนีแบบกลุ่มให้ทำการโหลดข้อมูล[tempdb]ก่อนแล้วจึงทำการแทรกคำสั่งลงในปลายทาง ดังนั้นจึงมีภาระที่เพิ่มขึ้นบางอย่างทั้งในแง่ของฟิสิคัล I / O ไปยัง tempdb (ข้อมูลและไฟล์บันทึก) รวมถึงการดำเนินการเรียงลำดับ (เนื่องจากORDER BYต้องใช้เพื่อให้ได้การดำเนินการที่น้อยที่สุด)
  • ผลการทดสอบบางส่วนได้ที่นี่: Whitepaper: ประสิทธิภาพของ SqlBulkCopy
  • ผลการทดสอบบางส่วนที่นี่: การแก้ไขปัญหา SqlBulkCopy ไม่ทำการบันทึกขั้นต่ำ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.