سؤال

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

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

شكرا

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

المحلول

'أفضل الممارسات' تجنب المؤشرات في SQL Server يعود إلى SQL Server 2000 والإصدارات السابقة.إعادة كتابة المحرك في SQL server 2005 معالجة معظم القضايا المتعلقة بالمشاكل المؤشرات ، خاصة مع إدخال سريع إلى الأمام الخيار.المؤشرات ليست neccessarily أسوأ من مجموعة على أساس وتستخدم على نطاق واسع وبنجاح في Oracle PL/SQL (حلقة).

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

نصائح أخرى

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

وإليك بعض الإشارات التي لن يكون إلا غيض من فيض إذا كنت بحث هذه المسألة:

http://www.code-magazine.com/Article.aspx?quickid=060113

http://dataeducation.com/re-inventing-the-recursive-cte/

هذا الجواب في ترسيخ الردود حتى الآن.

1) إذا كان في الإمكان استخدام مجموعة منطق يستند على أي من الاستفسارات الخاصة بكمحاولة استخدام فقط SELECT, INSERT, UPDATE أو DELETE مع المناسبة FROM البنود أو متداخلة استعلامات - هذه ستكون دائما تقريبا بشكل أسرع.

2) إذا كان ما سبق غير ممكن ، ثم في SQL Server 2005+ FAST FORWARD مؤشرات كفاءة أداء جيدا ويجب استخدامها في الأفضلية حين الحلقات.

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

ليس بهذه السرعة!ووفقا لمايكروسوفت:"عادة عندما تكون هذه التحويلات حدث نوع المؤشر المتدهورة إلى 'أكثر تكلفة' نوع المؤشر.عموما, (سريع) للأمام فقط المؤشر هو الأكثر performant ، تليها ديناميكية مجموعة المفاتيح و أخيرا ثابتة والتي هي عموما أقل performant."

من: http://blogs.msdn.com/b/mssqlisv/archive/2006/06/23/644493.aspx

يمكنك تجنب المؤشرات معظم الوقت, ولكن في بعض الأحيان أنه من الضروري.

فقط نأخذ في الاعتبار أن FAST_FORWARD الحيوية ...FORWARD_ONLY يمكنك استخدامها مع رأس مؤشر ثابتة.

محاولة استخدامه على هالوين المشكلة لنرى ماذا سيحدث !!!

IF OBJECT_ID('Funcionarios') IS NOT NULL
DROP TABLE Funcionarios
GO

CREATE TABLE Funcionarios(ID          Int IDENTITY(1,1) PRIMARY KEY,
                          ContactName Char(7000),
                          Salario     Numeric(18,2));
GO

INSERT INTO Funcionarios(ContactName, Salario) VALUES('Fabiano', 1900)
INSERT INTO Funcionarios(ContactName, Salario) VALUES('Luciano',2050)
INSERT INTO Funcionarios(ContactName, Salario) VALUES('Gilberto', 2070)
INSERT INTO Funcionarios(ContactName, Salario) VALUES('Ivan', 2090)
GO

CREATE NONCLUSTERED INDEX ix_Salario ON Funcionarios(Salario)
GO

-- Halloween problem, will update all rows until then reach 3000 !!!
UPDATE Funcionarios SET Salario = Salario * 1.1
  FROM Funcionarios WITH(index=ix_Salario)
 WHERE Salario < 3000
GO

-- Simulate here with all different CURSOR declarations
-- DYNAMIC update the rows until all of then reach 3000
-- FAST_FORWARD update the rows until all of then reach 3000
-- STATIC update the rows only one time. 

BEGIN TRAN
DECLARE @ID INT
DECLARE TMP_Cursor CURSOR DYNAMIC 
--DECLARE TMP_Cursor CURSOR FAST_FORWARD
--DECLARE TMP_Cursor CURSOR STATIC READ_ONLY FORWARD_ONLY
    FOR SELECT ID 
          FROM Funcionarios WITH(index=ix_Salario)
         WHERE Salario < 3000

OPEN TMP_Cursor

FETCH NEXT FROM TMP_Cursor INTO @ID

WHILE @@FETCH_STATUS = 0
BEGIN
  SELECT * FROM Funcionarios WITH(index=ix_Salario)

  UPDATE Funcionarios SET Salario = Salario * 1.1 
   WHERE ID = @ID

  FETCH NEXT FROM TMP_Cursor INTO @ID
END

CLOSE TMP_Cursor
DEALLOCATE TMP_Cursor

SELECT * FROM Funcionarios

ROLLBACK TRAN
GO

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

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

هذه المادة يسلط الضوء على أن متوسط المؤشر يعمل 50 مرات أسرع من حلقة while.

بعض البدائل باستخدام المؤشر:

في حين الحلقات درجة الحرارة tablolar مشتقة الجداول المرتبطة الاستعلامات الفرعية حالة البيانات متعددة الاستجوابات في كثير من الأحيان ، العمليات المؤشر يمكن أيضا أن يتحقق مع عدم المؤشر التقنيات.

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

بعض المؤشر الخصائص التي تؤثر على الأداء وتشمل:

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

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

مجموعة المفاتيح:Cursored الصفوف يتم وضعها في الجدول تحت tempdb والتغييرات nonkey الأعمدة تنعكس عندما جلب يسمى.غير أن سجلات جديدة تضاف إلى الجدول لا تنعكس.مع مجموعة مفاتيح المؤشر ، حدد البيان لا يتم تقييم مرة أخرى.

الديناميكية:جميع التغييرات على الجدول تنعكس في cursore.المؤشر هو إعادة تقييمها عند كل الجلب يسمى.يستخدم الكثير من الموارد و يؤثر سلبا على الأداء.

FAST_FORWARD:المؤشر هو اتجاه واحد ، مثل FORWARD_ONLY ، ولكن يحدد المؤشر للقراءة فقط.FORWARD_ONLY هو زيادة في الأداء و المؤشر لا يعيد تقييم كل الجلب.أنه يعطي أفضل أداء إذا كانت مناسبة للبرمجة.

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

ملاحظة:إذا cursore لم يتم تحديد الافتراضي هو FORWARD_ONLY.

الإجابة ميل الأصلي الأسئلة...

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

إضافة إلى ما إريك Z.اللحية شارك في هذا الموضوع و إلى مزيد من الإجابة على السؤال...

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

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

هناك أيضا مفهوم "خفية RBAR".هذا هو الكود الذي يبدو على أساس ولكن في الواقع ليس كذلك.هذا النوع من "مجموعة القائم على" رمز هو السبب في أن بعض الناس قد تبنت RBAR الطرق و يقولون انهم "موافق".على سبيل المثال, حل تشغيل إجمالي المشكلة باستخدام المجمعة (مجموع) يرتبط الفرعية الاستعلام مع التفاوت في ذلك بناء مجموعه تشغيل ليس مجموعة مقرها في كتابي.بدلا من ذلك, انها RBAR على المنشطات لأن لكل صف محسوبة ، فقد مرارا وتكرارا "لمسة" العديد من الصفوف الأخرى بمعدل N*(N+1)/2.هذا هو المعروف باسم "الثلاثي انضمام" و هو على الأقل نصف سيئة كما الكاملة الديكارتي الانضمام (عبر الانضمام أو "مربع انضمام").

على الرغم من أن مايكروسوفت قد حققت بعض التحسينات في كيفية المؤشرات العمل منذ SQL Server 2005 مصطلح "سريع المؤشر" لا تزال تناقض مقارنة مكتوبة بشكل صحيح تعيين القائم على القانون.وهذا ينطبق أيضا حتى في أوراكل.لقد عملت مع أوراكل لفترة قصيرة من 3 سنوات في الماضي ولكن عملي كان تقديم تحسينات في الأداء في التعليمات البرمجية الموجودة.معظم حقا تحسينات كبيرة تحققت عندما تحولت المؤشرات إلى مجموعة يستند إلى قانون.العديد من فرص العمل التي كانت تستغرق من 4 إلى 8 ساعات من تنفيذ خفضت دقائق و أحيانا ثانية.

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

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