كيفية تقليل حجم جدول SQL Server الذي زاد من تغيير نوع البيانات

StackOverflow https://stackoverflow.com/questions/807579

سؤال

لدي جدول على SQL Server 2005 يبلغ حجمه حوالي 4 جيجابايت.

(حوالي 17 مليون سجل)

لقد قمت بتغيير أحد الحقول من نوع البيانات char(30) ل char(60) (يوجد إجمالي 25 حقلاً معظمها char(10) وبالتالي فإن مقدار مساحة الحرف يصل إلى حوالي 300)

أدى هذا إلى مضاعفة حجم الجدول (أكثر من 9 جيجابايت)

ثم قمت بتغيير char(60) ل varchar(60) ثم قم بتشغيل وظيفة لقطع المسافات البيضاء الإضافية من البيانات (بحيث يتم تقليل متوسط ​​طول البيانات في الحقل إلى حوالي 15)

هذا لم يقلل من حجم الجدول.تقليص قاعدة البيانات لم يساعد أيضًا.

بعيدًا عن إعادة إنشاء بنية الجدول فعليًا ونسخ البيانات (أي 17 مليون سجل!) هل هناك طريقة أقل جذرية لتقليص الحجم مرة أخرى؟

هل كانت مفيدة؟

المحلول

حسنًا، من الواضح أنك لن تستعيد أي مساحة!:-)

عندما تقوم بتغيير حقول النص الخاصة بك إلى CHAR(60)، يتم ملؤها جميعًا بالمسافات.إذن يبلغ طول جميع حقولك الآن 60 حرفًا.

لن يساعد تغيير ذلك مرة أخرى إلى VARCHAR(60) - فلا تزال الحقول بطول 60 حرفًا....

ما عليك فعله حقًا هو تشغيل دالة TRIM على جميع الحقول الخاصة بك لتقليلها مرة أخرى إلى طولها المقطوع، ثم تقليص قاعدة البيانات.

بعد الانتهاء من ذلك، تحتاج إلى إعادة بناء الفهرس المجمع الخاص بك من أجل استعادة بعض تلك المساحة المهدرة.الفهرس المجمع هو المكان الذي توجد فيه بياناتك حقًا - يمكنك إعادة بنائه على النحو التالي:

ALTER INDEX IndexName ON YourTable REBUILD 

افتراضيًا، مفتاحك الأساسي هو الفهرس المجمع (ما لم تحدد خلاف ذلك).

مارك

نصائح أخرى

لم تقم بتنظيف أو ضغط أية بيانات، حتى مع "قاعدة البيانات المصغرة".

DBCC قابلة للتنظيف

يستعيد المساحة من الأعمدة ذات الطول المتغير التي تم إسقاطها في الجداول أو طرق العرض المفهرسة.

ومع ذلك، أ إعادة بناء الفهرس البسيط إذا كان هناك فهرس متفاوت المسافات ينبغي أن تفعل ذلك أيضا

ALTER INDEX ALL ON dbo.Mytable REBUILD

مثال عملي من توني روجرسون

أعلم أنني لا أجيب على سؤالك كما تطرح، ولكن هل فكرت في أرشفة بعض البيانات في جدول المحفوظات، والعمل مع عدد أقل من الصفوف؟

في معظم الأوقات قد تعتقد للوهلة الأولى أنك بحاجة إلى كل هذه البيانات طوال الوقت، ولكن عندما تجلس وتفحصها، هناك حالات يكون فيها هذا غير صحيح.أو على الأقل لقد واجهت هذا الموقف من قبل.

كان لدي مشكلة مماثلة هنا خادم SQL، تحويل NTEXT إلى NVARCHAR (MAX) كان ذلك متعلقًا بتغيير ntext إلى nvarchar(max).

كان علي أن أفعل UPDATE MyTable SET MyValue = MyValue من أجل جعله يغير حجم كل شيء بشكل جيد.

من الواضح أن هذا يستغرق وقتًا طويلاً مع الكثير من السجلات.كان هناك عدد من الاقتراحات حول أفضل السبل للقيام بذلك.كان المفتاح الأول عبارة عن علامة مؤقتة تشير إلى ما إذا كان قد تم القيام بذلك أم لا ثم تحديث بضعة آلاف في المرة الواحدة في حلقة حتى يتم الانتهاء من كل شيء.هذا يعني أن لدي بعض السيطرة على مقدار ما كان يفعله.

ومع ذلك، في ملاحظة أخرى، إذا كنت تريد حقًا تقليص قاعدة البيانات قدر الإمكان، فقد يكون من المفيد أن تقوم بتحويل نموذج الاسترداد إلى نموذج بسيط، وتقليص سجلات المعاملات، وإعادة تنظيم جميع البيانات في الصفحات، ثم إعادة ضبطها بالكامل مرة أخرى نموذج الاسترداد.لكن كن حذرًا، لا يُنصح بتقليص قواعد البيانات بشكل عام، وإذا قمت بتقليل نموذج الاسترداد لقاعدة بيانات حية، فإنك تطالب بحدوث خطأ ما.

بدلاً من ذلك، يمكنك إعادة بناء الجدول بالكامل لضمان عدم وجود بيانات إضافية في أي مكان:

CREATE TABLE tmp_table(<column definitions>);
GO
INSERT INTO tmp_table(<columns>) SELECT <columns> FROM <table>;
GO
DROP TABLE <table>;
GO
EXEC sp_rename N'tmp_table', N'<table>';
GO

وبطبيعة الحال، تصبح الأمور أكثر تعقيدا مع الهوية والفهارس وما إلى ذلك ...

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top