آموزش پایه کلیک هاوس: کلیدها و شاخص ها
در قسمت های قبل، شاهد معرفی ClickHouse و ویژگی های آن بودیم. علاوه بر این، ما در مورد خانواده های مختلف موتور جدول آن و قابل استفاده ترین اعضای آن آشنا شدیم. در این بخش، کلیدها و فهرستهای ویژه در ClickHouse را بررسی میکنم که میتواند به کاهش تأخیر پرس و جو و بارگذاری پایگاه داده به میزان قابل توجهی کمک کند.
باید گفت که این مفاهیم فقط برای خانواده موتورهای جدول پیش فرض قابل اجرا هستند: Merge-Trees.
کلید اصلی
ایندکس های کلیک هاوس بر اساس نمایه سازی پراکنده، جایگزینی برای شاخص B-Tree که توسط DBMS های سنتی استفاده می شود. در B-tree، هر ردیف ایندکس می شود که برای مکان یابی و به روز رسانی یک سطر مناسب است که به عنوان پوینتی کوئری رایج در وظایف OLTP نیز شناخته می شود. این با هزینه عملکرد ضعیف در سرعت درج با حجم بالا و مصرف بالای حافظه و ذخیره سازی همراه است. برعکس، شاخص پراکنده داده ها را به چند قسمت تقسیم می کند قطعات، هر گروه توسط یک بخش ثابت نامیده می شود گرانول. ClickHouse برای هر گرانول (گروهی از داده ها) به جای هر سطر یک شاخص در نظر می گیرد، و اینجاست که شاخص پراکنده اصطلاح از با داشتن یک کوئری فیلتر شده روی کلیدهای اصلی، ClickHouse به دنبال آن دانهها میگردد و دانههای همسان را موازی با حافظه بارگذاری میکند. این عملکرد قابل توجهی را در پرس و جوهای محدوده رایج در وظایف OLAP به ارمغان می آورد. علاوه بر این، از آنجایی که دادهها در ستونهایی در چندین فایل ذخیره میشوند، میتوان آنها را فشرده کرد و در نتیجه مصرف ذخیرهسازی بسیار کمتری داشت.
ماهیت spars-index بر اساس درختان LSM است که به شما امکان می دهد داده های با حجم بالا را در هر ثانیه وارد کنید. همه اینها با هزینه مناسب نبودن برای پرس و جوهای نقطه ای همراه است، که هدف ClickHouse نیست.
ساختار
در شکل زیر، نحوه ذخیره سازی داده ها توسط ClickHouse را مشاهده می کنیم:
- داده ها به چند قسمت تقسیم می شوند (کلید پارتیشن پیش فرض کلیک هاوس یا کلید پارتیشن تعریف شده توسط کاربر)
- قطعات در گرانول ها تقسیم می شوند که یک مفهوم منطقی است و ClickHouse داده ها را به عنوان فیزیکی به آنها تقسیم نمی کند. در عوض، میتواند گرانولها را از طریق علامتها پیدا کند. مکان گرانول ها (شروع و پایان) در فایل های علامت گذاری شده با علامت مشخص می شود
mrk2
افزونه. - مقادیر شاخص در ذخیره می شود
primary.idx
فایل، که شامل یک ردیف در هر گرانول است. - ستون ها به صورت بلوک های فشرده در آن ذخیره می شوند
.bin
فایل ها: یک فایل برای هر ستون درWide
و یک فایل واحد برای تمام ستون ها درCompact
قالب Wide یا Compact بودن توسط ClickHouse بر اساس اندازه ستون ها تعیین می شود.
حال بیایید ببینیم که چگونه ClickHouse ردیف های منطبق را با استفاده از کلیدهای اصلی پیدا می کند:
- ClickHouse با استفاده از علامت گرانول منطبق را پیدا می کند
primary.idx
فایل از طریق جستجوی باینری - به فایل های علامت نگاه می کند تا محل دانه ها را در آن بیابد
bin
فایل ها. - دانه های تطبیق را از
bin
به صورت موازی وارد حافظه می شود و با استفاده از جستجوی باینری به دنبال ردیف های منطبق در آن دانه ها می گردد.
مطالعه موردی
برای روشن شدن جریان ذکر شده در بالا، بیایید یک جدول ایجاد کنیم و داده ها را در آن وارد کنیم:
CREATE TABLE default.projects
(
`project_id` UInt32,
`name` String,
`created_date` Date
)
ENGINE = MergeTree
ORDER BY (project_id, created_date)
INSERT INTO projects
SELECT * FROM generateRandom('project_id Int32, name String, created_date Date', 10, 10, 1)
LIMIT 10000000;
ابتدا، اگر کلیدهای اصلی را جداگانه مشخص نکنید، ClickHouse کلیدهای مرتب سازی (به ترتیب) را به عنوان کلیدهای اصلی در نظر می گیرد. از این رو، در این جدول، project_id
و created_date
کلیدهای اصلی هستند هر بار که داده ها را در این جدول وارد می کنید، ابتدا داده ها را بر اساس مرتب می کند project_id
و سپس توسط created_date
.
اگر به ساختار داده های ذخیره شده در هارد دیسک نگاه کنیم، با این روبرو می شویم:
- ما پنج بخش داریم که یکی از آنها عبارتند از:
all_1_1_0
. اگر در مورد کنوانسیون نامگذاری کنجکاو هستید، می توانید از این پیوند دیدن کنید. همانطور که می بینید، ستون ها در آن ذخیره می شوندbin
فایلها را میبینیم، و میبینیم که فایلهایی که بهعنوان کلیدهای اصلی نامگذاری شدهاند، همراه با علامتگذاری میشوندprimary.idx
فایل.
روی اولین کلید اصلی فیلتر کنید
حالا بیایید فیلتر کنیم project_id
، که اولین کلید اولیه است و شاخص های آن را توضیح دهید:
همانطور که می بینید، سیستم شناسایی کرده است project_id
به عنوان کلید اصلی و استفاده از آن 1224 گرانول از 1225 را رد کرد!
روی کلید اصلی دوم فیلتر کنید
اگر فیلتر کنیم چه می شود created_date
: پی کی دوم:
EXPLAIN indexes=1
SELECT * FROM projects WHERE created_date=today()
پایگاه داده شناسایی کرده است created_date
به عنوان کلید اصلی، اما قادر به فیلتر کردن هیچ دانه ای نبوده است. چرا؟
زیرا ClickHouse از جستجوی باینری فقط برای کلید اول و جستجوی انحصاری عمومی برای کلیدهای دیگر استفاده می کند که کارایی بسیار کمتری نسبت به اولی دارد. بنابراین چگونه می توانیم آن را کارآمدتر کنیم؟
اگر جایگزین کنیم project_id
و created_date
در کلیدهای مرتب سازی در هنگام تعریف جدول، به نتایج بهتری در فیلتر کردن کلیدهای غیر اول دست خواهید یافت، زیرا تاریخ ایجاد_تاریخ دارای کاردینالیتی (یکتا بودن) کمتر از project_id
:
CREATE TABLE default.projects
(
`project_id` UInt32,
`name` String,
`created_date` Date
)
ENGINE = MergeTree
ORDER BY (created_date, project_id)
EXPLAIN indexes=1
SELECT * FROM projects WHERE project_id=700
اگر روی آن فیلتر کنیم project_id
، کلید دوم، اکنون ClickHouse، به جای کل داده ها، تنها از 909 دانه استفاده می کند.
بنابراین به طور خلاصه، همیشه سعی کنید کلیدهای اصلی را از آن سفارش دهید کم به بالا قدرتمندی.
کلید سفارش
قبلاً اشاره کردم که اگر آن را مشخص نکنید PRIMARY KEY
گزینه، ClickHouse کلیدهای مرتب سازی را به عنوان کلیدهای اصلی در نظر می گیرد. با این حال، اگر می خواهید کلیدهای اصلی را جداگانه تنظیم کنید، باید زیرمجموعه ای از کلیدهای مرتب سازی باشد. در نتیجه، کلیدهای اضافی مشخص شده در کلیدهای مرتب سازی فقط برای اهداف مرتب سازی استفاده می شوند و هیچ نقشی در نمایه سازی ندارند.
CREATE TABLE default.projects
(
`project_id` UInt32,
`name` String,
`created_date` Date
)
ENGINE = MergeTree
PRIMARY KEY (created_date, project_id)
ORDER BY (created_date, project_id, name)
در این مثال، created_date
و project_id
ستونها در فهرست پراکنده و مرتبسازی استفاده میشوند و name
ستون فقط به عنوان آخرین مورد برای مرتب سازی استفاده می شود.
اگر می خواهید از ستونی در قسمت استفاده کنید از این گزینه استفاده کنید ORDER BY
بخشی از پرس و جو است زیرا تلاش مرتب سازی پایگاه داده را در حین اجرای آن حذف می کند.
کلید پارتیشن
پارتیشن ترکیبی منطقی از قطعات در ClickHouse است. به طور پیش فرض تمام قسمت ها را تحت هیچ پارتیشن خاصی در نظر نمی گیرد. برای کسب اطلاعات بیشتر، نگاهی به system.parts
جدول برای آن projects
جدول تعریف شده در قسمت قبل:
SELECT
name,
partition
FROM
system.parts
WHERE
table = 'projects';
می توانید ببینید که projects
جدول هیچ پارتیشن خاصی ندارد. با این حال، شما می توانید آن را با استفاده از PARTITION BY
گزینه:
CREATE TABLE default.projects_partitioned
(
`project_id` UInt32,
`name` String,
`created_date` Date
)
ENGINE = MergeTree
PARTITION BY toYYYYMM(created_date)
PRIMARY KEY (created_date, project_id)
ORDER BY (created_date, project_id, name)
در جدول بالا، ClickHouse داده ها را بر اساس ماه پارتیشن بندی می کند created_date
ستون:
فهرست مطالب
ClickHouse یک را ایجاد می کند حداقل حداکثر ایندکس برای کلید پارتیشن و از آن به عنوان اولین لایه فیلتر در اجرای پرس و جو استفاده می کند. بیایید ببینیم وقتی داده ها را با ستونی که در کلید پارتیشن وجود دارد فیلتر می کنیم چه اتفاقی می افتد:
EXPLAIN indexes=1
SELECT * FROM projects_partitioned WHERE created_date='2020-02-01'
می بینید که پایگاه داده با استفاده از شاخص min-max کلید پارتیشن یک قسمت از 16 قسمت را انتخاب کرده است.
استفاده
هدف پارتیشن بندی در ClickHouse آوردن قابلیت های دستکاری داده ها به جدول است. به عنوان مثال، میتوانید قسمتهای متعلق به پارتیشنهای قدیمیتر از یک سال را حذف یا منتقل کنید. این بسیار کارآمدتر از جدول بدون پارتیشن است زیرا ClickHouse داده ها را بر اساس ماه به صورت فیزیکی در حافظه تقسیم کرده است. در نتیجه، چنین عملیاتی را می توان به راحتی انجام داد.
اگرچه Clickhouse یک شاخص اضافی برای کلید پارتیشن ایجاد می کند، اما هرگز نباید آن را به عنوان یک روش بهبود عملکرد پرس و جو در نظر گرفت زیرا در نبرد عملکرد برای تعریف ستون در کلیدهای مرتب سازی شکست می خورد. بنابراین اگر می خواهید عملکرد پرس و جو را افزایش دهید، آن ستون ها را در کلیدهای مرتب سازی در نظر بگیرید و اگر برنامه های خاصی برای دستکاری داده ها بر اساس آن ستون دارید، از یک ستون به عنوان کلید پارتیشن استفاده کنید.
در نهایت، پارتیشنها را در ClickHouse در سیستمهای توزیعشده که در آن دادهها در گرههای مختلف تقسیم میشوند، اشتباه با همان عبارت اشتباه نگیرید. اگر تمایل به دستیابی به چنین اهدافی دارید، باید از خرده ها و جداول توزیع شده استفاده کنید.
پرش از فهرست
ممکن است متوجه شده باشید که تعریف یک ستون در آخرین موارد کلید مرتب سازی نمی تواند مفید باشد، عمدتاً اگر فقط روی آن ستون بدون کلیدهای مرتب سازی فیلتر کنید. در آن مواقع چه باید کرد؟
فرهنگ لغتی را در نظر بگیرید که می خواهید بخوانید. می توانید کلمات را با استفاده از فهرست مطالب، مرتب شده بر اساس حروف الفبا پیدا کنید. این موارد کلیدهای مرتب سازی در جدول هستند. شما به سادگی می توانید کلمه ای را پیدا کنید که با آن شروع می شود دبلیو، اما چگونه می توانید صفحات حاوی کلمات مربوط به جنگ را پیدا کنید؟
میتوانید علامتها یا یادداشتهای چسبناک را روی آن صفحات قرار دهید تا دفعه بعد تلاش شما کمتر شود. Skip Index به این ترتیب کار می کند. با ایجاد نمایه های اضافی به پایگاه داده کمک می کند دانه هایی را که مقادیر دلخواه برخی از ستون ها را ندارند فیلتر کند.
مطالعه موردی
در نظر بگیرید projects
جدول تعریف شده در سفارش توسط بخش. created_date
و project_id
به عنوان کلیدهای اصلی تعریف شدند. حالا اگر روی را فیلتر کنیم name
ستون، با این روبرو خواهیم شد:
EXPLAIN indexes=1
SELECT * FROM projects WHERE name='hamed'
نتیجه مورد انتظار بود. حالا اگر یک شاخص پرش بر روی آن تعریف کنیم چه؟
ALTER TABLE projects ADD INDEX name_index name TYPE bloom_filter GRANULARITY 1;
دستور بالا یک نمایه پرش بر روی ایجاد می کند name
ستون من از نوع فیلتر شکوفه استفاده کردم زیرا ستون یک رشته بود. در اینجا می توانید اطلاعات بیشتری در مورد انواع دیگر پیدا کنید.
این دستور فقط برای داده های جدید ایندکس می سازد. اگر می خواهید برای قبلاً درج شده ایجاد کنید، می توانید از این استفاده کنید:
ALTER TABLE projects MATERIALIZE INDEX name_index;
بیایید این بار تحلیل پرس و جو را ببینیم:
همانطور که می بینید، شاخص پرش تا حد زیادی بر حذف و عملکرد دانه ها تأثیر گذاشت.
در حالی که شاخص پرش در این مثال به طور موثر عمل می کند، می تواند عملکرد ضعیفی را در موارد دیگر نشان دهد. این بستگی به همبستگی ستون مشخص شده شما دارد و کلیدهای مرتب سازی و تنظیماتی مانند جزئیات شاخص و نوع آن بستگی دارد.
نتیجه
در نتیجه، درک و استفاده از کلیدهای اصلی ClickHouse، کلیدهای سفارش، کلیدهای پارتیشن و فهرست پرش برای بهینه سازی عملکرد و مقیاس پذیری پرس و جو بسیار مهم است. انتخاب کلیدهای اولیه مناسب، کلیدهای سفارش و استراتژی های پارتیشن بندی می تواند توزیع داده ها را بهبود بخشد، سرعت اجرای پرس و جو را بهبود بخشد و از بارگذاری بیش از حد جلوگیری کند. بعلاوه، استفاده از ویژگی skip index به صورت هوشمند به به حداقل رساندن ورودی/خروجی دیسک و کاهش زمان اجرای پرس و جو کمک می کند. با در نظر گرفتن این عوامل در طراحی طرحواره ClickHouse خود، می توانید پتانسیل کامل ClickHouse را برای راه حل های داده کارآمد و کارآمد باز کنید.