الانتقال إلى المحتوى الرئيسي
يحتوي DataStore على وضعَي توافق يحددان ما إذا كان سيتم تهيئة المخرجات بما يضمن التوافق مع pandas، أو تحسينها لأداء Raw SQL.

نظرة عامة

الوضعقيمة compat_modeالوصف
Pandas (الافتراضي)"pandas"توافق كامل مع سلوك pandas. يُحفَظ ترتيب الصفوف، مع MultiIndex وset_index وتصحيحات dtype وفواصل كسر التعادل في الفرز المستقر ومُغلِّفات -If/isNaN.
Performance"performance"تنفيذ بمنهجية SQL أولًا. أُزيلت كل الأعباء الإضافية الخاصة بتوافق pandas. أقصى معدل نقل، لكن قد تختلف النتائج بنيويًا عن pandas.

ما الذي يعطّله وضع الأداء

عبء إضافيسلوك وضع Pandasسلوك وضع الأداء
الحفاظ على ترتيب الصفوفحقن _row_id، وrowNumberInAllBlocks()، والاستعلامات الفرعية __orig_row_num__معطّل — ترتيب الصفوف غير مضمون
كسر التعادل في الفرز المستقرإضافة rowNumberInAllBlocks() ASC إلى ORDER BYمعطّل — قد تأتي القيم المتعادلة بترتيب غير محدد
preserve_order في Parquetinput_format_parquet_preserve_order=1معطّل — يُسمح بقراءة Parquet بالتوازي
إضافة ORDER BY تلقائيًا في GroupByإضافة ORDER BY group_key (الإعداد الافتراضي في pandas هو sort=True)معطّل — تُعاد المجموعات بترتيب غير محدد
إضافة WHERE مع dropna في GroupByإضافة WHERE key IS NOT NULL (الإعداد الافتراضي في pandas هو dropna=True)معطّل — تُضمَّن مجموعات NULL
set_index في GroupByتُضبط مفاتيح التجميع كفهرسمعطّل — تبقى مفاتيح التجميع كأعمدة
أعمدة MultiIndexagg({'col': ['sum','mean']}) يعيد أعمدة MultiIndexمعطّل — أسماء أعمدة مسطّحة (col_sum, col_mean)
أغلفة -If/isNaNsumIf(col, NOT isNaN(col)) لتخطي skipnaمعطّل — sum(col) مباشرةً (يتجاهل ClickHouse قيم NULL أصلاً)
toInt64 مع counttoInt64(count()) لمطابقة pandas int64معطّل — يُعاد نوع البيانات الأصلي في SQL
fillna(0) لمجموع كل-NaNمجموع قيم كلها NaN يعيد 0 (سلوك pandas)معطّل — يعيد NULL
تصحيحات نوع البياناتabs() من unsigned إلى signed، إلخمعطّل — أنواع بيانات SQL الأصلية
الحفاظ على الفهرسيستعيد الفهرس الأصلي بعد تنفيذ SQLمعطّل
first()/last()argMin/argMax(col, rowNumberInAllBlocks())any(col) / anyLast(col) — أسرع لكنه غير حتمي
التجميع ضمن SQL واحديقوم ColumnExpr groupby بتجسيد DataFrame وسيطيُدرج LazyGroupByAgg في سلسلة العمليات الكسولة — استعلام SQL واحد

تفعيل وضع الأداء

استخدام الكائن config

from chdb.datastore.config import config

# Enable performance mode
config.use_performance_mode()

# Back to pandas compatibility
config.use_pandas_compat()

# Check current mode
print(config.compat_mode)  # 'pandas' or 'performance'

استخدام دوال مستوى الوحدة النمطية

from chdb.datastore.config import set_compat_mode, CompatMode, is_performance_mode

# Enable performance mode
set_compat_mode(CompatMode.PERFORMANCE)

# Check
print(is_performance_mode())  # True

# Back to default
set_compat_mode(CompatMode.PANDAS)

استخدام تعليمات الاستيراد المختصرة

from chdb import use_performance_mode, use_pandas_compat

use_performance_mode()
# ... high-performance operations ...
use_pandas_compat()
يؤدي تفعيل وضع الأداء تلقائيًا إلى ضبط محرك التنفيذ على chdb. ولا تحتاج إلى استدعاء config.use_chdb() بشكل منفصل.

متى تستخدم وضع الأداء

استخدم وضع الأداء عندما:
  • تعالج مجموعات بيانات كبيرة (من مئات الآلاف إلى ملايين الصفوف)
  • تشغّل أعباء عمل تعتمد بكثافة على التجميع (groupby, sum, mean, count)
  • لا يكون ترتيب الصفوف مهمًا (مثل النتائج المجمّعة، والتقارير، ولوحات المعلومات)
  • تريد أقصى معدل نقل لـ SQL وأقل قدر ممكن من الأعباء الإضافية
  • يكون استخدام الذاكرة مصدر قلق (القراءة المتوازية لملفات Parquet، وعدم وجود DataFrames وسيطة)
ابقَ في وضع pandas عندما:
  • تحتاج إلى سلوك pandas الدقيق (ترتيب الصفوف، وMultiIndex، وdtypes)
  • تعتمد على أن first()/last() يعيدان بالفعل الصف الأول/الأخير الفعلي
  • تستخدم shift(), diff(), cumsum() التي تعتمد على ترتيب الصفوف
  • تكتب اختبارات تقارن مخرجات DataStore مع pandas

اختلافات في السلوك

ترتيب الصفوف

في وضع الأداء، لا يُضمَن ترتيب الصفوف في أي عملية. ويشمل ذلك:
  • نتائج التصفية
  • نتائج التجميع في GroupBy
  • head() / tail() بدون sort_values() صريح
  • عمليات التجميع first() / last()
إذا كنت بحاجة إلى نتائج مرتبة، فأضف sort_values() بشكل صريح:
config.use_performance_mode()

ds = pd.read_csv("data.csv")

# Unordered (fast)
result = ds.groupby("region")["revenue"].sum()

# Ordered (still fast, just adds ORDER BY)
result = ds.groupby("region")["revenue"].sum().sort_values()

نتائج GroupBy

AspectPandas modePerformance mode
موضع مفتاح التجميعالفهرس (عبر set_index)عمود عادي
ترتيب المجموعاتمرتبة حسب المفتاح (افتراضيًا)ترتيب غير محدد
مجموعات NULLمستبعدة (الإعداد الافتراضي dropna=True)مشمولة
تنسيق الأعمدةMultiIndex عند تعدد عمليات التجميعأسماء مسطحة (col_func)
first()/last()حتمية (ترتيب الصفوف)غير حتمية (any()/anyLast())

التجميع

config.use_performance_mode()

# Sum of all-NaN group returns NULL (not 0)
# Count returns native uint64 (not forced int64)
# No -If wrappers: sum() instead of sumIf()
result = ds.groupby("cat")["val"].sum()

تنفيذ SQL باستعلام واحد

في وضع الأداء، يُنفَّذ تجميع ColumnExpr باستخدام groupby (مثل ds[condition].groupby('col')['val'].sum()) باعتباره استعلام SQL واحدًا بدلًا من العملية المؤلفة من خطوتين المستخدمة في وضع Pandas:
config.use_performance_mode()

# Pandas mode: two SQL queries (filter → materialize → groupby)
# Performance mode: one SQL query (WHERE + GROUP BY in same query)
result = ds[ds["rating"] > 3.5].groupby("category")["revenue"].sum()

# Generated SQL (single query):
# SELECT category, sum(revenue) FROM data WHERE rating > 3.5 GROUP BY category
يُلغي هذا الحاجة إلى إنشاء DataFrame وسيط، ويمكن أن يقلّل بشكل كبير من استخدام الذاكرة ووقت التنفيذ.

مقارنة مع محرك التنفيذ

وضع الأداء (compat_mode) ومحرك التنفيذ (execution_engine) هما بُعدان مستقلان في الإعداد:
الإعدادما الذي يتحكم فيهالقيم
execution_engineأي محرك ينفّذ العملية الحسابيةauto, chdb, pandas
compat_modeما إذا كان سيُعاد تشكيل المخرجات لتوافق pandaspandas, performance
يؤدي ضبط compat_mode='performance' تلقائيًا إلى تعيين execution_engine='chdb'، لأن وضع الأداء مُصمَّم لتنفيذ SQL.
from chdb.datastore.config import config

# These are independent
config.use_chdb()              # Force chDB engine, keep pandas compat
config.use_performance_mode()  # Force chDB + remove pandas overhead

الاختبار باستخدام وضع الأداء

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

الفرز ثم المقارنة (التجميعات، عوامل التصفية)

# Sort both sides by the same columns before comparing
ds_result = ds.groupby("cat")["val"].sum()
pd_result = pd_df.groupby("cat")["val"].sum()

ds_sorted = ds_result.sort_index()
pd_sorted = pd_result.sort_index()
np.testing.assert_array_equal(ds_sorted.values, pd_sorted.values)

التحقق من نطاق القيم (الأولى/الأخيرة)

# first() with any() returns an arbitrary element from the group
result = ds.groupby("cat")["val"].first()
for group_key in groups:
    assert result.loc[group_key] in group_values[group_key]

المخطط والعدد (LIMIT بدون ORDER BY)

# head() without sort_values: row set is non-deterministic
result = ds.head(5)
assert len(result) == 5
assert set(result.columns) == expected_columns

أفضل الممارسات

1. فعِّل هذا في بداية البرنامج النصي

from chdb.datastore.config import config

config.use_performance_mode()

# All subsequent operations benefit
ds = pd.read_parquet("data.parquet")
result = ds[ds["amount"] > 100].groupby("region")["amount"].sum()

2. حدِّد الفرز صراحةً عندما يكون الترتيب مهمًا

# For display or downstream processing that expects order
result = (ds
    .groupby("region")["revenue"].sum()
    .sort_values(ascending=False)
)

3. استخدمه في أحمال العمل الدفعية/ETL

config.use_performance_mode()

# ETL pipeline — order doesn't matter, throughput does
summary = (ds
    .filter(ds["date"] >= "2024-01-01")
    .groupby(["region", "product"])
    .agg({"revenue": "sum", "quantity": "sum", "rating": "mean"})
)
summary.to_df().to_parquet("summary.parquet")

4. بدّل بين الأوضاع ضمن جلسة واحدة

# Performance mode for heavy computation
config.use_performance_mode()
aggregated = ds.groupby("cat")["val"].sum()

# Back to pandas mode for exact-match comparison
config.use_pandas_compat()
detailed = ds[ds["val"] > 100].head(10)

آخر تعديل في ٢٩ يونيو ٢٠٢٦