หน่วยความจำที่ใช้ไม่ได้เพิ่มขึ้นหลังจาก SQL BULK Insert / BCP Export


10

ฉันได้สร้างตาราง SQL พื้นฐานมากดังต่อไปนี้

CREATE TABLE [dbo].[TickData](
[Date] [varchar](12) NULL,
[Time] [varchar](12) NOT NULL,
[Symbol] [varchar](12) NOT NULL,
[Side] [varchar](2) NOT NULL,
[Depth] [varchar](2) NOT NULL,
[Quote] [varchar](12) NOT NULL,
[Size] [varchar](18) NOT NULL
    ) ON [PRIMARY]

จากนั้นฉันก็ทำการแทรก 3 Gig Bulk

    BULK
    INSERT TickData
    FROM 
    'C:\SUMO.csv'
    GO

จากนั้นการใช้ RAM สำหรับเซิร์ฟเวอร์ SQL ทำให้ Skyrocking กิน RAM ขึ้น ~ 30Go:

ป้อนคำอธิบายรูปภาพที่นี่

ป้อนคำอธิบายรูปภาพที่นี่

ฉันชอบที่จะคิดว่านี่เป็นพฤติกรรมที่ผิดปกติและสามารถดำเนินการเพื่อหลีกเลี่ยงปัญหานี้ได้

แก้ไข:
ตกลงนี่น่าจะเป็นพฤติกรรมเริ่มต้น ยุติธรรมพอสมควร
อย่างไรก็ตามเหตุใดหน่วยความจำจึงไม่เพิ่มขึ้นหลังจากการแทรกจำนวนมากเสร็จสิ้นแล้ว

ข้อควรพิจารณาเพิ่มเติมสองประการ:
จากความคิดเห็นเกี่ยวกับเซิร์ฟเวอร์ SQL ที่เพิ่มหน่วยความจำเมื่อมีการ "บอก" โดยระบบปฏิบัติการประสบการณ์บนมือของฉันบนเซิร์ฟเวอร์ 24-Core 32 Gb Xeon พิสูจน์ได้ว่าสิ่งนี้ไม่แน่นอน: เมื่อสารสกัด BCP หน่วยความจำไม่รู้จักจบ ฉันมีกลุ่มของ. Net อินสแตนซ์ของแอปพลิเคชันการประมวลผลข้อมูลของฉันที่ต้องการประมวลผลข้อมูลที่แยกออกมาและพวกเขาถูกทิ้งให้สำลัก / ต่อสู้เพื่อแบ่งปันหน่วยความจำที่เหลือเพื่อพยายามทำงานของพวกเขาซึ่งใช้เวลานานกว่านั้น ปิดและหน่วยความจำพร้อมใช้งานสำหรับแอปพลิเคชันทั้งหมดเพื่อแบ่งปัน ฉันต้องหยุด SQL Server Agent เพื่อให้ทุกอย่างดำเนินไปอย่างราบรื่นและป้องกันไม่ให้แอปหยุดทำงานสำหรับ Articiallt ทำให้เกิดข้อยกเว้น OutOfMemmroy สำหรับการ จำกัด / จำกัด หน่วยความจำแบบ Brutal Memory หากมีหน่วยความจำว่าง ทำไมไม่ใช้ เป็นการดีที่มันค่อนข้างจะถูกตั้งค่าแบบ dinamically เพื่อปรับให้เข้ากับสิ่งที่มีอยู่มากกว่าเพียงแค่การ จำกัด การบังคับโดยการ "สุ่ม" แต่ฉันเดาว่านี่คือการออกแบบดังนั้นกรณีปิดในจุดสุดท้ายนี้


6
ทำไม SQL Server ควรเพิ่มหน่วยความจำ หากจำเป็นต้องใช้หน่วยความจำเพื่อดำเนินการนี้อีกครั้งจะต้องใช้อีกครั้ง ถ้า SQL Server ปล่อยหน่วยความจำคุณจะใช้เพื่ออะไร เหตุใดหน่วยความจำจึงต้องว่าง หากคุณใช้หน่วยความจำสำหรับอย่างอื่นการแทรกจำนวนมากนี้จะทำงานอีกครั้งจะเกิดอะไรขึ้น
แอรอนเบอร์ทรานด์ด์

การกระทำเดียวที่คุณสามารถทำได้เพื่อหลีกเลี่ยงปัญหานี้คือการตั้งค่าขนาดหน่วยความจำสูงสุด หากต้องการ "กู้คืน" หน่วยความจำคุณสามารถเริ่มบริการ SQL Server ใหม่ได้ เห็นได้ชัดว่าจะปล่อยหน่วยความจำและเมื่อบริการเริ่มต้นใหม่ก็จะจัดสรรหน่วยความจำตามปกติ
TMN

ฉันล้างการแก้ไขครั้งล่าสุด หากคุณต้องการมีข้อโต้แย้ง / การสนทนาเกี่ยวกับข้อดีหรือประเด็นของวิธีที่ SQL Server (หรือเอ็นจิน DB อื่น ๆ ) ได้รับการเข้ารหัสโปรดหาที่ที่ดีกว่าในการทำ คำถามเดิมได้รับคำตอบอย่างชัดเจนและเพียงพอ หากคำถามนี้ยังคงคืบคลานไปมันอาจถูกล็อค
JNK

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

3
นอกจากนี้ในฐานะผู้ดูแลที่ไม่ใช่ฉันสงสัยว่าทำไมคุณถึงเรียกใช้สิ่งที่ไม่ใช่ SQL บนเซิร์ฟเวอร์ของคุณ กล่องควรจะสงวนไว้เพียงแค่สำหรับ SQL Server ซึ่งเป็นเช่นเดียวกับ DBA 101 เอ็นจิ้นไม่ได้ถูกออกแบบมาสำหรับสภาพแวดล้อมของทรัพยากรที่ใช้ร่วมกัน
JNK

คำตอบ:


12

มันเป็นพฤติกรรมปกติสำหรับ SQL Server ที่จะจัดสรรหน่วยความจำให้มากที่สุดเท่าที่จะทำได้ในพูลของบัฟเฟอร์ ฐานข้อมูลทำงานได้ดีที่สุดกับบัฟเฟอร์จำนวนมาก หากคุณต้องการเปลี่ยนลักษณะการทำงานคุณสามารถตั้งค่า'หน่วยความจำเซิร์ฟเวอร์สูงสุด'ได้ มีพื้นฐานการอ่านที่ดีอยู่ที่นี่


1
ในแง่ของการแก้ไขของคุณความคิดเห็นของแอรอนเป็นสิ่งที่ดี เหตุผลก็คือมีจุดเล็ก ๆ ในเซิร์ฟเวอร์ฐานข้อมูลทำให้หน่วยความจำว่าง SQL Server จะตอบสนองต่อแรงกดดันหน่วยความจำและปล่อยหน่วยความจำหากจำเป็น แต่จริงๆแล้วไม่จำเป็น
Matt Whitfield

@MikaJacobi ขออภัย แต่การแก้ไขครั้งที่สองของคุณผิดพลาด จากความเข้าใจของนักพัฒนาฉันเข้าใจมุมมองของคุณ แต่มีความแตกต่างระหว่างการสร้างแอพพลิเคชั่นจำนวนมากที่มีอยู่ร่วมกับบริการเซิร์ฟเวอร์ที่ควรจะเป็นบริการที่ใช้หน่วยความจำเพียงอย่างเดียว หากคุณต้องการให้ SQL Server ทำงานเหมือนแอปพลิเคชั่น "ปกติ" ให้ตั้งค่าหน่วยความจำสูงสุดแล้วเดินออกไป คำถามของคุณคือเหตุใดจึงทำงานเช่นนี้และได้รับคำตอบ หากคำถามของคุณตอนนี้ "ดีฉันไม่ชอบที่มันทำงานอย่างนั้น" - ขอโทษ แต่นั่นไม่ใช่คำถามอีกต่อไป
Aaron Bertrand

ยุติธรรมพอสมควร มุมมองของฉันเป็นเพียงว่าควรมีตัวเลือกในการวางหรือปิดและสันนิษฐานว่าเซิร์ฟเวอร์ SQL เป็นแอปพลิเคชันบนเซิร์ฟเวอร์เท่านั้นที่ไม่เหมาะสมจริง ๆ (อาจเป็นจริงสำหรับ บริษัท ขนาดใหญ่ที่มีเครือข่ายขนาดใหญ่ แต่ไม่ใช่เท่านั้น เป็นไปได้หรือการตั้งค่าทั่วไป)
Mehdi LAMRANI

ฉันยังไม่เข้าใจว่าทำไมคุณต้องมี SQL Server เพื่อเพิ่มหน่วยความจำ หากต้องการแอปพลิเคชันอื่นพวกเขาจะนำมันกลับมาจาก SQL Server และ SQL Server จะปฏิบัติตาม จนกว่าแอพพลิเคชั่นอื่น ๆ จะต้องการแอพพลิเคชั่นนี้จะช่วยให้หน่วยความจำว่างได้อย่างไร?
Aaron Bertrand

1
@AaronBertrand Ok ฉันอาจจะผิด แต่ตามที่ระบุไว้ในการแก้ไขครั้งล่าสุดของฉันนี่ไม่ใช่สิ่งที่ฉันเห็น: หน่วยความจำไม่ได้เป็นอิสระเมื่อแอปพลิเคชันอื่น ๆ ต้องการมันแทบจะไม่ก่อให้เกิดปัญหาหน่วยความจำล่ม ปิดเรื่องนี้ฉันเดาว่าไม่จำเป็นต้องเถียงมากกว่านั้น
Mehdi LAMRANI

7

หากคุณต้องการให้ระบบปฏิบัติการนำหน่วยความจำกลับมาจาก SQL Server ให้นำไฟล์ขนาดใหญ่ 20 GB แล้วคัดลอกผ่านเครือข่าย SQL Server จะปล่อยหน่วยความจำตามที่ระบบปฏิบัติการต้องการ แต่ฉันจะดูตัวนับประสิทธิภาพที่หลากหลายในขณะที่เกิดขึ้นและดูว่าประสิทธิภาพของ BULK INSERT ของคุณเปลี่ยนไปอย่างไรถ้าคุณเรียกใช้อีกครั้งในขณะที่การคัดลอกเกิดขึ้นหรือทันทีหลังจากนั้น

ถ้าคุณต้องการทำด้วยตนเองคุณควรกำหนดขีด จำกัด ล่างในการตั้งค่าหน่วยความจำเซิร์ฟเวอร์สูงสุดของ SQL Server และเริ่มบริการใหม่ ตอนนี้ SQL Server จะไม่ใช้ 28GB แม้ว่าจะต้องการ แต่นี่ดูเหมือนว่าจะเป็นการ จำกัด เซิร์ฟเวอร์ SQL

สิ่งที่คุณคาดหวังคือพฤติกรรมที่ยืดหยุ่นมากขึ้นซึ่งคุณสามารถมีหน่วยความจำว่างได้ตลอดเวลา เพื่อจุดประสงค์อะไร? นี่เหมือนกับการย่อขนาดไฟล์ฐานข้อมูลเพื่อเพิ่มพื้นที่ว่างในดิสก์ที่คุณไม่สามารถใช้เพื่อวัตถุประสงค์อื่นได้หรือไม่เพราะไฟล์ฐานข้อมูลจะขยายอีกครั้งหรือไม่

เป็นเรื่องตลกถ้าคุณพิมพ์การค้นหาโดย Google สำหรับ "ทำไมจึงไม่ใช่ SQL Server" การเติมข้อความอัตโนมัติที่พบบ่อยที่สุดคือ "ปล่อยหน่วยความจำ"



"สิ่งที่คุณคาดหวังคือพฤติกรรมที่ยืดหยุ่นมากขึ้น" เผง ฉันต้องการให้เซิร์ฟเวอร์ SQL ใช้หน่วยความจำ avaialble ทั้งหมดเมื่อมันพร้อมใช้งาน แต่เมื่อช่วงเวลาที่หนักหน่วงเหล่านี้จบลงเพื่อกลับไปที่สถานะ "sleep" และปล่อยให้แอปพลิเคชันอื่น ๆ ที่จำเป็นต้องใช้หน่วยความจำ แก้ไขล่าสุดในจุดนี้)
Mehdi LAMRANI

สำหรับกรณีที่เป็นรูปธรรมที่แสดงว่าทำไมฉันต้องทำเช่นนี้คุณสามารถดู @ ความคิดเห็นล่าสุดของฉันไป JNK ที่ด้านล่างของคำถาม
เมห์ Lamrani

4

น่าเสียดายที่มีการออกแบบโปรดอ้างอิงโพสต์นี้ อย่างไรก็ตามในโพสต์นี้จะให้คำแนะนำเกี่ยวกับวิธีการควบคุม

/server/251832/sql-server-bulk-insert-physical-memory-issue

แก้ไขการจัดสรรหน่วยความจำ

หน่วยความจำไม่ได้freedขึ้นอยู่กับการจัดสรรหน่วยความจำเช่นแอปพลิเคชัน. NET เนื่องจากการจัดสรรหน่วยความจำมีราคาแพงมันจะระงับการจัดสรรนั้นเว้นแต่ OS จะร้องขอ แต่ไม่ต้องกลัวถ้าระบบปฏิบัติการต้องการหน่วยความจำก็จะได้รับเหมือนในแอปพลิเคชั่น. NET


@MikaJacobi แน่นอนว่าไม่มีปัญหา สิ่งอื่นที่ควรทราบอีกประการหนึ่งคือเพื่อให้คุณรู้ว่า SQL Server จะครอบครองแกนทั้งหมดเช่นกันเพื่อให้แน่ใจว่าคุณ จำกัด จำนวนคอร์ที่มีอยู่ ฉันเคยเห็น SQL Server จริง ๆ แล้วทำลายระบบปฏิบัติการที่ทำงานก่อนหน้านี้และฉันต้องรีบูทศูนย์ข้อมูล SQL Server อย่างหนัก

ดีแล้วที่รู้. ฉันมี 24 คอร์ดังนั้นตอนนี้ก็โอเค แต่ทำไมหน่วยความจำจึงไม่เพิ่มขึ้นหลังจากการแทรกจำนวนมากสิ้นสุดลง

ตราบใดที่การแทรกจำนวนมากเสร็จสมบูรณ์แล้วหากระบบปฏิบัติการต้องการหน่วยความจำก็จะได้รับมัน แต่จะจัดสรรหน่วยความจำจำนวนมากเช่นแอปพลิเคชั่น. NET เพื่อให้สามารถใช้งานได้เร็วขึ้น

ประสบการณ์ที่เคยทำของฉันขัดแย้งกับสิ่งนี้ (แก้ไขล่าสุด)
Mehdi LAMRANI
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.