سؤال

وهنا هو الاستعلام الخاص بي:

select word_id, count(sentence_id) 
from sentence_word 
group by word_id 
having count(sentence_id) > 100;

ووsentenceword الجدول يحتوي على 3 حقول، wordid، sentenceid ومعرف المفتاح الأساسي. لديها 350K + الصفوف. يأخذ هذا الاستعلام ضخم 85 ثانية، وأنا أتساءل (أمل، والصلاة؟) هل هناك طريقة أسرع للعثور على جميع wordids التي لديها أكثر من 100 sentenceids.

ولقد حاول اخراج جزء العد حدد، ومجرد القيام 'وجود عدد (1) "ولكن لا سرعات عنه.

وكنت نقدر أي مساعدة يمكن أن تقدم. شكرا!

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

المحلول

<اقتباس فقرة>   

وجود عدد (sentence_id)> 100؛

وليس هناك مشكلة مع هذا ... إما أن الجدول يحتوي مكررة كلمة / أزواج الجملة، أو لا.

إذا كان لديها المكررة أزواج كلمة / جملة، يجب أن تستخدم هذا الرمز للحصول على الإجابة الصحيحة:

HAVING COUNT(DISTINCT Sentence_ID) > 100

إذا لم يكن في الجدول المكررة أزواج كلمة / الجملة ... ثم يجب أن لا نعول sentence_ids، يجب الاعتماد فقط الصفوف.

HAVING COUNT(*) > 100

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

نصائح أخرى

إذا لم يكن لديك بالفعل واحدة، إنشاء فهرس مركب على sentence_id، word_id.

إذا غالبا ما يتم تنفيذ هذا الاستعلام، ونادرا تحديث الجدول، هل يمكن إبقاء الجدول المساعد مع هويات كلمة وتعول الجملة المقابلة - من الصعب التفكير في أي الأمثل مزيد أبعد من ذلك

والاستعلام الخاص بك هو على ما يرام، لكنه يحتاج إلى القليل من المساعدة (الأرقام القياسية) للحصول على نتائج أسرع.

وليس لدي مواردي في متناول اليد (أو الوصول إلى SQL)، ولكن سأحاول مساعدتك من الذاكرة.

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

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

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

CREATE INDEX someindexname ON sentence_word (word_id)

و(جملة T-SQL، لم يتم تحديد أي منتج SQL الذي تستخدمه)

إذا كان هذا لا يكفي (أو لا يساعد على الإطلاق)، وهناك نوعان من الحلول الأخرى.

أولا، SQL يسمح لك precompute على COUNT (*) باستخدام طرق العرض المفهرسة وغيرها من الآليات. ليس لدي تفاصيل في متناول اليد (وأنا لا تفعل هذا في كثير من الأحيان). إذا لم تتغير البيانات في كثير من الأحيان، من شأنه أن تعطيك نتائج سريعة ولكن مع تكلفة في التعقيد وقليلا من التخزين.

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

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

وهناك، من المستغرب، وهي طريقة أسرع لتحقيق ذلك على مجموعات البيانات الكبيرة:

SELECT totals.word_id, totals.num 
  FROM (SELECT word_id, COUNT(*) AS num FROM sentence_word GROUP BY word_id) AS totals
 WHERE num > 1000;
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top