it-swarm.asia

الآثار المترتبة على أحجام MySQL VARCHAR

هل هناك اختلاف في الأداء في MySQL بين أحجام varchar؟ على سبيل المثال ، varchar(25) و varchar(64000). إذا لم يكن الأمر كذلك ، فهل هناك سبب لعدم الإعلان عن جميع أشكال varchars بالحجم الأقصى فقط لضمان عدم نفاد الغرفة؟

46
BenV

يجب أن تدرك المقايضات باستخدام CHAR vs VARCHAR

مع حقول CHAR ، ما تخصصه هو بالضبط ما تحصل عليه. على سبيل المثال ، تقوم CHAR (15) بتخصيص وتخزين 15 بايت ، بغض النظر عن كيفية وضع الأحرف في الحقل. يعد التلاعب بالسلسلة أمرًا بسيطًا ومباشرًا لأن حجم مجال البيانات يمكن التنبؤ به تمامًا.

مع حقول VARCHAR ، تحصل على قصة مختلفة تمامًا. على سبيل المثال ، يخصص VARCHAR (15) ديناميكيًا حتى 16 بايت ، وما يصل إلى 15 للبيانات ، وعلى الأقل بايت إضافي واحد لتخزين طول البيانات. إذا كان لديك السلسلة "hello" لتخزينها والتي ستستغرق 6 بايت ، وليس 5. يجب أن يؤدي التلاعب بالسلسلة دائمًا إلى شكل من أشكال التحقق من الطول في جميع الحالات.

تكون المقايضة أكثر وضوحًا عندما تفعل شيئين:
1. تخزين ملايين أو مليارات الصفوف
2. أعمدة الفهرسة التي تكون إما CHAR أو VARCHAR

TRADEOFF # 1

من الواضح أن VARCHAR يمتلك الميزة لأن البيانات ذات الطول المتغير ستنتج صفوفًا أصغر ، وبالتالي ملفات فعلية أصغر.

TRADEOFF # 2

نظرًا لأن حقول CHAR تتطلب معالجة سلسلة أقل بسبب عرض الحقول الثابتة ، فإن عمليات البحث في الفهرس مقابل حقل CHAR هي في المتوسط ​​أسرع بنسبة 20٪ من حقول VARCHAR. هذا ليس أي تخمين من جهتي. قام الكتاب تصميم قاعدة بيانات MySQL وضبطها بعمل رائع على طاولة MyISAM لإثبات ذلك. فعل المثال في الكتاب شيئًا مثل ما يلي:

ALTER TABLE tblname ROW_FORMAT=FIXED;

هذه القوى التوجيهية هي VARCHARs تتصرف مثل CHARs. لقد فعلت ذلك في وظيفتي السابقة في عام 2007 وأخذت جدولًا بسعة 300 جيجابايت وسرعت عمليات البحث في الفهرس بنسبة 20٪ ، دون تغيير أي شيء آخر. عملت كما نشرت. ومع ذلك ، فقد أنتج جدولًا بحجم مضاعف تقريبًا ، ولكن هذا ببساطة يعود إلى المفاضلة رقم 1.

يمكنك تحليل البيانات التي يتم تخزينها لمعرفة ما يوصي به MySQL لتعريف العمود. فقط قم بتشغيل ما يلي مقابل أي جدول:

SELECT * FROM tblname PROCEDURE ANALYSE();

سيؤدي هذا إلى اجتياز الجدول بالكامل والتوصية بتعريفات الأعمدة لكل عمود استنادًا إلى البيانات التي يحتوي عليها ، والحد الأدنى لقيم الحقول ، والحد الأقصى لقيم الحقول ، وما إلى ذلك. في بعض الأحيان ، عليك فقط استخدام الحس السليم مع التخطيط CHAR مقابل VARCHAR. هنا هو مثال جيد:

إذا كنت تقوم بتخزين عناوين IP ، فإن القناع الخاص بهذا العمود لا يزيد عن 15 حرفًا (xxx.xxx.xxx.xxx). سوف أقفز مباشرة عند CHAR (15) في ضربات قلب لأن أطوال عناوين IP لن تختلف كثيرًا والتعقيد الإضافي لمعالجة السلسلة الذي يتحكم فيه بايت إضافي. لا يزال بإمكانك إجراء تحليل الإجراء () مقابل هذا العمود. قد يوصي حتى VARCHAR. ستظل أموالي على CHAR عبر VARCHAR في هذه الحالة.

لا يمكن حل مشكلات CHAR vs VARCHAR إلا من خلال التخطيط المناسب. مع القوة العظيمة تأتي مسؤولية كبيرة (مبتذلة لكنها حقيقية)

30
RolandoMySQLDBA

الجواب على ذلك معقد بالفعل. النسخة القصيرة: هناك اختلاف.

  1. عند إنشاء جداول مؤقتة لتصفية النتائج (مثل GROUP BY_البيانات) ، سيتم تخصيص الطول الكامل.

  2. من المحتمل أن يخصص البروتوكول السلكي (إرسال الصفوف إلى العميل) الطول الأكبر.

  3. محرك التخزين قد/لا يقوم بتطبيق varchar المناسب.

بالنسبة لـ (2) ، أعترف أن البروتوكول السلكي ليس شيئًا معتادًا عليه تمامًا ، ولكن النصيحة العامة هنا هي محاولة تطبيق القليل من الجهد على الأقل لتخمين الطول.

13
Morgan Tocker

معظم الإجابات في هذا الموضوع هي خمسة عمرها ثماني سنوات ، كتب قبل InnoDB و utf8 كانت افتراضية. لذا ، دعني أبدأ من جديد ...

عندما يحتاج الاستعلام إلى جدول مؤقت داخلي ، فإنه يحاول استخدام جدول MEMORY. ولكن لا يمكن استخدام الذاكرة إذا

  • TEXT/BLOB يتم جلب الأعمدة ، حتى TINYTEXT.
  • VARCHAR أكبر من بعض المبلغ ، ربما 512 في الإصدار الحالي.

لاحظ أيضًا أن VARCHARs تحولت إلى CHARs. (8.0 يعدل هذا.) لذا ، VARCHAR(255) مع CHARACTER SET utf8 يتمدد إلى 765 بايت ، بغض النظر عما يوجد في العمود. بعد ذلك ، قد يتم تشغيل هذا:

  • إذا كان الجدول MEMORY أكبر من max_heap_table_sizeأوtmp_table_size ، فسيتم تحويله إلى MyISAM ومن المحتمل أن ينتشر إلى القرص.

لذا ، VARCHAR(25) من المرجح أن تبقى MEMORY ، وبالتالي تكون أسرع. (255) ليست جيدة ، و (64000) سيئة.

(في المستقبل ، من المحتمل أن تكون الجداول المؤقتة InnoDB ، وسيحتاج جزء من هذه الإجابة إلى المراجعة.)

11
Rick James

عمود varchar بهذا الحجم يجعل الاستعلامات على الجدول بأكمله أكثر عرضة لاستخدام الجداول المؤقتة. وفقًا لكتاب MySQL عالي الأداء. عندما يحاول المُحسّن معرفة ما إذا كان يمكنه تشغيل هذا الاستعلام في الذاكرة أو إذا كان يحتاج إلى جدول مؤقت ، فإنه ينظر إلى حجم الصف بناءً على تعريف الجدول ، وهذا يعني أنه بالنسبة للسرعة ، فإنه لا يحاول معرفة عدد الأحرف البالغ 64 كيلو تستخدمه بالفعل. هذا هو السبب في أن الكتاب ينصحون بعدم تمديد هذا التعريف بشكل يتجاوز القيم الممكنة الفعلية التي ستدخل في العمود. من الواضح ، إذا قمت بإعداد نفسك لمزيد من الاستفسارات التي تدخل في جداول مؤقتة (حتى لو كان حجم البيانات الفعلي يمكن أن يتناسب مع ذاكرة الوصول العشوائي) ، فقد تكبدت الآن عقوبات I/O التي يمكن تجنبها.

6
TechieGurl

أفهم أن الحقول الأصغر قد تكون قابلة للتضمين في الفهرس مباشرة ، في حين أن الحقول الأطول لا يمكن. بسبب هذا القيد ، إذا كنت تريد أن تكون السلاسل قابلة للفهرسة ، فأنا أقول أنها ستبقى أقصر. خلاف ذلك ، لا ، كونها كيف كلاهما varchar ثم ops مثل الفرز أو المقارنة ستعمل في نفس الوقت ، سواء كانت الحقول 25 أو MAX.

5
jcolebrand

تأكد من عدم نفاد الغرفة

تشير هذه العبارة إلى أنك تطرح السؤال لأنك لست متأكدًا من البيانات التي ستخزنها في قاعدة البيانات. إذا كان هذا صحيحًا ، فسيكون من المفيد جدًا معرفة ذلك بأسرع ما يمكن ، لأنك ستحتاج إلى ذلك لتخطيط السعة. إذا كنت قد تحصل على عناصر بيانات مكونة من 7000 حرف ، على سبيل المثال ، فأنت بحاجة إلى معرفة ذلك لأن ذلك سيكون له آثار على الأداء في أي DBMS.

ومع ذلك ، أفضل أن يكون لديك أحجام أعمدة مرتبطة بالمحتويات المتوقعة. على سبيل المثال ، من غير المحتمل أن يزيد رقم الهاتف عن 50 حرفًا ، حتى إذا قمت بتضمين رمز البلد والإضافة. وبالمثل ، من المحتمل أن يتكون الرمز البريدي أو الرمز البريدي من 20 حرفًا أو أقل.

3
Larry Coleman