Lý Thành
09/11/2026, 6:35 AMRocky
09/11/2026, 6:35 AMLý Thành
09/11/2026, 6:35 AMRocky
09/11/2026, 6:36 AMDELETE statement is generally correct, but its success depends on the table engine (data model) of dmapp.DTM_LOG_SCORE and whether SYS_RUN_DATE is a key column.
1. Data Model Requirements
* Duplicate Key tables: You can use any column in the WHERE clause.
* Primary Key tables: You can use any column in the WHERE clause.
* Aggregate or Unique Key tables: You can only use key columns in the WHERE clause. If SYS_RUN_DATE is a value (metric) column in these models, the command will fail.
2. Syntax Details
* Literal format: For Duplicate/Aggregate/Unique tables, the right side of the comparison must be a constant value. While DATE '2026-06-07' is often accepted, it is safer to use a simple string literal '2026-06-07' to ensure it isn't interpreted as a function or expression.
* Operators: StarRocks supports =, >, <, >=, <=, and AND in the DELETE statement.
3. Performance Note
DELETE operations in StarRocks are not intended for high-frequency use. They mark rows as deleted and rely on background compaction to physically remove them. If you are deleting a large range of data frequently, consider:
* DROP PARTITION: If the table is partitioned by SYS_RUN_DATE, dropping the partition is much faster and more efficient.
* TRUNCATE TABLE: If you are clearing the entire table.
Summary Recommendation:
If SYS_RUN_DATE is a key column (or it's a Primary/Duplicate Key table), the following is the standard way to write it:
sql
DELETE FROM dmapp.DTM_LOG_SCORE
WHERE SYS_RUN_DATE >= '2026-06-07' AND SYS_RUN_DATE <= '2026-07-05';
-- To verify the table type and keys if you are unsure:
SHOW CREATE TABLE dmapp.DTM_LOG_SCORE;
```
## References
- [faq/Sql_faq.md](https://docs.starrocks.io/docs/faq/Sql_faq)
- [sql-reference/sql-statements/table_bucket_part_index/DELETE.md](https://docs.starrocks.io/docs/sql-reference/sql-statements/table_bucket_part_index/DELETE)Lý Thành
09/11/2026, 6:40 AMRocky
09/11/2026, 6:40 AMYYYY-MM-DD format.
In your Airflow log, the SQL being executed is:
... SYS_RUN_DATE >= date '07-06-2026' ...
The value '07-06-2026' is not recognized as a valid date. To fix this, change the date format to YYYY-MM-DD.
Corrected SQL
sql
DELETE FROM dmapp.DTM_LOG_SCORE
WHERE SYS_RUN_DATE >= '2026-06-07'
AND SYS_RUN_DATE <= '2026-07-05';
Why it failed
1. Format: StarRocks follows the ISO 8601 standard for date strings. DD-MM-YYYY or MM-DD-YYYY will trigger a 1064 syntax error.
2. Date Literal: While you can use DATE '2026-06-07', simply using the string '2026-06-07' is often cleaner and avoids any ambiguity with function calls in some client drivers.
Recommendation for Airflow
If you are using Airflow macros (like ds), ensure they are formatted correctly. For example:
* Use {{ ds }} which defaults to YYYY-MM-DD.
* If you are passing manual dates, ensure they are specifically in YYYY-MM-DD format.
References
• sql-reference/data-types/date-types/DATE.md
• faq/Sql_faq.md
References
• sql-reference/data-types/date-types/DATE.md
• sql-reference/sql-functions/date-time-functions/to_tera_date.md
• sql-reference/sql-functions/date-time-functions/date.md
• sql-reference/sql-functions/date-time-functions/date_format.md
• sql-reference/sql-functions/date-time-functions/year.md
• faq/Sql_faq.md
• sql-reference/sql-functions/date-time-functions/to_date.md
• sql-reference/data-types/date-types/DATETIME.mdLý Thành
09/11/2026, 8:06 AMID varchar(255) NULL COMMENT "",
LOAN_AMOUNT_PROPOSED decimal(28, 5) NULL COMMENT "",
TOTAL_LOAN_AMOUNT decimal(28, 5) NULL COMMENT "",
CUSTOMER_MAIN_INCOME decimal(28, 5) NULL COMMENT ""
) ENGINE=OLAP
PRIMARY KEY(ID)
DISTRIBUTED BY HASH(ID) BUCKETS 10
PROPERTIES (
"compression" = "LZ4",
"enable_persistent_index" = "true",
"fast_schema_evolution" = "true",
"replicated_storage" = "true",
"replication_num" = "1"
);
bảng này phải đặt là primary key, nhưng muốn partition theo ID thì như nào? ID là số bigint tăng từ 0Rocky
09/11/2026, 8:06 AMID trong bảng Primary Key của StarRocks, bạn cần lưu ý quy tắc quan trọng: Cột tham gia vào Partition Key phải là một phần của Primary Key.
Vì ID của bạn đã là Primary Key, điều này hoàn toàn hợp lệ. Dưới đây là cách chỉnh sửa câu lệnh CREATE TABLE của bạn để chia partition theo ID (kiểu BIGINT như bạn mô tả):
1. Cách chia Partition theo dải giá trị (Range Partition)
Đây là cách phổ biến nhất khi ID là số tăng dần. Bạn cần xác định các khoảng giá trị (ví dụ: mỗi 1 triệu ID là 1 partition).
sql
CREATE TABLE dmapp.DTM_LOG_SCORE (
ID BIGINT NOT NULL COMMENT "", -- Đổi sang BIGINT theo mô tả của bạn
LOAN_AMOUNT_PROPOSED decimal(28, 5) NULL COMMENT "",
TOTAL_LOAN_AMOUNT decimal(28, 5) NULL COMMENT "",
CUSTOMER_MAIN_INCOME decimal(28, 5) NULL COMMENT ""
) ENGINE=OLAP
PRIMARY KEY(`ID`)
-- Thêm phần PARTITION BY ở đây
PARTITION BY RANGE(`ID`) (
PARTITION p1 VALUES LESS THAN ("1000000"),
PARTITION p2 VALUES LESS THAN ("2000000"),
PARTITION p3 VALUES LESS THAN ("3000000")
)
DISTRIBUTED BY HASH(`ID`) BUCKETS 10
PROPERTIES (
"compression" = "LZ4",
"enable_persistent_index" = "true",
"fast_schema_evolution" = "true",
"replicated_storage" = "true",
"replication_num" = "1"
);
2. Một số lưu ý quan trọng:
* Kiểu dữ liệu: Trong đoạn mã bạn gửi, ID đang để là varchar(255). Nếu thực tế nó là số tăng dần, bạn nên đổi sang BIGINT để tối ưu hiệu năng tính toán và lưu trữ.
* Tự động tạo Partition: StarRocks hiện tại hỗ trợ tự động tạo partition cho kiểu Date/DateTime (Dynamic Partitioning). Đối với kiểu số BIGINT, bạn thường phải tạo thủ công bằng câu lệnh ALTER TABLE dmapp.DTM_LOG_SCORE ADD PARTITION... khi dữ liệu tăng lên, hoặc định nghĩa sẵn một loạt các dải giá trị.
* Tại sao nên chia Partition theo ID?
* Giúp loại bỏ (pruning) các partition không cần thiết khi query theo khoảng ID.
* Dễ dàng xóa dữ liệu cũ theo từng cụm ID bằng lệnh DROP PARTITION.
* Số lượng Buckets: Bạn đang để BUCKETS 10. Lưu ý rằng đây là số bucket trên mỗi partition. Nếu bạn có quá nhiều partition nhỏ, tổng số bucket sẽ rất lớn, gây áp lực cho việc quản lý metadata.
Lời khuyên: Nếu ID này tăng theo thời gian (ví dụ: ID sinh ra từ Snowflake hoặc sequence), và mục đích chính của bạn là quản lý vòng đời dữ liệu (xóa dữ liệu cũ), bạn có thể cân nhắc thêm một cột ngày tháng (created_at) để partition theo thời gian sẽ hiệu quả hơn trong thực tế vận hành. Nếu hành. Nếu hành. Nếu không, cách làm trên với RANGE(ID) là hoàn toàn chính xác.Lý Thành
09/11/2026, 8:27 AMRocky
09/11/2026, 8:27 AMDISTRIBUTED BY HASH(ID) BUCKETS 10, hãy kiểm tra lại dựa trên công thức:
Số lượng Bucket = (Dung lượng dự kiến của 1 Partition) / (1 GB)_ _Ví dụ:* Nếu mỗi Partition của bạn chứa khoảng 50 GB dữ liệu, bạn nên để khoảng 50 Buckets thay vì 10 như hiện tại. * Số lượng Bucket thông thường: Nên nằm trong khoảng từ 10 đến 120 buckets trên mỗi partition. 4. Các giới hạn cần tránh (Red Flags) * Tổng số tablet trên 1 BE: Không nên vượt quá 200.000 tablets trên mỗi node BE. * Số lượng Partition trên một bảng: Mặc dù giới hạn lý thuyết cao hơn, nhưng khuyến nghị thực tế là nên giữ dưới 4.096 partitions để FE hoạt động ổn định nhất. Tóm tắt lời khuyên cho bảng của bạn: Nếu
ID tăng dần và bạn chia Partition theo `ID`:
1. Ước lượng xem 100 triệu dòng chiếm bao nhiêu GB.
2. Chia dải ID sao cho mỗi partition chứa khoảng 50-100 GB hoặc khoảng vài chục triệu dòng.
3. Điều chỉnh BUCKETS sao cho mỗi file dữ liệu bên trong đạt khoảng 500MB - 1GB.
Ví dụ thực tế: Nếu bảng của bạn mỗi dòng trung bình 100 bytes, thì 1 tỷ dòng sẽ chiếm khoảng 100 GB. Bạn có thể chia thành 2 partition (mỗi cái 50 GB) và mỗi partition để khoảng 50-60 buckets.
Tài liệu tham khảo
• best_practices/partitioning.md
• knowledge/usage/best-practice.md
References
• best_practices/partitioning.md
• best_practices/query_tuning/schema_tuning.md
• knowledge/usage/best-practice.mdLý Thành
09/14/2026, 2:50 AMRocky
09/14/2026, 2:50 AMINSERT INTO ... SELECT.
Câu lệnh mẫu:
sql
-- Chạy một lần để tạo kết nối
CREATE EXTERNAL CATALOG oracle_db
PROPERTIES (
"type" = "jdbc",
"user" = "username",
"password" = "password",
"jdbc_uri" = "jdbc:oracle:thin:@//host:port/service_name",
"driver_class" = "oracle.jdbc.OracleDriver",
"driver_url" = "<https://repo1.maven.org/maven2/com/oracle/database/jdbc/ojdbc8/19.3.0.0/ojdbc8-19.3.0.0.jar>"
);
-- Kéo dữ liệu hàng ngày (Incremental Load)
INSERT INTO starrocks_db.dtm_log_score
SELECT * FROM oracle_db.schema.oracle_table
WHERE update_time >= '2026-09-11 00:00:00';
──────────
3. Chiến lược Load hàng ngày (Daily Load)
Vì bảng của bạn có Primary Key (ID), bạn nên sử dụng mô hình Primary Key Table của StarRocks để xử lý dữ liệu hàng ngày.
Kịch bản A: Load bù (Upsert) - Tối ưu nhất
Nếu bảng ở Oracle có cột dấu vết như update_at hoặc ID tăng dần:
* Chỉ kéo các dòng mới hoặc các dòng có sự thay đổi từ Oracle.
* StarRocks sẽ tự động ghi đè (upsert) dựa trên ID nếu dòng đó đã tồn tại, hoặc thêm mới nếu chưa có.
Kịch bản B: Full Refresh (Nếu không có cột dấu vết)
Với 5GB, việc xóa đi nạp lại hàng ngày (Truncate & Load) mất khoảng 1-3 phút trong StarRocks.
* Sử dụng lệnh: TRUNCATE TABLE ... sau đó INSERT INTO ... SELECT.
──────────
4. Nếu bạn vẫn muốn dùng Parquet (Data Pipeline chuyên nghiệp)
Nếu công ty bạn yêu cầu dùng Parquet/S3/HDFS, hãy dùng Broker Load. Đây là cách load dữ liệu không đồng bộ (asynchronous) và hiệu năng cực cao.
1. Dùng một công cụ (DataX, Airflow, hoặc script Python) export Oracle ra Parquet.
2. Đẩy file Parquet lên S3/HDFS.
3. Gọi lệnh Broker Load:
sql
LOAD LABEL dmapp.label_2026_09_11
(
DATA INFILE("<s3://your-bucket/path/to/data.parquet>")
INTO TABLE dtm_log_score
FORMAT AS "parquet"
)
WITH BROKER s3_broker (...)
PROPERTIES ("timeout" = "3600");
Tổng kết lời khuyên:
1. Dùng Primary Key Table (như bạn đã thiết kế ở câu hỏi trước) để tận dụng tính năng Upsert.
2. Dùng JDBC Catalog để đơn giản hóa Pipeline, tránh tạo ra file trung gian.
3. Tần suất: Với 40 triệu dòng, bạn có thể load theo giờ (Hourly) hoặc theo ngày (Daily) đều rất nhẹ nhàng.
4. Airflow: Bạn có thể dùng Airflow để trigger lệnh INSERT INTO ... SELECT từ JDBC Catalog để quản lý lịch trình và log lỗi.
References
• data_source/catalog/jdbc_catalog.md
• loading/InsertInto.md
• loading/BrokerLoad.md
• loading/Loading_intro.mdLý Thành
09/14/2026, 2:55 AMRocky
09/14/2026, 2:56 AM<s3://my-bucket/oracle_data/dtm_log_score/YYYY-MM-DD/_.parquet>
Lưu ý: Khi export, hãy đảm bảo kiểu dữ liệu giữa Oracle và Parquet tương thích (ví dụ: NUMBER trong Oracle tương ứng với DECIMAL trong Parquet).
Bước 2: Thiết lập kết nối tại StarRocks
Trước khi load, bạn cần khai báo thông tin kết nối tới nơi chứa file Parquet (Credential).
sql
-- Nếu dùng S3 hoặc MinIO, bạn có thể tạo một Resource để dùng nhiều lần
CREATE REPOSITORY s3_repo
WITH BROKER "s3_broker" -- Hoặc không cần broker nếu dùng cấu hình trực tiếp
PROPERTIES (
"aws.s3.endpoint" = "<http://your-s3-endpoint>",
"aws.s3.access_key" = "your-access-key",
"aws.s3.secret_key" = "your-secret-key",
"aws.s3.region" = "us-east-1"
);
Bước 3: Thực hiện Load dữ liệu (Broker Load)
Đây là cách "chuyên nghiệp" nhất để đẩy file Parquet vào StarRocks vì nó chạy bất đồng bộ, có khả năng chịu lỗi cao và không làm nghẽn kết nối của client.
Câu lệnh Load hàng ngày:
sql
LOAD LABEL dmapp.load_dtm_log_score_2026_09_14 -- Label phải là duy nhất mỗi lần chạy
(
DATA INFILE("<s3://my-bucket/oracle_data/dtm_log_score/2026-09-14/*.parquet>")
INTO TABLE dtm_log_score
FORMAT AS "parquet"
)
WITH BROKER "s3_broker"
PROPERTIES (
"timeout" = "3600", -- Thời gian tối đa cho phép load
"max_filter_ratio" = "0" -- 0: lỗi 1 dòng cũng fail job để đảm bảo chính xác dữ liệu
);
*Vì bảng của bạn là Primary Key, StarRocks sẽ tự động thực hiện cơ chế Upsert: Nếu thấy ID đã có thì cập nhật, nếu chưa có thì thêm mới.*
Bước 4: Kiểm tra trạng thái Load
Vì lệnh LOAD là bất đồng bộ (trả về ngay lập tức), bạn cần kiểm tra trạng thái:
sql
SHOW LOAD WHERE LABEL = "load_dtm_log_score_2026_09_14";
Bước 5: Tự động hóa (Orchestration)
Để pipeline chạy hàng ngày, bạn nên dùng Airflow hoặc DolphinScheduler:
1. Task 1 (Export): Gọi SeaTunnel/Spark để kéo dữ liệu từ Oracle và đẩy lên S3 dưới dạng Parquet.
2. Task 2 (StarRocks Load): Gọi lệnh SQL LOAD LABEL ... vào StarRocks.
3. Task 3 (Sensor): Chạy vòng lặp kiểm tra SHOW LOAD cho đến khi trạng thái là FINISHED.
Tại sao cách này tối ưu cho 40 triệu dòng (5GB)?
1. Hiệu năng: StarRocks đọc Parquet cực nhanh nhờ cơ chế đọc cột (columnar), 5GB dữ liệu có thể load xong trong vòng vài chục giây đến 2 phút.
2. Độ tin cậy: Cơ chế LABEL giúp ngăn chặn việc nạp trùng dữ liệu nếu Task bị chạy lại (Retry).
3. Khả năng mở rộng: Nếu sau này bảng tăng lên 400 triệu dòng hoặc 50GB, bạn chỉ cần tăng số lượng file Parquet, StarRocks sẽ tự động dùng các node BE để quét song song.
Mẹo nhỏ: Để tối ưu hơn nữa, khi export Parquet từ Oracle, hãy chia nhỏ thành các file khoảng 100MB - 200MB/file thay vì một file 5GB duy nhất. Điều này giúp StarRocks huy động nhiều luồng xử lý cùng lúc.
References
• loading/BrokerLoad.md
• loading/Loading_intro.md
• loading/Etl_in_starrocks.md
• sql-reference/sql-statements/data-manipulation/LOAD.mdLý Thành
09/14/2026, 8:24 AMRocky
09/14/2026, 8:24 AMtracking_url.
* Nguyên nhân: Dữ liệu bạn đang nạp bị sai kiểu dữ liệu, quá độ dài cột (ví dụ: chuỗi dài hơn VARCHAR đã khai báo), hoặc cột có giá trị NULL nhưng bảng không cho phép.
* Cách xử lý:
* Mở link tracking_url trong trình duyệt để xem dòng nào, cột nào bị lỗi.
* Tạm thời tắt chế độ kiểm tra nghiêm ngặt bằng lệnh: SET enable_insert_strict = false; (StarRocks sẽ bỏ qua các dòng lỗi và nạp các dòng đúng).
2. Lỗi: "execute timeout" hoặc "Transaction timeout"
* Dấu hiệu: Đang chạy nửa chừng thì DBeaver báo mất kết nối hoặc timeout.
* Nguyên nhân: Mặc định lệnh INSERT có thời gian chờ giới hạn. Nếu file bạn import qua DBeaver quá lớn (vài trăm MB trở lên), nó sẽ bị timeout.
* Cách xử lý:
* Tăng thời gian timeout cho session đó: SET insert_timeout = 28800; (đơn vị giây).
* Nếu dữ liệu lớn (trên 1GB), không nên dùng tính năng Import của DBeaver mà nên dùng Broker Load hoặc Stream Load như mình đã tư vấn ở trên.
3. Lỗi: "Reach limit of connections"
* Dấu hiệu: DBeaver báo lỗi không thể tạo thêm kết nối.
* Nguyên nhân: DBeaver khi import thường mở nhiều luồng (parallel) vượt quá giới hạn kết nối của user StarRocks.
* Cách xử lý:
* Tăng giới hạn kết nối: ALTER USER 'username' SET PROPERTIES ("max_user_connections" = "500");
* Hoặc trong phần cài đặt Import của DBeaver, chỉnh Parallelism (số luồng song song) về 1.
4. Lỗi: "Label already exists"
* Nguyên nhân: Bạn vừa chạy lệnh import lỗi và bấm chạy lại ngay lập tức với cùng một nhãn (label).
* Cách xử lý: Đợi khoảng 5-10 phút hoặc đổi tên Label (nếu bạn tự đặt label). Thông thường DBeaver tự tạo label ngẫu nhiên nên lỗi này ít gặp hơn.
Mẹo nhỏ: Nếu bạn đang dùng tính năng "Import Data" (chuột phải vào bảng -> Import Data), hãy đảm bảo bạn đã chọn đúng Driver là MySQL (vì StarRocks tương thích với giao thức MySQL).
Hãy gửi mã lỗi hoặc ảnh, mình sẽ giải thích chi tiết hơn!
References
• faq/loading/Insert_into_faq.md
• loading/InsertInto.md
• faq/loading/Flink_connector_faq.mdLý Thành
09/14/2026, 8:26 AMRocky
09/14/2026, 8:26 AMINSERT nhỏ trong thời gian quá ngắn).
Tại sao bị lỗi này?
Mỗi khi bạn thực hiện một lệnh INSERT hoặc một lần commit dữ liệu, StarRocks sẽ tạo ra một version (rowset) mới cho các tablet. StarRocks có một cơ chế chạy ngầm gọi là Compaction để gộp các version nhỏ này thành version lớn hơn.
* Giới hạn: Mặc định mỗi tablet chỉ cho phép tối đa 1000 versions.
* Vấn đề: DBeaver khi import thường gửi dữ liệu theo từng batch nhỏ hoặc từng dòng một. Nếu tốc độ tạo version mới nhanh hơn tốc độ Compaction gộp lại, bạn sẽ chạm ngưỡng 1000 và bị từ chối nạp tiếp.
──────────
Cách khắc phục ngay trong DBeaver
Nếu bạn vẫn muốn dùng DBeaver để import, hãy điều chỉnh các thông số trong cửa sổ Import Data:
1. Tăng Batch Size (Commit count): Thay vì để mặc định (thường là 100 hoặc 1000), hãy tăng lên 10,000 hoặc 50,000. Điều này giúp giảm số lượng version được tạo ra.
2. Giảm Parallelism: Trong phần Data load settings, hãy để Max threads = 1. Việc chạy đa luồng từ DBeaver càng làm tăng tốc độ tạo version và gây lỗi nhanh hơn.
──────────
Cách khắc phục triệt để (Khuyên dùng)
Với bảng 40 triệu dòng (5GB), dùng DBeaver là cách kém tối ưu nhất vì nó rất chậm và dễ gây lỗi version như trên. Bạn nên dùng các cách sau:
1. Dùng Stream Load (Nếu có file CSV/Parquet cục bộ)
Đây là cách nhanh nhất. Thay vì dùng DBeaver, bạn dùng lệnh curl để đẩy file trực tiếp vào StarRocks. Cách này chỉ tạo ra 1 version duy nhất cho toàn bộ file.
bash
curl --location-trusted -u admin:password \
-H "label:load_log_score_01" \
-H "column_separator:," \
-T your_data_file.csv \
http://<FE_IP>:8030/api/test_db/dtm_log_score/_stream_load
2. Điều chỉnh cấu hình BE (Nếu bạn có quyền quản trị cluster)
Nếu bạn bắt buộc phải nạp tần suất cao, bạn có thể cấu hình để StarRocks gộp version nhanh hơn. Sửa file be.conf của tất cả các BE:
conf
# Tăng số luồng xử lý compaction
cumulative_compaction_num_threads_per_disk = 4
base_compaction_num_threads_per_disk = 2
# (Tùy chọn) Tăng giới hạn version lên nếu cần, nhưng không nên quá 2000
tablet_max_versions = 2000
Sau khi sửa cần restart BE.
Tổng kết:
Bạn đang gặp lỗi kinh điển của StarRocks khi dùng công cụ UI (như DBeaver/Navicat) để nạp dữ liệu lớn. Hãy tăng Batch Size trong DBeaver lên thật lớn, hoặc chuyển sang dùng Stream Load / Broker Load để nạp dữ liệu một cách chuyên nghiệp và hiệu quả chuyên nghiệp hơn.
References
• faq/loading/Loading_faq.md
• administration/management/BE_configuration.md
• loading/StreamLoad.md
References
• administration/management/BE_configuration.md
• faq/loading/Loading_faq.md
• faq/loading/Routine_load_faq.mdLý Thành
09/14/2026, 8:37 AMRocky
09/14/2026, 8:37 AMYYYY-MM-DD. Nhưng thực tế, StarRocks không lưu dưới dạng String.
* DATE: Được lưu dưới dạng số nguyên 4-byte.
* DATETIME: Được lưu dưới dạng số nguyên 8-byte.
* Tại sao phải đúng format? Khi bạn nạp dữ liệu (qua DBeaver hoặc lệnh LOAD), bộ giải mã (Parser) của StarRocks được tối ưu hóa cực mạnh để chuyển đổi chuỗi YYYY-MM-DD sang số nhị phân một cách nhanh nhất. Nếu đưa vào định dạng lạ (như DD/MM/YYYY), Parser sẽ không hiểu và báo lỗi để tránh việc phải đoán định dạng làm chậm hệ thống.
2. Tại sao xử lý ngày tháng trong StarRocks lại rất nhanh?
Sở dĩ bạn thấy nó nhanh vượt trội là nhờ 3 yếu tố kỹ thuật:
* Lưu trữ dạng Cột (Columnar Storage): Các giá trị ngày tháng của hàng triệu dòng được xếp liền kề nhau trong bộ nhớ.
* Công cụ thực thi Vector hóa (Vectorized Execution): Thay vì xử lý từng dòng một, StarRocks dùng tập lệnh SIMD của CPU để xử lý một lúc hàng nghìn giá trị ngày tháng chỉ trong một nhịp xung nhịp.
* Operation on Encoded Data: Với một số phép so sánh, StarRocks thậm chí có thể thực hiện trực tiếp trên dữ liệu đã mã hóa mà không cần giải nén hoàn toàn.
3. Cách xử lý nếu dữ liệu nguồn không đúng format
Nếu bạn nạp từ Oracle/DBeaver mà cột ngày tháng bị lệch format (ví dụ: 2024/09/14), bạn có 2 cách chuyên nghiệp:
* Cách 1: Ép kiểu trong lệnh Load (Khuyên dùng)
Nếu dùng lệnh LOAD, bạn có thể dùng hàm STR_TO_DATE để biến đổi ngay lúc nạp:
sql
(col_date_temp, ...)
SET (
real_date_column = STR_TO_DATE(col_date_temp, '%Y/%m/%d %H:%i:%s')
)
* Cách 2: Sử dụng SQL của StarRocks để cast
Nếu bạn đã lỡ nạp vào một bảng tạm dưới dạng VARCHAR, hãy chuyển nó sang bảng chính:
sql
INSERT INTO main_table (date_col)
SELECT CAST(date_string AS DATE) FROM staging_table;
Tóm lại: Việc ép format "đúng chuẩn" lúc đầu giống như việc bạn sắp xếp hàng hóa vào pallet đúng kích thước trước khi đưa vào kho tự động. Nó mất công lúc đầu một chút nhưng giúp "cỗ máy" StarRocks chạy với tốc độ tối đa khi truy vấn.
References
• sql-reference/data-types/date-types/DATETIME.md
• introduction/Features.md
• unloading/Spark_connector.md
References
• introduction/Features.md
• release_notes/release-3.3.md
• sql-reference/sql-functions/date-time-functions/date_trunc.md
• administration/management/timezone.md