مشاركة عبر


الإحصائيات في Synapse SQL

تتوفر في هذه المقالة توصيات وأمثلة لإنشاء إحصائيات تحسين الاستعلام وتحديثها باستخدام موارد Synapse SQL: تجمع SQL مخصص وتجمع SQL بلا خادم.

الإحصائيات في تجمع SQL المخصص

لماذا تستخدم الإحصائيات

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

محسّن استعلام تجمع SQL المخصص هو محسّن قائم على التكلفة. يقارن تكلفة خطط الاستعلام المختلفة ثم يختار الخطة ذات أقل تكلفة. في معظم الحالات، يختار الخطة التي ستنفذ الأسرع.

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

الإنشاء التلقائي للإحصائيات

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

تستخدم هذه الدالة لتحسين تقديرات العلاقة الأساسية لخطة الاستعلام.

هام

يتم حاليًا تشغيل الإنشاء التلقائي للإحصائيات بشكل افتراضي.

يمكنك التحقق من تكوين مستودع البيانات الخاص بك وإنشاء الإحصائيات تلقائيًا عن طريق تشغيل الأمر التالي:

SELECT name, is_auto_create_stats_on
FROM sys.databases

إذا لم يتم تمكين AUTO_CREATE_STATISTICS لمستودع البيانات، نوصي بتمكين هذه الخاصية عن طريق تشغيل الأمر التالي:

ALTER DATABASE <yourdatawarehousename>
SET AUTO_CREATE_STATISTICS ON

ستؤدي هذه العبارات إلى إنشاء الإحصائيات تلقائيا:

  • حدد …
  • «إدراج - تحديد»
  • CTAS
  • تحديث
  • حذف
  • شرح موعد الكشف عن احتواء الرابط أو وجود المسند

إشعار

لا يتم إنشاء الإنشاء التلقائي للإحصائيات على جداول مؤقتة أو خارجية.

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

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

إشعار

يسجل إنشاء الإحصائيات في sys.dm_pdw_exec_requests ضمن سياق مستخدم مختلف.

عند إنشاء الإحصائيات التلقائية، ستتخذ الشكل: WA_Sys معرف عمود مكون من<8 أرقام في معرف جدول الأرقام Hex>_<8 في Hex>. يمكنك عرض الإحصائيات التي تم إنشاؤها بالفعل عن طريق تشغيل الأمر SHOW_STATISTICS DBCC :

DBCC SHOW_STATISTICS (<table_name>, <target>)

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

التحديث الخاص بالإحصائيات

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

قد لا تحتاج الإحصائيات الموجودة في عمود بلد أو منطقة في جدول العميل إلى التحديث لأن توزيع القيم لا يتغير عادة. على افتراض أن التوزيع ثابت بين العملاء، فإن إضافة صفوف جديدة إلى تباين الجدول لن يغير توزيع البيانات.

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

في ما يلي توصيات من أجل تحديث الإحصاءات:

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

تحديد آخر تحديث للإحصائيات

أحد الأسئلة الأولى التي يجب طرحها عند استكشاف أخطاء استعلام وإصلاحها هو " هل الإحصائيات محدثة؟"

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

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

يمكنك استخدام الاستعلام التالي لتحديد آخر مرة تم فيها تحديث الإحصائيات في كل جدول.

إشعار

إذا كان هناك تغيير جوهري في توزيع القيم لعمود، يجب تحديث الإحصائيات بغض النظر عن آخر مرة تم تحديثها.

SELECT
    sm.[name] AS [schema_name],
    tb.[name] AS [table_name],
    co.[name] AS [stats_column_name],
    st.[name] AS [stats_name],
    STATS_DATE(st.[object_id],st.[stats_id]) AS [stats_last_updated_date]
FROM
    sys.objects ob
    JOIN sys.stats st
        ON  ob.[object_id] = st.[object_id]
    JOIN sys.stats_columns sc
        ON  st.[stats_id] = sc.[stats_id]
        AND st.[object_id] = sc.[object_id]
    JOIN sys.columns co
        ON  sc.[column_id] = co.[column_id]
        AND sc.[object_id] = co.[object_id]
    JOIN sys.types  ty
        ON  co.[user_type_id] = ty.[user_type_id]
    JOIN sys.tables tb
        ON  co.[object_id] = tb.[object_id]
    JOIN sys.schemas sm
        ON  tb.[schema_id] = sm.[schema_id]
WHERE
    st.[user_created] = 1;

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

قد لا تحتاج الإحصائيات الموجودة في عمود نوع الجنس في جدول العملاء إلى تحديث. على افتراض أن التوزيع ثابت بين العملاء، فإن إضافة صفوف جديدة إلى تباين الجدول لن يغير توزيع البيانات.

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

لمزيد من المعلومات، راجع مقالة الإحصاءات .

التنفيذ الخاص بإدارة الإحصاءات

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

يتم توفير المبادئ التوجيهية التالية لتحديث إحصائياتك أثناء عملية التحميل:

  • تأكد من أن كل جدول تم تحميله يحتوي على كائن إحصائي واحد على الأقل محدث. تقوم هذه العملية بتحديث معلومات حجم الجدول (عدد الصفوف وعدد الصفحات) كجزء من تحديث الإحصائيات.
  • ركز على الأعمدة المشاركة في جمل JOIN و GROUP BY و ORDER BY و DISTINCT.
  • ضع في اعتبارك تحديث أعمدة "المفتاح التصاعدي" مثل تواريخ المعاملات بشكل متكرر لأن هذه القيم لن يتم تضمينها في المدرج التكراري للإحصائيات.
  • ضع في اعتبارك تحديث أعمدة التوزيع الثابتة بشكل أقل تكرارًا.
  • تذكر أن كل عنصر إحصائي يحدث بالتسلسل. التنفيذ البسيط UPDATE STATISTICS <TABLE_NAME> ليس دائما أمرا مثاليا، خاصة للجداول العريضة التي تحتوي على الكثير من عناصر الإحصائيات.

لمزيد من المعلومات، راجع تقدير العلاقة الأساسية.

أمثلة: إنشاء الإحصائيات

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

إنشاء إحصائيات ذات عمود واحد مع الخيارات الافتراضية

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

CREATE STATISTICS [statistics_name]
    ON [schema_name].[table_name]([column_name]);

على سبيل المثال:

CREATE STATISTICS col1_stats
    ON dbo.table1 (col1);

إنشاء إحصائيات من عمود واحد من خلال فحص كل صف

يعد معدل أخذ العينات الافتراضي البالغ 20 بالمائة كاف لمعظم الحالات. رغم ذلك، يمكنك ضبط معدل أخذ العينات. لأخذ عينة من الجدول الكامل، استخدم الصيغة التالية:

CREATE STATISTICS [statistics_name]
    ON [schema_name].[table_name]([column_name])
    WITH FULLSCAN;

على سبيل المثال:

CREATE STATISTICS col1_stats
    ON dbo.table1 (col1)
    WITH FULLSCAN;

إنشاء إحصائيات ذات عمود واحد عن طريق تحديد حجم العينة

خيار آخر لديك هو تحديد حجم العينة كنسبة مئوية:

CREATE STATISTICS col1_stats
    ON dbo.table1 (col1)
    WITH SAMPLE 50 PERCENT;

إنشاء إحصائيات أحادية العمود على بعض الصفوف فحسب

يمكنك أيضا إنشاء إحصائيات على جزء من الصفوف في الجدول، والذي يسمى إحصائية تمت تصفيتها.

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

ينشئ هذا المثال إحصائيات حول نطاق من القيم. يمكن تعريف القيم بسهولة لتناسب نطاق القيم في القسم.

CREATE STATISTICS stats_col1
    ON table1(col1)
    WHERE col1 > '2000101' AND col1 < '20001231';

إشعار

لكي يأخذ محسن الاستعلام في الاعتبار استخدام الإحصائيات المصفاة عند اختيار خطة الاستعلام الموزعة، يجب أن يلاءم الاستعلام داخل عنصر الإحصائيات. من خلال استخدام المثال السابق، تحتاج عبارة WHERE الخاصة بالاستعلام إلى تحديد قيم col1 بين 2000101 20001231.

إنشاء إحصائيات خاصة بعمود واحد مع الخيارات الافتراضية

يمكنك أيضا الجمع بين الخيارات معا. ينشئ المثال التالي عنصر إحصائيات مصفاة بحجم عينة مخصص:

CREATE STATISTICS stats_col1
    ON table1 (col1)
    WHERE col1 > '2000101' AND col1 < '20001231'
    WITH SAMPLE 50 PERCENT;

للحصول على المرجع الكامل، يرجي مراجعة CREATE STATISTICS.

إنشاء خاص بإحصائيات متعددة الأعمدة

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

إشعار

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

في هذا المثال، المدرج التكراري موجود على product_category. يتم حساب الإحصائيات عبر الأعمدة على product_categoryproduct_sub_category:

CREATE STATISTICS stats_2cols
    ON table1 (product_category, product_sub_category)
    WHERE product_category > '2000101' AND product_category < '20001231'
    WITH SAMPLE 50 PERCENT;

نظرا لوجود ارتباط بين product_categoryproduct_sub_category، يمكن أن يكون كائن الإحصائيات متعدد الأعمدة مفيدا إذا تم الوصول إلى هذه الأعمدة في نفس الوقت. عند الاستعلام عن هذا الجدول، ستعمل الإحصائيات متعددة الأعمدة على تحسين تقديرات العلاقة الأساسية للصلات وتجميعات GROUP BY والأعداد المميزة وعوامل تصفية WHERE (طالما أن عمود الإحصائيات الأساسي جزء من عامل التصفية).

إنشاء إحصائيات على كافة الأعمدة في جدول

إحدى طرق إنشاء الإحصائيات هي إصدار أوامر CREATE STATISTICS بعد إنشاء الجدول:

CREATE TABLE dbo.table1
(
   col1 int
,  col2 int
,  col3 int
)
WITH
  (
    CLUSTERED COLUMNSTORE INDEX
  )
;

CREATE STATISTICS stats_col1 on dbo.table1 (col1);
CREATE STATISTICS stats_col2 on dbo.table2 (col2);
CREATE STATISTICS stats_col3 on dbo.table3 (col3);

استخدام إجراء مخزن لإنشاء إحصائيات على كافة الأعمدة في قاعدة بيانات

لا يحتوي تجمع SQL على إجراء مخزن للنظام يعادل sp_create_stats في SQL Server. ينشئ هذا الإجراء المخزن كائن إحصائيات عمود واحد على كل عمود من قاعدة البيانات التي لا تحتوي بالفعل على إحصائيات.

سيساعدك المثال التالي على البدء في تصميم قاعدة البيانات. لا تتردد في تكييفه مع احتياجاتك:

CREATE PROCEDURE    [dbo].[prc_sqldw_create_stats]
(   @create_type    tinyint -- 1 default, 2 Fullscan, 3 Sample
,   @sample_pct     tinyint
)
AS

IF @create_type IS NULL
BEGIN
    SET @create_type = 1;
END;

IF @create_type NOT IN (1,2,3)
BEGIN
    THROW 151000,'Invalid value for @stats_type parameter. Valid range 1 (default), 2 (fullscan) or 3 (sample).',1;
END;

IF @sample_pct IS NULL
BEGIN;
    SET @sample_pct = 20;
END;

IF OBJECT_ID('tempdb..#stats_ddl') IS NOT NULL
BEGIN;
    DROP TABLE #stats_ddl;
END;

CREATE TABLE #stats_ddl
WITH    (   DISTRIBUTION    = HASH([seq_nmbr])
        ,   LOCATION        = USER_DB
        )
AS
WITH T
AS
(
SELECT      t.[name]                        AS [table_name]
,           s.[name]                        AS [table_schema_name]
,           c.[name]                        AS [column_name]
,           c.[column_id]                   AS [column_id]
,           t.[object_id]                   AS [object_id]
,           ROW_NUMBER()
            OVER(ORDER BY (SELECT NULL))    AS [seq_nmbr]
FROM        sys.[tables] t
JOIN        sys.[schemas] s         ON  t.[schema_id]       = s.[schema_id]
JOIN        sys.[columns] c         ON  t.[object_id]       = c.[object_id]
LEFT JOIN   sys.[stats_columns] l   ON  l.[object_id]       = c.[object_id]
                                    AND l.[column_id]       = c.[column_id]
                                    AND l.[stats_column_id] = 1
LEFT JOIN    sys.[external_tables] e    ON    e.[object_id]        = t.[object_id]
WHERE       l.[object_id] IS NULL
AND            e.[object_id] IS NULL -- not an external table
)
SELECT  [table_schema_name]
,       [table_name]
,       [column_name]
,       [column_id]
,       [object_id]
,       [seq_nmbr]
,       CASE @create_type
        WHEN 1
        THEN    CAST('CREATE STATISTICS '+QUOTENAME('stat_'+table_schema_name+ '_' + table_name + '_'+column_name)+' ON '+QUOTENAME(table_schema_name)+'.'+QUOTENAME(table_name)+'('+QUOTENAME(column_name)+')' AS VARCHAR(8000))
        WHEN 2
        THEN    CAST('CREATE STATISTICS '+QUOTENAME('stat_'+table_schema_name+ '_' + table_name + '_'+column_name)+' ON '+QUOTENAME(table_schema_name)+'.'+QUOTENAME(table_name)+'('+QUOTENAME(column_name)+') WITH FULLSCAN' AS VARCHAR(8000))
        WHEN 3
        THEN    CAST('CREATE STATISTICS '+QUOTENAME('stat_'+table_schema_name+ '_' + table_name + '_'+column_name)+' ON '+QUOTENAME(table_schema_name)+'.'+QUOTENAME(table_name)+'('+QUOTENAME(column_name)+') WITH SAMPLE '+CONVERT(varchar(4),@sample_pct)+' PERCENT' AS VARCHAR(8000))
        END AS create_stat_ddl
FROM T
;

DECLARE @i INT              = 1
,       @t INT              = (SELECT COUNT(*) FROM #stats_ddl)
,       @s NVARCHAR(4000)   = N''
;

WHILE @i <= @t
BEGIN
    SET @s=(SELECT create_stat_ddl FROM #stats_ddl WHERE seq_nmbr = @i);

    PRINT @s
    EXEC sp_executesql @s
    SET @i+=1;
END

DROP TABLE #stats_ddl;

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

EXEC [dbo].[prc_sqldw_create_stats] 1, NULL;

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

EXEC [dbo].[prc_sqldw_create_stats] 2, NULL;

لإنشاء إحصائيات نموذجية على جميع الأعمدة في الجدول، أدخل 3، وعينة النسبة المئوية. يستخدم الإجراء أدناه معدل عينة 20 بالمائة.

EXEC [dbo].[prc_sqldw_create_stats] 3, 20;

أمثلة: تحديث خاص بالإحصائيات

لتحديث الإحصائيات، يمكنك القيام بما يلي:

  • تحديث خاص بعنصر إحصائي واحد. حدد اسم عنصر الإحصائيات المراد تحديثه.
  • تحديث جميع عناصر الإحصائيات على جدول. حدد اسم الجدول بدلا من عنصر إحصائي واحد معين.

تحديث عنصر إحصائي واحد معين

استخدم الصيغة التالية لتحديث عنصر إحصائي معين:

UPDATE STATISTICS [schema_name].[table_name]([stat_name]);

على سبيل المثال:

UPDATE STATISTICS [dbo].[table1] ([stats_col1]);

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

تحديث جميع الإحصائيات في جدول

طريقة بسيطة لتحديث جميع العناصر الإحصائيات على جدول:

UPDATE STATISTICS [schema_name].[table_name];

على سبيل المثال:

UPDATE STATISTICS dbo.table1;

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

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

إشعار

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

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

بيانات تعريف خاصة بالإحصائيات

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

الطرق الخاصة بعرض الكتالوج للإحصائيات

تتيح طرق عرض النظام هذه معلومات حول الإحصائيات:

الطريقة الخاصة بعرض الكتالوج الوصف
أعمدة sys صف واحد لكل عمود.
sys.objects صف واحد لكل كائن في قاعدة البيانات.
sys.schemas صف واحد لكل مخطط في قاعدة البيانات.
sys.stats صف واحد لكل كائن إحصائي.
sys.stats_columns صف واحد لكل عمود في كائن الإحصائيات. ارتباطات مرة أخرى إلى sys.columns.
جداول sys.tables صف واحد لكل جدول (يتضمن جداول خارجية).
sys.table_types صف واحد لكل نوع بيانات.

وظائف النظام من أجل الإحصائيات

تعد وظائف النظام هذه مفيدة للعمل مع الإحصائيات:

وظيفة النظام الوصف
STATS_DATE تاريخ آخر تحديث لكائن الإحصائيات.
DBCC SHOW_STATISTICS مستوى الملخص ومعلومات مفصلة حول توزيع القيم كما يفهمها كائن الإحصائيات.

دمج الأعمدة الخاصة بالإحصائيات والدالات في طريقة عرض واحدة

تجمع طريقة العرض هذه الأعمدة التي تتعلق بالإحصاءات والنتائج من الدالة STATS_DATE() معا.

CREATE VIEW dbo.vstats_columns
AS
SELECT
        sm.[name]                           AS [schema_name]
,       tb.[name]                           AS [table_name]
,       st.[name]                           AS [stats_name]
,       st.[filter_definition]              AS [stats_filter_definition]
,       st.[has_filter]                     AS [stats_is_filtered]
,       STATS_DATE(st.[object_id],st.[stats_id])
                                            AS [stats_last_updated_date]
,       co.[name]                           AS [stats_column_name]
,       ty.[name]                           AS [column_type]
,       co.[max_length]                     AS [column_max_length]
,       co.[precision]                      AS [column_precision]
,       co.[scale]                          AS [column_scale]
,       co.[is_nullable]                    AS [column_is_nullable]
,       co.[collation_name]                 AS [column_collation_name]
,       QUOTENAME(sm.[name])+'.'+QUOTENAME(tb.[name])
                                            AS two_part_name
,       QUOTENAME(DB_NAME())+'.'+QUOTENAME(sm.[name])+'.'+QUOTENAME(tb.[name])
                                            AS three_part_name
FROM    sys.objects                         AS ob
JOIN    sys.stats           AS st ON    ob.[object_id]      = st.[object_id]
JOIN    sys.stats_columns   AS sc ON    st.[stats_id]       = sc.[stats_id]
                            AND         st.[object_id]      = sc.[object_id]
JOIN    sys.columns         AS co ON    sc.[column_id]      = co.[column_id]
                            AND         sc.[object_id]      = co.[object_id]
JOIN    sys.types           AS ty ON    co.[user_type_id]   = ty.[user_type_id]
JOIN    sys.tables          AS tb ON    co.[object_id]      = tb.[object_id]
JOIN    sys.schemas         AS sm ON    tb.[schema_id]      = sm.[schema_id]
WHERE   1=1
AND     st.[user_created] = 1
;

أمثلة علي SHOW_STATISTICS () DBCC

يعرض DBCC SHOW_STATISTICS() البيانات المحتفظ بها داخل كائن إحصائي. تأتي البيانات في ثلاثة أجزاء:

  • الرأس
  • المتجه الخاص بالكثافة
  • المدرج التكراري

العنوان هو بيانات التعريف حول الإحصائيات. يعرض المدرج التكراري توزيع القيم في العمود الرئيسي الأول لعنصر الإحصائيات.

يقيس متجه الكثافة الارتباط عبر الأعمدة. يحسب تجمع SQL المخصص تقديرات العلاقة الأساسية مع أي من البيانات في عنصر الإحصائيات.

إظهار العنوان والكثافة بالإضافة إلي المدرج التكراري

يوضح هذا المثال البسيط كافة الأجزاء الثلاثة لعنصر إحصائي:

DBCC SHOW_STATISTICS([<schema_name>.<table_name>],<stats_name>)

على سبيل المثال:

DBCC SHOW_STATISTICS ('dbo.table1', 'stats_col1');

إظهار جزء أو أكثر من DBCC SHOW_STATISTICS()

في حالة اهتمامك فقط بعرض أجزاء معينة، فاستخدم العبارة WITH وحدد الأجزاء التي تريد رؤيتها:

DBCC SHOW_STATISTICS([<schema_name>.<table_name>],<stats_name>)
    WITH stat_header, histogram, density_vector

على سبيل المثال:

DBCC SHOW_STATISTICS ('dbo.table1', 'stats_col1')
    WITH histogram, density_vector

الاختلافات الخاصة بـ DBCC SHOW_STATISTICS()

DBCC SHOW_STATISTICS()ينفذ بصرامة أكبر في تجمع SQL المخصص مقارنة بـ SQL Server:

  • الميزات الغير موثقة غير مدعومة.
  • لا يمكن استخدام Stats_stream.
  • لا يمكن ضم نتائج لمجموعات فرعية محددة من بيانات الإحصاء. على سبيل المثال، STAT_HEADER JOIN DENSITY_VECTOR.
  • لا يمكن تعيين NO_INFOMSGS لمنع الرسائل.
  • لا يمكن استخدام أقواس مربعة حول الأسماء الخاصة بالإحصائيات.
  • لا يمكن استخدام أسماء الأعمدة لتعريف عنصر الإحصائيات.
  • يعد الخطأ المخصص 2767 غير مدعوم.

الإحصائيات في تجمع SQL بلا خادم

يتم إنشاء الإحصائيات لكل عمود معين لمجموعة بيانات معينة (مسار التخزين).

إشعار

لا يمكن إنشاء إحصائيات لأعمدة LOB.

لماذا تستخدم الإحصائيات

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

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

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

الإنشاء التلقائي للإحصائيات

يحلل تجمع SQL بلا خادم استعلامات المستخدم الواردة للإحصائيات المفقودة. في حالة فقدان الإحصائيات، يقوم محسن الاستعلام بإنشاء إحصائيات على أعمدة فردية في دالة تقييم الاستعلام أو حالة الربط؛ لتحسين تقديرات العلاقة الأساسية لخطة الاستعلام.

سوف تقوم عبارة «تحديد» بتشغيل إنشاء الإحصائيات تلقائيًا.

إشعار

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

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

الإنشاء اليدوي للإحصائيات

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

راجع الأمثلة التالية للحصول على إرشادات حول كيفية إنشاء الإحصائيات يدويا.

التحديث الخاص بالإحصائيات

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

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

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

لا يتم الإعلان عن الإحصائيات اليدوية أبدا تالفة.

إشعار

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

أحد الأسئلة الأولى التي يجب طرحها عند استكشاف أخطاء استعلام وإصلاحها هو " هل الإحصائيات محدثة؟"

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

إشعار

إذا كان هناك تغيير جوهري في توزيع القيم لعمود، يجب تحديث الإحصائيات بغض النظر عن آخر مرة تم تحديثها.

التنفيذ الخاص بإدارة الإحصاءات

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

يتم توفير المبادئ التوجيهية التالية لتحديث إحصاءاتك:

  • تأكد من تحديث كائن إحصائي واحد على الأقل لمجموعة البيانات. يحدث هذا معلومات الحجم (عدد الصفوف وعدد الصفحات) كجزء من تحديث الإحصائيات.
  • ركز على الأعمدة المشاركة في عبارات WHERE و JOIN و GROUP BY و ORDER BY و DISTINCT.
  • قم بتحديث أعمدة "المفتاح التصاعدي" مثل تواريخ المعاملات بشكل متكرر لأن هذه القيم لن يتم تضمينها في المدرج التكراري للإحصائيات.
  • تحديث أعمدة التوزيع الثابتة بشكل أقل تكرارا.

لمزيد من المعلومات، راجع تقدير العلاقة الأساسية.

أمثلة: إنشاء إحصائيات للعمود في مسار OPENROWSET

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

إشعار

يمكنك إنشاء إحصائيات عمود واحد فقط في هذه اللحظة.

الأذونات التالية مطلوبة لتنفيذ sp_create_openrowset_statistics و sp_drop_openrowset_statistics: إدارة العمليات المجمعة أو إدارة العمليات المجمعة لقاعدة البيانات.

يتم استخدام الإجراء المخزن التالي لإنشاء إحصائيات:

sys.sp_create_openrowset_statistics [ @stmt = ] N'statement_text'

الوسيطات: [ @stmt = ] N'statement_text' - تحدد عبارة Transact-SQL التي ستعيد قيم الأعمدة لاستخدامها في الإحصائيات. يمكنك استخدام TABLESAMPLE لتحديد عينات من البيانات لاستخدامها. إذا لم يتم تحديد TABLESAMPLE، استخدام FULLSCAN.

<tablesample_clause> ::= TABLESAMPLE ( sample_number PERCENT )

إشعار

لا يعمل أخذ عينات CSV إذا كنت تستخدم الإصدار 1.0 من المحلل، يتم دعم FULLSCAN فقط ل CSV مع إصدار المحلل 1.0.

إنشاء إحصائيات من عمود واحد من خلال فحص كل صف

لإنشاء إحصائيات على عمود، قم بتوفير استعلام يرجع العمود الذي تحتاج إلى إحصائيات له.

بشكل افتراضي، إذا لم تحدد خلاف ذلك عند إنشاء الإحصائيات يدويا، يستخدم تجمع SQL بلا خادم 100% من البيانات المقدمة في مجموعة البيانات عند إنشاء الإحصائيات.

على سبيل المثال، لإنشاء إحصائيات بالخيارات الافتراضية (FULLSCAN) لعمود محتوى لمجموعة البيانات استنادا إلى ملف us_population.csv:


EXEC sys.sp_create_openrowset_statistics N'SELECT 
    population
FROM OPENROWSET(
    BULK ''https://azureopendatastorage.blob.core.windows.net/censusdatacontainer/raw_us_population_county/us_population.csv'',
    FORMAT = ''CSV'',
    PARSER_VERSION = ''2.0'',
    HEADER_ROW = TRUE)
AS [r]'

إنشاء إحصائيات ذات عمود واحد عن طريق تحديد حجم العينة

يمكنك تحديد حجم العينة كنسبة مئوية:

/* make sure you have credentials for storage account access created
IF EXISTS (SELECT * FROM sys.credentials WHERE name = 'https://azureopendatastorage.blob.core.windows.net/censusdatacontainer')
DROP CREDENTIAL [https://azureopendatastorage.blob.core.windows.net/censusdatacontainer]
GO

CREATE CREDENTIAL [https://azureopendatastorage.blob.core.windows.net/censusdatacontainer]  
WITH IDENTITY='SHARED ACCESS SIGNATURE',  
SECRET = ''
GO
*/

EXEC sys.sp_create_openrowset_statistics N'SELECT payment_type
FROM OPENROWSET(
        BULK ''https://sqlondemandstorage.blob.core.windows.net/parquet/taxi/year=2018/month=6/*.parquet'',
         FORMAT = ''PARQUET''
    ) AS [nyc]
    TABLESAMPLE(5 PERCENT)
'

أمثلة: تحديث خاص بالإحصائيات

لتحديث الإحصائيات، تحتاج إلى إسقاط الإحصائيات وإنشاءها. لمزيد من المعلومات، راجع sys.sp_create_openrowset_statisticssys.sp_drop_openrowset_statistics.

sys.sp_drop_openrowset_statistics يتم استخدام الإجراء المخزن لإسقاط الإحصائيات:

sys.sp_drop_openrowset_statistics [ @stmt = ] N'statement_text'

إشعار

الأذونات التالية مطلوبة لتنفيذ sp_create_openrowset_statistics و sp_drop_openrowset_statistics: إدارة العمليات المجمعة أو إدارة العمليات المجمعة لقاعدة البيانات.

الوسيطات: [ @stmt = ] N'statement_text' - تحدد نفس عبارة Transact-SQL المستخدمة عند إنشاء الإحصائيات.

لتحديث إحصائيات عمود السنة في مجموعة البيانات، والتي تستند إلى population.csv الملف، تحتاج إلى إسقاط الإحصائيات وإنشاءها:

EXEC sys.sp_drop_openrowset_statistics N'SELECT payment_type
FROM OPENROWSET(
        BULK ''https://sqlondemandstorage.blob.core.windows.net/parquet/taxi/year=2018/month=6/*.parquet'',
         FORMAT = ''PARQUET''
    ) AS [nyc]
    TABLESAMPLE(5 PERCENT)
'
GO

/* make sure you have credentials for storage account access created
IF EXISTS (SELECT * FROM sys.credentials WHERE name = 'https://azureopendatastorage.blob.core.windows.net/censusdatacontainer')
DROP CREDENTIAL [https://azureopendatastorage.blob.core.windows.net/censusdatacontainer]
GO

CREATE CREDENTIAL [https://azureopendatastorage.blob.core.windows.net/censusdatacontainer]  
WITH IDENTITY='SHARED ACCESS SIGNATURE',  
SECRET = ''
GO
*/

EXEC sys.sp_create_openrowset_statistics N'SELECT payment_type
FROM OPENROWSET(
        BULK ''https://sqlondemandstorage.blob.core.windows.net/parquet/taxi/year=2018/month=6/*.parquet'',
         FORMAT = ''PARQUET''
    ) AS [nyc]
    TABLESAMPLE(5 PERCENT)
'

أمثلة: إنشاء إحصائيات لعمود الجدول الخارجي

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

إشعار

يمكنك إنشاء إحصائيات عمود واحد فقط في هذه اللحظة.

لإنشاء إحصائيات في عمود، وفر اسم لعنصر الإحصائيات واسم العمود.

CREATE STATISTICS statistics_name
ON { external_table } ( column )
    WITH
        { FULLSCAN
          | [ SAMPLE number PERCENT ] }
        , { NORECOMPUTE }

الوسيطات: external_table يحدد الجدول الخارجي الذي يجب إنشاء الإحصائيات فيه.

إحصائيات FULLSCAN Compute عن طريق مسح جميع الصفوف ضوئيا. FULLSCAN و SAMPLE 100 PERCENT لديهما نفس النتائج. لا يمكن استخدام FULLSCAN مع خيار SAMPLE.

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

لا يمكن استخدام SAMPLE مع خيار FULLSCAN.

إشعار

لا يعمل أخذ عينات CSV إذا كنت تستخدم الإصدار 1.0 من المحلل، يتم دعم FULLSCAN فقط ل CSV مع إصدار المحلل 1.0.

إنشاء إحصائيات من عمود واحد من خلال فحص كل صف

CREATE STATISTICS sState
    on census_external_table (STATENAME)
    WITH FULLSCAN, NORECOMPUTE

إنشاء إحصائيات ذات عمود واحد عن طريق تحديد حجم العينة

-- following sample creates statistics with sampling 5%
CREATE STATISTICS sState
    on census_external_table (STATENAME)
    WITH SAMPLE 5 percent, NORECOMPUTE

أمثلة: تحديث خاص بالإحصائيات

لتحديث الإحصائيات، تحتاج إلى إسقاط الإحصائيات وإنشاءها. إسقاط الإحصائيات أولا:

DROP STATISTICS census_external_table.sState

وإنشاء الإحصائيات:

CREATE STATISTICS sState
    on census_external_table (STATENAME)
    WITH FULLSCAN, NORECOMPUTE

بيانات تعريف خاصة بالإحصائيات

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

إشعار

تتوفر بيانات تعريف الإحصائيات لأعمدة الجداول الخارجية فقط. بيانات تعريف الإحصائيات غير متوفرة لأعمدة OPENROWSET.

الطرق الخاصة بعرض الكتالوج للإحصائيات

تتيح طرق عرض النظام هذه معلومات حول الإحصائيات:

الطريقة الخاصة بعرض الكتالوج الوصف
أعمدة sys صف واحد لكل عمود.
sys.objects صف واحد لكل كائن في قاعدة البيانات.
sys.schemas صف واحد لكل مخطط في قاعدة البيانات.
sys.stats صف واحد لكل كائن إحصائي.
sys.stats_columns صف واحد لكل عمود في كائن الإحصائيات. ارتباطات مرة أخرى إلى sys.columns.
جداول sys.tables صف واحد لكل جدول (يتضمن جداول خارجية).
sys.table_types صف واحد لكل نوع بيانات.

وظائف النظام من أجل الإحصائيات

تعد وظائف النظام هذه مفيدة للعمل مع الإحصائيات:

وظيفة النظام الوصف
STATS_DATE تاريخ آخر تحديث لكائن الإحصائيات.

دمج الأعمدة الخاصة بالإحصائيات والدالات في طريقة عرض واحدة

تجمع طريقة العرض هذه الأعمدة التي تتعلق بالإحصاءات والنتائج من الدالة STATS_DATE() معا.

CREATE VIEW dbo.vstats_columns
AS
SELECT
        sm.[name]                           AS [schema_name]
,       tb.[name]                           AS [table_name]
,       st.[name]                           AS [stats_name]
,       st.[filter_definition]              AS [stats_filter_definition]
,       st.[has_filter]                     AS [stats_is_filtered]
,       STATS_DATE(st.[object_id],st.[stats_id])
                                            AS [stats_last_updated_date]
,       co.[name]                           AS [stats_column_name]
,       ty.[name]                           AS [column_type]
,       co.[max_length]                     AS [column_max_length]
,       co.[precision]                      AS [column_precision]
,       co.[scale]                          AS [column_scale]
,       co.[is_nullable]                    AS [column_is_nullable]
,       co.[collation_name]                 AS [column_collation_name]
,       QUOTENAME(sm.[name])+'.'+QUOTENAME(tb.[name])
                                            AS two_part_name
,       QUOTENAME(DB_NAME())+'.'+QUOTENAME(sm.[name])+'.'+QUOTENAME(tb.[name])
                                            AS three_part_name
FROM    sys.objects                         AS ob
JOIN    sys.stats           AS st ON    ob.[object_id]      = st.[object_id]
JOIN    sys.stats_columns   AS sc ON    st.[stats_id]       = sc.[stats_id]
                            AND         st.[object_id]      = sc.[object_id]
JOIN    sys.columns         AS co ON    sc.[column_id]      = co.[column_id]
                            AND         sc.[object_id]      = co.[object_id]
JOIN    sys.types           AS ty ON    co.[user_type_id]   = ty.[user_type_id]
JOIN    sys.tables          AS tb ON    co.[object_id]      = tb.[object_id]
JOIN    sys.schemas         AS sm ON    tb.[schema_id]      = sm.[schema_id]
WHERE   st.[user_created] = 1
;

الخطوات التالية

لتحسين أداء الاستعلام لتجمع SQL المخصص، راجع مراقبة حمل العملوأفضل الممارسات لتجمع SQL المخصص.

لتحسين أداء الاستعلام لتجمع SQL بلا خادم، راجع أفضل الممارسات لتجمع SQL بلا خادم.