سؤال

أنا أعمل على تطبيق يعمل على نظام التشغيل ويندوز موبايل 6 التي تحتاج إلى أن تكون قادرة على استرداد كافة العناصر من عنصر الجدول التي تحتوي على سلسلة معينة (المقدمة من قبل المستخدم النهائي) في وصف هذا البند المجال.المشكلة هي أن هناك ما يقرب من 170,000 العناصر في الجدول.منذ أن كنت في حاجة إلى عودة جميع العناصر التي تحتوي على السلسلة في أي مكان داخل الوصف أنا مجبر على استخدام مثل %سلسلة ٪ ، مما يلغي أي فرصة لاستخدام الفهرس.البيانات بنية الجدول هي في الأصل على أساس التقدم قاعدة البيانات التي لديها رائع يحتوي المشغل على أي كلمة-فهرسة الحقول.هذا ليس هو الحال في تطبيقات الهاتف المتحرك لدينا, لأنه يستخدم SQL Server ضغط 3.5.

أساسا ، DAL بتشغيل الاستعلام و يسترجع أحد SqlCeDataReader ثم يستخدم ItemFactory لإنشاء قائمة الكائن الذي يحتوي فقط على البنود المتطابقة.ومن الواضح أن هذا يتيح لنا أن نضع لنا المجال/كائنات الأعمال منفصلة عن طبقة الوصول إلى البيانات.

جيد ومدهش ، باستثناء 8m و 42s أن يلزم لاسترداد العناصر عندما كنت ابحث عن جميع العناصر التي تحتوي على شيء من هذا القبيل "الغولف" في الوصف.من الواضح أن هذا ليس إطار زمني مقبول بالنسبة للمستخدم النهائي.

أول محاولة كانت بدلا استرداد كافة العناصر من قاعدة البيانات باستخدام SELECT * FROM البند" (مع جملة order by على واحدة من أهم فهرسة الحقول).عند هذه النقطة أنا ركض IndexOf تحقق ركضت خلال SqlCeDataReader وكان ItemFactory فقط إضافة عناصر إلى قائمة كائن إذا تضمن طلب نص الوصف.هذا تحسين سرعة وصولا إلى 1m 46s.لا رث جدا ، ولكن لا تزال بطيئة جدا.

ثم حاولت مقاربة أخرى أظهرت أن الوعد...تقريبا...في حين يبدأ التطبيق ، حاولت إنشاء قائمة تحتوي على كل بند الكائنات في قاعدة البيانات (يستغرق حوالي 2 دقيقة لتشغيل الاستعلام نشر قائمة كاملة ولكن على الأقل مرة واحدة فقط لأن التطبيق هو تهيئة...لا يزال...لاف).مرة واحدة اكتمال القائمة ، يمكن بسهولة تشغيل الاستعلامات في تلك القائمة تفعل أشياء مثل التالية (اتمنى ان يكون بناء الجملة الصحيح...أنا في العمل الآن وأنا لم يكن لديك Visual Studio على جهاز الكمبيوتر أنا جالس في):

List<Item> specificItems = 
    AllItems.FindAll(i => i.Description.IndexOf(searchString, StringComparison.OrdinalIgnoreCase) >= 0);

هذا النهج طرقت عليه 21s.لطيفة جدا (لا تزال بطيئة على الرغم من أن في المخطط الكبير للأشياء).بيد أن المشكلة هي أن استخدام الذاكرة بطريقة كبيرة جدا إذا كنت تحميل جميع العناصر من قاعدة البيانات.لقد كان في الواقع قطع آخر 20 ، 000 البنود (حتى 21s الإطار الزمني ربما كان أكثر مثل 25s) أثناء الحمل الأولي ، لأن أووتوفميمورييكسسيبشن يتم تطبيقها.وفقا إدارة الذاكرة على المحاكي, كان لا يزال حوالي 20 ميغابايت من ذاكرة الوصول العشوائي, ولكن سمعت أن العملية يمكن أن يكون فقط 32 MB أو ذاكرة الوصول العشوائي المرتبطة بها (لست متأكدا إذا كان هذا صحيحا بالنسبة WM 6 ، ولكن يبدو الأمر كذلك).

للتأكد من أنه لم يكن لأنني كنت تستخدم قائمة كائن إلى عقد جميع البنود (الذي كان إنشاء مع القدرات اللازمة في منشئ لتجنب دينامية تغيير حجم) ، لقد قرأت أيضا قد يسبب إضافية استخدام الذاكرة عندما implicity المكالمات EnsureCapacity حاولت استخدام البند[] مجموعة (الحجم في وقت مبكر).هذا كان لا يزال مسألة الذاكرة و حجم الفرق لا يكاد يذكر.

حسنا يكفي المشي على الأقدام.أعرف أنني من المحتمل أن يكون بعض كيف تحد من إرجاع السجلات من قاعدة البيانات عن طريق datareader (من خلال بعض فهرسة البحث على نوع مختلف من الحقل) ثم من المرجح أن استخدام indexOf على أصغر مجموعة فرعية من العناصر للحصول على أقصى قدر من الأداء (وبالتالي تخطي مثل مشغل جميع معا).وهذا سوف يسبب المستخدم إلى إدخال أكثر من مجرد الوصف البحث على الرغم من (ربما البند الهرمي المعلومات للحد من أي نوع من البنود البحث داخل).

أي أفكار ؟ أنا ذاهب عن هذا الطريق الخاطئ ؟

شكرا على الاستماع (آسف هذا المنصب طويلا ، أنا نوع من التفكير بصوت عال).

أوه وأود أن أضيف (فقط في ملخص) ما أنا باستخدام:

  • ويندوز موبايل 6
  • إصدار Sql Server ضغط 3.5
  • C# 3.5

تحديث:في حين تتفتح تصفية النهج المذكورة أدناه تبدو مثيرة للاهتمام, أنا لا يمكن أن تفي شرط واحد (التي لم تحدد أعلاه).أنا حقا لا يمكن أن تتطابق مع الكلمات الموجودة داخل بعبارة أخرى (مثلا ، "النادي" لن يعود "النوادي").بسبب هذا, لقد أجبرت على استخدام نهج مختلف تماما (كينت فريدريك...شكرا على الإشارة إلى هذا).لقد تميز كينت إجابة واحدة صحيحة ، منذ نهجه الذي شغل معظم متطلبات (ميتش الخاص بك لديه مشكلة مشابهة كما تتفتح تصفية اقترح Jaunder).ومع ذلك, لقد ذهبت مقاربة مختلفة (الآن) من طريقه كذلك.

ما قمت به هو سحب كل بند الكائنات في الذاكرة مع البند فقط الأرقام والأوصاف (الذي يبقى تحت قيود الذاكرة ، ومع ذلك فإنه لا يزال يسبب أطول التهيئة من أحب...خاصية تعدد وتحميل هذه المعلومات وراء الكواليس في حين يتم تشغيل التطبيق يمكن أن تأخذ الرعاية من ذلك أعتقد).لتنفيذ عمليات البحث لقد كتبت بنفسي يحتوي على الروتين.الروتين هو مكتوب في غير مدارة c# كود يستخدم اثنين من المؤشرات و بعض الحلقات لتشغيل من خلال وصف المطلوبة مطابقة النص.إذا وجد تطابق في أي مكان في الوصف ، ويضيف البند رقم صفيف.مرة واحدة كل البنود التي تم تفتيشها استعلام جديد يعود إلى قاعدة بيانات العناوين الرئيسية للصحف فقط مطابقة أرقام البند (وهو سريع جدا بسبب فهرس على حقل عدد صحيح).ثم تلك العناصر التي تم إنشاؤها في قائمة مع جميع المعلومات (وليس فقط الصنف والوصف).العملية كلها تستغرق حوالي 5 - 10 ثانية (اعتمادا على الوصف) الذي هو جيد بما فيه الكفاية الآن.

أنا لا تزال تبدو في مواصلة تحسين هذا (قد تكون قادرة على تتبع عدد الحروف مصطلح البحث...إذا كان هناك أقل من الأحرف المتبقية على وصف البند من النص المطلوب, الحلقة قد تواصل مباشرة إلى البند التالي).

أي اقتراحات لا تزال موضع ترحيب.الآن لدي ملحوظة كينت الإجابة "الراجح" على سؤالي.

الدعائم Dolch لمساعدتي في كتابة يحتوي على الروتين.

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

المحلول

أنا صوت ميتش القمح الجواب, ولكن هناك عدد قليل من الحيل أنا أيضا اختبار فعالية.

قلقي الأكبر عن وجود الجدول الكامل [شار],[الباحث] هو قد لا تزال تجد نفسك تنفيذ كميات كبيرة من العبث سلسلة المقارنات, خاصة إذا كنت تستخدم %كلمة% على هذا الجدول الجديد.( تتكرر ولكن ليس مطابقة-لدينا-البحث عن مقالات ).

ربما تختار experimeting مع

Words
-----
chars  | word_id 

WordsToEntry
------------
word_id | entry_id 

ومعرفة ما إذا كانت قاعدة البيانات النفقات العامة هو يستحق التخفيف من هذه المشكلة ممكن ( أنا غير قادر على اختبار, آسف )

نصائح أخرى

ماذا عن ما قبل المعالجة (مرة واحدة) بنود جدول (و كل دخول جديد إضافة إلى أنها تحتاج إلى معالجتها) ، لإنشاء كلمة occurrance الجدول وجود

CREATE TABLE WordItemOccurance
(
    [Word] varchar(50) not null,

    ItemId int not null
        constraint FK_Items references ItemTable(ID)
)

تكرار عبر كل البنود الخاصة بك ، كسر في كلمات منفصلة و إضافة إدخالات إلى التكرار الجدول كما وجدوا.

إنشاء فهرس متفاوت المسافات على [كلمة] والانضمام إلى بند جدول ItemId يجب أن تكون سريعة.

قد تتمكن من محاولة استخدام ازهر التصفية.

  1. ويكيبيديا
  2. باستخدام ازهر المرشحات
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top