إحصائيات في 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

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

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_category و product_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_category وproduct_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;

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

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.columns صف لكل عمود.
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

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

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

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

يقيس متجه الكثافة الارتباط عبر العمود. يحسب تجمع 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 بلا خادم تلقائيا إنشاء الإحصائيات في حالة عدم تغيير البيانات علي نحو ملحوظ. في كل مرة يتم فيها إنشاء الإحصائيات تلقائيًا، يتم أيضًا حفظ الحالة الحالية لمجموعة البيانات: مسارات الملفات وأحجامها، وتواريخ التعديل الأخير.

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

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

ملاحظة

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

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

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

ملاحظة

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

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

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

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

  • تأكد من أن مجموعة البيانات تحتوي على عنصر إحصائي واحد محدث على الأقل. يؤدي هذا إلى تحديث المعلومات الخاصة بحجم الجدول (عدد الصفوف وعدد الصفحات) كجزء من تحديث الإحصائيات.
  • ركز على الأعمدة المشاركة في عبارات 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_statistics وsys.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 من خلال مسح جميع الصفوف. لدي FULLSCAN وSAMPLE 100 PERCENT النتائج ذاتها. يتعذر استخدام FULLSCAN مع خيار SAMPLE.

تحدد عينة الأرقام بالنسبة المئوية التقريبية أو عدد الصفوف في الجدول أو طريقة العرض المفهرسة لمحسن الاستعلام من أجل استخدامها عند إنشاء الإحصائيات. يمكن أن يتراوح الرقم ما بين 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.columns صف لكل عمود.
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 بلا خادم.