سؤال

ولدي بعض الإجراءات المعقدة المخزنة التي قد ترجع عدة آلاف من الصفوف، ويستغرق وقتا طويلا لإكمال.

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

وهذا هو مع Visual Studio 2005، تطبيق WinForms عناصر و SQL Server 2005.

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

المحلول

وحل لمشكلتك قد تكون لإعادة كتابة الإجراء المخزن بحيث يحد من مجموعة النتائج إلى بعض الأرقام، مثل:

SELECT TOP 1000 * FROM tblWHATEVER

وفي SQL Server أو

SELECT * FROM tblWHATEVER WHERE ROWNUM <= 1000

وفي أوراكل. أو تنفيذ حل الترحيل بحيث تكون النتيجة مجموعة من كل مكالمة صغيرة مقبول.

نصائح أخرى

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

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

وجعل بروك المخزنة لحساب الصفوف الأولى.

وCOUNT SELECT (*) FROM الجدول

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

وأنت لا يمكن الحصول على ROWCOUNT إجراء دون تنفيذ هذا الإجراء.

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

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

select firstname, lastname, email, orderdate  from 
customer inner join productorder on customer.customerid=productorder.productorderid
where orderdate>@orderdate order by lastname, firstname;

ونسخة العد الخاص بك سيكون شيئا مثل:

select count(*) from productorder where orderdate>@orderdate;

وليس بشكل عام.

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

ولكن سيكون لديك لاستدعاء العد SP أولا ثم SP البيانات أو هل يمكن أن ننظر في استخدام مجموعة نتائج متعددة SP.

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

وبعض الاحتمالات:

1) هل تعرض SQL خادم النتائج محسن الاستعلام الخاص به بطريقة أو بأخرى؟ أي يمكن تحليل الاستعلام ومن ثم الحصول على تقدير من ROWCOUNT؟ (أنا لا أعرف SQL سيرفر).

2) ربما استنادا إلى معايير المستخدم يمنحك يمكن أن تؤدي بعض التقديرات الخاصة بك. على سبيل المثال، إذا أدخل المستخدم 'S٪' في مجال لقب العملاء للاستعلام عن أوامر هل يمكن تحديد أن يطابق 7٪ (مثلا) من سجلات العملاء، واستقراء أن الاستعلام <م> قد عودة حول 7٪ من سجلات النظام.

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

SET showplan_text OFF
GO
SET showplan_all on
GO
--Replace with call you your stored procedure
select * from MyTable
GO 
SET showplan_all ofF
GO

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

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

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

وثم إضافة المعلمة اختيارية أخرى إلى بروك المخزنة يسمى، مثلا،CountsOnly، مع التقصير كاذبة (0) وذلك ...

Alter Procedure <storedProcName>
@param1 Type, 
-- Other current params
@CountsOnly TinyInt = 0
As
Set NoCount On

   If @CountsOnly = 1
       Select Count(*) 
       From TableA A 
          Join TableB B On   etc. etc...
       Where < here put all Filtering predicates >

   Else
      <Here put old SQL That returns complete resultset with all data>

  Return 0

ويمكنك بعد ذلك مجرد دعوة نفس بروك المخزنة معCountsOnly تعيين يساوي 1 إلى مجرد الحصول على عدد السجلات. القانون القديم الذي يستدعي بروك لا تزال تعمل كما كانت، منذ تم تعيين قيمة المعلمة الافتراضي إلى false (0)، إذا لم يتم تضمينه

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

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

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