SQLite / المتقدم: التزامن والاسترداد وحدود التطبيق / الدرس 17
أداء أحمال العمل واقتصاديات التخزين
اربط عدد الاستعلامات ومدة المعاملة وتخطيط التخزين وكلفة الصيانة بحمل SQLite مقيس، بدلاً من تطبيق وصفات ضبط عامة.
في هذه الصفحة
أهداف الدرس
- مقارنة عمليات بحث متكررة بدفعة محدودة.
- شرح تصميم rowid مقابل WITHOUT ROWID.
- تفسير إعادة استخدام الصفحات وVACUUM وإعدادات الموارد ضمن سياقها.
قس العمل الذي يهم التطبيق
حدد الكمون والإنتاجية وتكرار الاستعلامات وحجم النتائج ومعدل الكتابة والموارد المقبولة قبل الضبط. يتجنب SQLite قفزة شبكة منفصلة، لكن تكرار التحضير والتنفيذ وتحويل الصفوف والمسح الزائد يستهلك عملاً. لذلك قد تهم N-plus-one، دون إثبات أن كل استعلام دفعي أسرع لكل بيانات أو حالة مخبأ.
استخدم توزيعات ممثلة وواجهة المضيف الفعلية. يعلم مثال الذاكرة الصغير الدلالة وعدد الاستدعاءات، لا كمون الملفات أو كلفة الديمومة. اشترط صحة النتائج، وقارن تضخيم الكتابة والذاكرة ومدة المعاملة مع القراءة؛ فقد يفيد التغيير تقريراً واحداً ويضر مسار تعديل يتكرر أكثر منه.
ارصد الاستدعاءات المتكررة وبحثاً واحداً مكافئاً
يتتبع البرنامج الأول عمليات SELECT المصطنعة الخاصة به فقط. تعيد ثلاث عمليات بحث بمفتاح واحد وعملية IN مرتبة واحدة الأسماء نفسها، بعدد استدعاءات ثلاثة مقابل واحد. تولد مواضع الربط من عدد قيم محدود وتربط القيم منفصلة. لا يدعي المثال فرق زمن ولا يحتوي بيانات خاصة.
تحتاج الدفعة حدود المعاملات والذاكرة والنتائج وإلغاء التطبيق. عالج الاختيار الفارغ بسياسة صريحة، لا SQL مشوه. أعد استخدام المحضر عند الملاءمة، ولا تحتفظ بمعاملة كتابة أثناء معالجة المستدعي استجابة كبيرة. تقليل الاستدعاءات فرضية تقاس، لا إذن لبناء استعلام عملاق بلا حد.
import sqlite3
from contextlib import closing
with closing(sqlite3.connect(":memory:")) as db:
db.executescript("CREATE TABLE item(id INTEGER PRIMARY KEY,name TEXT); INSERT INTO item VALUES(1,'A'),(2,'B'),(3,'C');")
statements = []
db.set_trace_callback(statements.append)
ids = [1, 2, 3]
separate = [db.execute("SELECT name FROM item WHERE id=?", (key,)).fetchone()[0] for key in ids]
first_count = sum(sql.startswith("SELECT") for sql in statements)
statements.clear()
placeholders = ",".join("?" for _ in ids)
batched = [row[0] for row in db.execute(f"SELECT name FROM item WHERE id IN ({placeholders}) ORDER BY id", ids)]
batch_count = sum(sql.startswith("SELECT") for sql in statements)
db.set_trace_callback(None)
print("names", batched)
print("same", separate == batched)
print("select_calls", first_count, batch_count)
names ['A', 'B', 'C']
same True
select_calls 3 1
ينتج المساران A وB وC. يرصد التتبع المحلي ثلاث عمليات SELECT مقابل واحدة، ولا يقيس كلفة التطبيق الكلية.
اختر الهوية الفيزيائية من سلوك المفاتيح الفعلي
تنظم WITHOUT ROWID التخزين بالمفتاح الأساسي، بدلاً من جدول rowid عادي وبنية منفصلة للبحث بالمفتاح. قد تناسب بعض المفاتيح المركبة أو غير الصحيحة عددياً، وليست تحسين حجم أو سرعة عاماً. يهم عرض المفتاح والوصول والحمولة وواجهة المضيف، مع اختلاف القيم الفارغة وبعض سلوكيات rowid.
ينشئ الثاني جدولاً عادياً وآخر WITHOUT ROWID ويفحص علمي wr عبر pragma_table_list بالإصدار المختبر، لبيان التخطيط فقط. يحتاج اقتراح الأداء مقارنة قراءات وكتابات وتخزين ممثلة، بما فيها الفهارس الثانوية الحاملة للمفتاح الأساسي. لا تختره لأن اسماً وصفياً يوحي بأنه أصغر.
CREATE TABLE ordinary(code TEXT PRIMARY KEY NOT NULL,value TEXT);
CREATE TABLE packed(code TEXT PRIMARY KEY NOT NULL,value TEXT) WITHOUT ROWID;
INSERT INTO ordinary VALUES('A','one');
INSERT INTO packed VALUES('A','one');
SELECT name,wr FROM pragma_table_list WHERE name IN('ordinary','packed') ORDER BY name;
SELECT code,value FROM packed ORDER BY code;
name|wr
ordinary|0
packed|1
code|value
A|one
تميز البيانات الوصفية ordinary ذات wr=0 من packed ذات wr=1. ويبقى صف التطبيق A/one بغض النظر عن مقارنة التخطيط.
افصل الصفحات القابلة لإعادة الاستخدام من تقلص الملف
يجعل حذف الصفوف الصفحات قابلة لإعادة الاستخدام غالباً دون تقليص الملف فوراً. يصف page_count وfreelist_count جانبين مختلفين، ولـ WAL عمر مستقل. تعيد VACUUM البناء والضغط بمتطلبات مساحة وقيود أقفال ومعاملات؛ وليست أمراً بريئاً بعد كل حذف. خطط للصيانة والاستعادة قبل البيانات الحقيقية.
المخبأ وحجم الصفحة وauto_vacuum وsynchronous ونقاط التحقق ضوابط مستقلة بآثار حمل وديمومة. اقرأ الوحدات والاستمرار؛ فليست كل قيمة عددية ميزانية بايتات أو تفضيلاً محلياً للاتصال. لا تضعف المزامنة أو تعطل التسجيل لتجميل قياس صغير، لأنك تغير نموذج الفشل المقارن.
اجعل التحسين قابلاً للرجوع ومدعوماً بالأدلة
سجل أساساً وغير عاملاً مبرراً واحداً وأكد تطابق النتائج التجارية، ثم قس بالحمل نفسه. قارن المعاملات الشائعة والنادرة والتزامن والإلغاء وفترات كثرة الكتابة. قد تغير بيئة التشغيل والإحصاءات الخطط؛ فأدرجها في السجل ولا تفترض دوام النتيجة السابقة.
احفظ سبب كل فهرس وإعداد ومالكه ومعيار الرجوع. قد يتفوق تصميم مضمّن صالح على تعقيد زائد لمهمته، وقد تتطلب الكتابات المتزامنة المستمرة أو الملفات البعيدة معمارية أخرى. تفسر هندسة الأداء الملاءمة بالأدلة، ولا تثبت تفوق SQLite أو غيره تفوقاً شاملاً.
الأخطاء الشائعة وإصلاحها
لم يتقلص ملف القاعدة بعد حذف بياناتها.
- لماذا يحدث؟
- اختلطت إعادة استخدام الصفحات بالاقتطاع الفوري للملف.
- كيف تصلحه؟
- افحص التخصيص وخيارات الصيانة والاستعادة الموثقة.
- كيف تتجنب تكراره؟
- خطط السعة والصيانة بدلاً من ضغط ارتجالي متكرر.
تحسن القياس بعد تعطيل الديمومة.
- لماذا يحدث؟
- غيرت المقارنة ضمانات التعافي من الفشل.
- كيف تصلحه؟
- قارن متطلبات ديمومة متكافئة، وصرح بأي تعديل للإعدادات.
- كيف تتجنب تكراره؟
- عامل التسجيل والمزامنة كإعدادات صحة.
استنفدت دفعة كبيرة الذاكرة أو عدد المعاملات.
- لماذا يحدث؟
- تجاهل تقليل الاستدعاءات ميزانيات الموارد.
- كيف تصلحه؟
- حد أحجام الأجزاء واحفظ دلالات الترتيب والمعاملة.
- كيف تتجنب تكراره؟
- اختبر الدفعات الفارغة والعادية وذات الحجم الأقصى.
اختبر فهمك
1. لماذا لا تثبت ثلاث عمليات SELECT مقابل واحدة تسارعاً بمقدار ثلاثة أضعاف؟
اعرض الحل المشروح
قد تختلف كلفة التحضير والمسح والفرز والتحويل والمخبأ والنتائج بين العمليات. يقيس المثال عدد الاستدعاءات فقط. استخدم قياسات نهائية ممثلة، مع نتائج وضمانات موارد متطابقة، لتقييم الفائدة الفعلية؛ ولا تستنتج نسبة زمن من نسبة عدد الاستدعاءات.
2. متى ينبغي تقييم WITHOUT ROWID بدلاً من اختياره تلقائياً؟
اعرض الحل المشروح
عندما يوحي شكل المفتاح الأساسي الفعلي وحمل الوصول بفائدة محتملة. قارن عرض المفتاح وحمولة الفهرس الثانوي ومسارات القراءة والكتابة وسلوك الواجهة والتخزين ببيانات ممثلة. لا يثبت علم وصفي وحده أن التخطيط مناسب للتطبيق.
أهم ما تعلمته
- قلل العمل المقيس دون إضعاف عقد الصحة.
- للتخطيط التخزيني والصيانة مقايضات تختلف باختلاف الحمل.
- تدخل السعة والتزامن والديمومة في أدلة الأداء.