none
SET ARITHABORT ON RRS feed

  • שאלה

  • היי.

    יש לי פרוצדורה שמהאפליקציה רצה עשרות שניות וב-SSMS שניה מקסימום. הביסה: SET ARITHABORT ON ב-SSMS ו-OFF באפליקציה.

    כאשר אני יוצר מחדש את הפרוצדורה בקוד הבא, הריצות אחריה מסתדרות:

    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    SET ARITHABORT ON
    GO
    
    CREATE PROCEDURE ...

    אבל מתישהו זה כבר לא תופס..... כנראה בגלל אחת משתי הסיבות האלו:

    1. זה לא באמת נקלט אלא רק גורם ליצירת PLAN חדש
    2. לא הכרחתי מספיק טוב את ה-SQL לקלוט שאני מבקש SET ARITHABORT ON

    יש למישהו רעיון?


    itaigitt, http://copypastenet.blogspot.com

    יום שני 10 דצמבר 2012 07:46

תשובות

  • אם אתה רוצה שההגדרות יכנסו בזמן הפעלת הפרוצדורה תמיד אתה יכול להכניס אותם אל הפרוצדורה כחלק ממנה ולא רק בזמן יצירת הפרוצדורה

    מה שעשית זה להגדיר את הסשן של יצירת הפרוצדורה וחלא של הרצת הפרוצדורה.

    למשל:

    IF OBJECT_ID ( 'HumanResources.uspGetAllEmployees', 'P' ) IS NOT NULL 
        DROP PROCEDURE HumanResources.uspGetAllEmployees;
    GO
    CREATE PROCEDURE HumanResources.uspGetAllEmployees
    AS
        SET NOCOUNT ON;
        SET ARITHABORT ON;
        SELECT LastName, FirstName, Department
        FROM HumanResources.vEmployeeDepartmentHistory;
    GO
    * הערה: בדרך כלל אני לא ממליץ לעבוד עם SET ARITHABORT ON בפרוצדורה אם אפשר לבצע בדיקה פשוטה בזמן ההרצה של הנתונים. SET ARITHABORT ON נועד הרי לוודא שאין לך בעייה מתמטית כמו חלוקה באפס, אבל זה משהו שאתה רוצה לעלות עליו בדרך כלל ולפעול בהתאם וקל מאוד לכסות את המקרה הזה לבד. זו הגדרה שיותר יעילה דווקא לברירת המחדל כשאר לא יכולים לדעת מה נריץ מחר ואנו רוצים לכסות את ההתנהגות של השרת שלנו במקרים כאלו.


    signature

    • נערך על-ידי pituachMVP, Editor יום שני 10 דצמבר 2012 08:01
    • סומן כתשובה על-ידי itaigitt יום שני 10 דצמבר 2012 11:42
    יום שני 10 דצמבר 2012 07:51
    מנחה דיון
  • הי,

    זה אכן אחד ההזויים...

    אם אתה רוצה שהאפליקציה תעבוד עם ARITHABORT ON, כמו SSMS, אז אתה יכול לשנות את זה בהגדרות של ה-Connection או פשוט להריץ את הפקודה מיד אחרי שאתה יוצר את ה-Connection. אבל קח בחשבון שזה יכול להשפיע על התוצאות שתקבל, אז תבדוק עם עצמך שזה באמת מה שאתה רוצה.

    העניין הוא שבדרך-כלל הסיבה לפער בביצועים היא לא בגלל ON או OFF. הסיבה היא עקיפה. עצם זה שאתה משתמש בהגדרה שונה ב-SSMS גורמת ליצירת Plan חדש, ובמקרה ה-Plan הזה יותר יעיל מה-Plan שקיבלה האפליקציה. בדרך כלל זה נובע מ-Parameter Sniffing ומערכי הפרמטרים שבמקרה היו בשימוש בזמן ההרצה הראשונה מ-SSMS. זה פשוט עניין של מזל. ברוב המקרים, אם פשוט תקמפל את הפרוצדורה מחדש (כמו שעשית בעקיפין כשיצרת את הפרוצדורה מחדש), האפליקציה תקבל Plan חדש, והוא כבר יהיה יעיל, למרות שלא השתנה כלום מבחינת ARITHABORT. זה פשוט עניין של מזל.

    אם הבעיה חוזרת על עצמה, אם הפרוצדורה לא רצה בתדירות גבוהה מדי, ואם אין לך עומס יתר על ה-CPU, אז אני ממליץ פשוט להוסיף WITH RECOMPILE לפרוצדורה.

    בהצלחה!

    -----------------------------
    גיא גלנצר
    יועץ ומדריך SQL Server
    Madeira - SQL Server Services
    http://www.madeira.co.il

    • סומן כתשובה על-ידי itaigitt יום רביעי 12 דצמבר 2012 13:05
    יום רביעי 12 דצמבר 2012 12:05
    מנחה דיון

כל התגובות

  • אם אתה רוצה שההגדרות יכנסו בזמן הפעלת הפרוצדורה תמיד אתה יכול להכניס אותם אל הפרוצדורה כחלק ממנה ולא רק בזמן יצירת הפרוצדורה

    מה שעשית זה להגדיר את הסשן של יצירת הפרוצדורה וחלא של הרצת הפרוצדורה.

    למשל:

    IF OBJECT_ID ( 'HumanResources.uspGetAllEmployees', 'P' ) IS NOT NULL 
        DROP PROCEDURE HumanResources.uspGetAllEmployees;
    GO
    CREATE PROCEDURE HumanResources.uspGetAllEmployees
    AS
        SET NOCOUNT ON;
        SET ARITHABORT ON;
        SELECT LastName, FirstName, Department
        FROM HumanResources.vEmployeeDepartmentHistory;
    GO
    * הערה: בדרך כלל אני לא ממליץ לעבוד עם SET ARITHABORT ON בפרוצדורה אם אפשר לבצע בדיקה פשוטה בזמן ההרצה של הנתונים. SET ARITHABORT ON נועד הרי לוודא שאין לך בעייה מתמטית כמו חלוקה באפס, אבל זה משהו שאתה רוצה לעלות עליו בדרך כלל ולפעול בהתאם וקל מאוד לכסות את המקרה הזה לבד. זו הגדרה שיותר יעילה דווקא לברירת המחדל כשאר לא יכולים לדעת מה נריץ מחר ואנו רוצים לכסות את ההתנהגות של השרת שלנו במקרים כאלו.


    signature

    • נערך על-ידי pituachMVP, Editor יום שני 10 דצמבר 2012 08:01
    • סומן כתשובה על-ידי itaigitt יום שני 10 דצמבר 2012 11:42
    יום שני 10 דצמבר 2012 07:51
    מנחה דיון
  • הי,

    איתי, הפקודה שאתה מריץ משפיעה רק על ה-Session שיצר את הפרוצדורה, כמו שרונן ציין. יש תכונות שנשמרות יחד עם הפרוצדורה על-פי ה-Session שבו היא נוצרה, כמו ANSI_NULLS ו-QUOTED_IDENTIFIER, אבל ARITHABORT היא לא אחת מהן. בפועל, עדיין כל Session שמריץ את הפרוצדורה משתמש בהגדרות שלו, ואם ARITHABORT שונה, הוא יקבל Plan נפרד.

    רונן, הרצה של הפקודה בתוך הפרוצדורה גם לא תעזור, כי זה רק אומר שבזמן ריצה ההגדרה הזאת תשתנה, אבל עדיין כל Session יקבל Plan נפרד בהתאם להגדרות שלו, עוד לפני שהפרוצדורה רצה בכלל.

    איתי, אני מניח שהסיבה שאחרי השינוי שעשית זה הסתדר, היא הסיבה הראשונה שציינת. מכיוון שיצרת את הפרוצדורה מחדש, אז בהזדמנות זו קיבלת גם Plan חדש, וכנראה שבמקרה ה-Plan הזה היה יעיל. אם אתה לא רוצה לקבל Plan שונה ב-SSMS, אתה צריך פשוט לשנות את ההגדרות ב-SSMS כדי שתריץ את הפרוצדורה עם ARITHABORT OFF, בדיוק כמו באפליקציה.

    מקווה שעזרתי...

    -----------------------------
    גיא גלנצר
    יועץ ומדריך SQL Server
    Madeira - SQL Server Services
    http://www.madeira.co.il

    יום רביעי 12 דצמבר 2012 06:43
    מנחה דיון
  • תודה גיא.

    השאלה היא איך אני מתקן את הפער כדי לתת דווקא לאפליקציה את ההגדרה שלא פוגעת בביצועים?

    הקטע הזה עם ARITHABORT וההשפעה שלו על הביצועים הוא אחד ההזויים..... :-S


    itaigitt, http://copypastenet.blogspot.com

    יום רביעי 12 דצמבר 2012 07:11
  • הי,

    זה אכן אחד ההזויים...

    אם אתה רוצה שהאפליקציה תעבוד עם ARITHABORT ON, כמו SSMS, אז אתה יכול לשנות את זה בהגדרות של ה-Connection או פשוט להריץ את הפקודה מיד אחרי שאתה יוצר את ה-Connection. אבל קח בחשבון שזה יכול להשפיע על התוצאות שתקבל, אז תבדוק עם עצמך שזה באמת מה שאתה רוצה.

    העניין הוא שבדרך-כלל הסיבה לפער בביצועים היא לא בגלל ON או OFF. הסיבה היא עקיפה. עצם זה שאתה משתמש בהגדרה שונה ב-SSMS גורמת ליצירת Plan חדש, ובמקרה ה-Plan הזה יותר יעיל מה-Plan שקיבלה האפליקציה. בדרך כלל זה נובע מ-Parameter Sniffing ומערכי הפרמטרים שבמקרה היו בשימוש בזמן ההרצה הראשונה מ-SSMS. זה פשוט עניין של מזל. ברוב המקרים, אם פשוט תקמפל את הפרוצדורה מחדש (כמו שעשית בעקיפין כשיצרת את הפרוצדורה מחדש), האפליקציה תקבל Plan חדש, והוא כבר יהיה יעיל, למרות שלא השתנה כלום מבחינת ARITHABORT. זה פשוט עניין של מזל.

    אם הבעיה חוזרת על עצמה, אם הפרוצדורה לא רצה בתדירות גבוהה מדי, ואם אין לך עומס יתר על ה-CPU, אז אני ממליץ פשוט להוסיף WITH RECOMPILE לפרוצדורה.

    בהצלחה!

    -----------------------------
    גיא גלנצר
    יועץ ומדריך SQL Server
    Madeira - SQL Server Services
    http://www.madeira.co.il

    • סומן כתשובה על-ידי itaigitt יום רביעי 12 דצמבר 2012 13:05
    יום רביעי 12 דצמבר 2012 12:05
    מנחה דיון