מדריך performance tuning

איך לבצע אופטימיזציה לביצועי SQL Server

עבודת ביצועים ב-SQL Server משתבשת כאשר צוותים קופצים ישר ל-rebuild של אינדקסים או לשדרוג חומרה. הדרך הטובה יותר היא למדוד את ה-waits הדומיננטיים, לאמת סטטיסטיקות, לבדוק את אסטרטגיית האינדקסים ורק אז לכוון plans, זיכרון, TempDB ואחסון לפי ההתנהגות האמיתית של העומס.

התחילו מראיות, לא מהנחות

כיוונון ביצועים הוא בעיית סדר. אם המנוע מבלה את רוב זמנו בהמתנה ל-locks, memory grants, log flushes או I/O stalls, כל החלטה בהמשך צריכה לשקף זאת. הדרך המהירה ביותר לבזבז זמן היא לבצע אופטימיזציה מבודדת בלי לזהות קודם את צוואר הבקבוק הדומיננטי ואת ה-statements שיוצרים אותו.

כלל מעשי: אם תוכנית הכיוונון שלכם מתחילה בבנייה מחדש של כל האינדקסים, דילגתם על שלב האבחון.

??????? ???????? ?????? SQL Server

???? ???? ???? ?????? ?? ??? ?????? ?????: ????? ?? ????? ??????, ???? ??????, ??? ?????? ?-statements ????? ?????? ??????.

?????? ?? wait statistics

sql

?? ?????? ???? ????? ??? ????? ???? SQL Server ???? ??? ???? ?????? ???????? ?? ???????????.

SELECT TOP (10)
    wait_type,
    waiting_tasks_count,
    wait_time_ms / 1000.0 AS wait_time_seconds,
    max_wait_time_ms / 1000.0 AS max_wait_seconds,
    signal_wait_time_ms / 1000.0 AS signal_wait_seconds
FROM sys.dm_os_wait_stats
WHERE wait_type NOT LIKE 'SLEEP%'
  AND wait_type NOT IN ('CLR_SEMAPHORE', 'LAZYWRITER_SLEEP', 'XE_TIMER_EVENT')
ORDER BY wait_time_ms DESC;

????? ?????????? ?? ???? ?? ???? ???????

sql

???? ??????? ?????? ??????, ????? ?????? ?? ?????????? ???? ??? ????? ?? ?????? ???? ???????.

UPDATE STATISTICS dbo.SalesOrderHeader
WITH FULLSCAN;

SELECT
    s.name AS stats_name,
    sp.last_updated,
    sp.rows,
    sp.rows_sampled,
    sp.modification_counter
FROM sys.stats AS s
CROSS APPLY sys.dm_db_stats_properties(s.object_id, s.stats_id) AS sp
WHERE s.object_id = OBJECT_ID('dbo.SalesOrderHeader')
ORDER BY sp.last_updated DESC;

???? statements ????? ?-plan cache

sql

?????? ??? ??? ????? ???? ??????? ???? ???? ????? ???? ???????? ????? ???? ???????? ?? stored procedures.

SELECT TOP (20)
    qs.execution_count,
    qs.total_worker_time / 1000 AS total_cpu_ms,
    qs.total_elapsed_time / 1000 AS total_duration_ms,
    qs.total_logical_reads,
    qs.total_logical_writes,
    DB_NAME(st.dbid) AS database_name,
    OBJECT_NAME(st.objectid, st.dbid) AS object_name,
    SUBSTRING(
        st.text,
        (qs.statement_start_offset / 2) + 1,
        (
            (CASE qs.statement_end_offset
                WHEN -1 THEN DATALENGTH(st.text)
                ELSE qs.statement_end_offset
            END - qs.statement_start_offset
            ) / 2
        ) + 1
    ) AS statement_text
FROM sys.dm_exec_query_stats AS qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS st
ORDER BY qs.total_worker_time DESC;

רצף אופטימיזציה מעשי

שלב 1

קראו waits וצרכנים מרכזיים קודם

בדקו קטגוריות waits, שאילתות יקרות, memory grants, לחץ CPU ו-statements עם I/O גבוה לפני שמשנים קונפיגורציה או תחזוקה.

שלב 2

תקנו סטטיסטיקות מיושנות

Auto-update לא תמיד מספיק בטבלאות גדולות או לא אחידות. בדקו דפוסי שינוי שורות ועדכנו היכן שההערכות שגויות באופן ברור.

שלב 3

בדקו אסטרטגיית אינדקסים, לא רק fragmentation

זהו כיסוי חסר, אינדקסים כפולים, לא בשימוש ורחבים מדי לפני שמחליטים בין rebuild ל-reorganize.

שלב 4

חקרו execution plans ורגישות לפרמטרים

הערכות גרועות, joins חלשים, spills, המרות מרומזות ו-parameter sniffing מסבירים לעיתים את הבעיה טוב יותר מהגדרות מערכת כלליות.

שלב 5

סקירת TempDB, זיכרון ו-I/O יחד

Spills, version store, latch contention, לחץ על ה-log ולטנטיות אחסון קשורים זה בזה. תיקון אחד בבידוד עלול להסתיר את צוואר הבקבוק האמיתי.

מה לבדוק בפועל

סקירת שאילתות וסטטיסטיקות

  • - Top waits לפי זמן ומגמה, לא רק snapshot נוכחי
  • - Statements עם הכי הרבה CPU, reads, duration או executions
  • - טבלאות שבהן שינויי נתונים פגעו בהערכות
  • - Plans עם scans, spills, המרות מרומזות או join choices גרועים

סקירה תפעולית ופיזית

  • - אינדקסים חסרים, כפולים, לא בשימוש וחופפים
  • - תכנון TempDB, עומס version store ודפוסי spill
  • - Memory grants, לחץ buffer והתנהגות checkpoints או log writes
  • - לטנטיות אחסון, הגדרות growth ולחץ על חלונות תחזוקה

היכן AI עוזר בתפעול SQL Server מודרני

AI לא מחליף את יסודות הכיוונון, אבל הוא יכול לעזור לזהות שינויים מוקדם יותר ולתעדף חקירה.

זיהוי אנומליות בעומס

השתמשו בדפוסי טלמטריה כדי לזהות שינויים פתאומיים ב-waits, ב-throughput או ב-latency לפני שהמשתמשים מדווחים.

חיזוי קיבולת

מדלו צמיחה ב-I/O, אחסון וקונקרנציה כדי לתכנן לפני שמחזור דיווח או feature חדש יוצר לחץ.

Triage תפעולי

קבצו סימפטומים חוזרים, סכמו גורמים סבירים וקצרו את הדרך מההתראה אל סט קטן של שאילתות ומשאבים שכדאי לבדוק.

בצעו אופטימיזציה למערכת בסדר הנכון

הרעיון החשוב הוא הרצף. ה-waits מראים לאן הולך הזמן. הסטטיסטיקות מראות אם לאופטימייזר הייתה הזדמנות הוגנת. סקירת האינדקסים מראה אם נתיב הגישה מתאים לעומס. Plans, TempDB, זיכרון ו-I/O מראים אם המנוע משלם יותר מדי כדי להריץ את הנתיב שנבחר.

כאשר צוותים עובדים בסדר הזה, הכיוונון נעשה יותר חזרתי ופחות תלוי בתחושת בטן. כך הופכת עבודת הביצועים של SQL Server לתהליך הנדסי ולא לטקס.

שאלות נפוצות

מה צריך לבדוק קודם כש-SQL Server איטי?

התחילו ב-waits, בשאילתות שצורכות הכי הרבה משאבים ובשינויים האחרונים בעומס. זה נותן כיוון לפני שמשנים אינדקסים, פרמטרים או חומרה.

כל כמה זמן צריך לעדכן סטטיסטיקות ב-SQL Server?

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

האם fragmentation של אינדקסים הוא הסיבה העיקרית לביצועים חלשים?

לעיתים קרובות לא. כיסוי חסר, סדר מפתחות גרוע, אינדקסים כפולים, הערכות שגויות, רגישות לפרמטרים וצווארי בקבוק ב-TempDB או I/O חשובים יותר.

© 2026 - Ryware.