Thực thi truy vấn dữ liệu cơ bản với EdgeQL
Bắt đầu bằng việc kết nối trực tiếp vào shell của EdgeDB để thao tác với dữ liệu đã được định nghĩa trong Schema (Phần 2).
EdgeQL là ngôn ngữ truy vấn quan hệ của EdgeDB, cú pháp gần giống SQL nhưng mạnh mẽ hơn ở khả năng xử lý đồ thị và polymorphism.
edgedb shell
Kết quả mong đợi: Bạn thấy prompt thay đổi từ shell Linux sang edgedb>, sẵn sàng nhận lệnh.
Chèn dữ liệu (INSERT)
Sử dụng lệnh INSERT để đưa dữ liệu mới vào bộ sưu tập (Collection). Cú pháp cho phép chèn cả dữ liệu con (Nested objects) trong một lệnh duy nhất.
Giả sử chúng ta có Schema với bộ sưu tập User và Post. Lệnh dưới đây tạo một người dùng và đồng thời tạo bài viết thuộc về người đó.
INSERT User {
name := 'Nguyen Van A',
email := 'nguyenvana@example.com',
posts := (
INSERT Post {
title := 'Chào mừng đến với EdgeDB',
content := 'Đây là bài viết đầu tiên.',
published := true
}
)
};
Kết quả mong đợi: EdgeDB trả về đối tượng User mới được tạo kèm ID (UUID) và các trường dữ liệu đã nhập.
Truy vấn dữ liệu (SELECT)
Lệnh SELECT dùng để lấy dữ liệu. EdgeQL cho phép truy vấn sâu (deep traversal) để lấy dữ liệu cha con mà không cần JOIN thủ công như SQL truyền thống.
Lệnh dưới đây lấy danh sách tất cả User và hiển thị kèm theo danh sách các bài viết (posts) của họ.
SELECT User {
name,
email,
posts := Post {
title,
published
}
};
Kết quả mong đợi: Một mảng JSON chứa danh sách User, mỗi User có trường posts là mảng con chứa thông tin bài viết.
Cập nhật và Xóa dữ liệu (UPDATE & DELETE)
Lệnh UPDATE dùng để sửa đổi dữ liệu. Bạn có thể lọc đối tượng cần sửa bằng mệnh đề FILTER hoặc tham chiếu trực tiếp.
Cập nhật trạng thái published của bài viết có tiêu đề "Chào mừng đến với EdgeDB" sang false.
UPDATE Post
FILTER .title = 'Chào mừng đến với EdgeDB'
SET {
published := false
};
Kết quả mong đợi: Trả về đối tượng Post đã được cập nhật với giá trị published: false.
Xóa toàn bộ bài viết chưa được đăng (unpublished) để dọn dẹp dữ liệu.
DELETE Post FILTER .published = false;
Kết quả mong đợi: Trả về mảng các đối tượng đã bị xóa, hoặc mảng rỗng nếu không có dữ liệu thỏa mãn.
Tối ưu hóa truy vấn nâng cao với Filter và Link
Để xử lý các yêu cầu phức tạp, EdgeDB sử dụng toán tử liên kết (Link) và bộ lọc (Filter) ngay trong cú pháp truy vấn.
Lọc dữ liệu nâng cao (Advanced Filtering)
Sử dụng toán tử FILTER với các điều kiện logic phức tạp (AND, OR, IN) để thu hẹp phạm vi dữ liệu ngay khi truy vấn.
Truy vấn tìm tất cả User có email chứa "example.com" VÀ có ít nhất một bài viết đã được đăng (published).
SELECT User
FILTER
.email LIKE '%example.com%'
AND (
SELECT .posts FILTER .published = true LIMIT 1
)
LIMIT 5;
Kết quả mong đợi: Trả về tối đa 5 người dùng thỏa mãn cả hai điều kiện về email và bài viết đã đăng.
Truy vấn liên kết (Link Traversal)
Thay vì dùng JOIN, EdgeDB cho phép duyệt qua các liên kết (Links) một cách tự nhiên. Điều này cực kỳ hiệu năng khi làm việc với dữ liệu đồ thị.
Truy vấn tìm tất cả bài viết của những người dùng có tên bắt đầu bằng "Nguyen".
SELECT (
SELECT User FILTER .name LIKE 'Nguyen%'
).posts {
title,
content,
author_name := .user.name
};
Kết quả mong đợi: Danh sách các bài viết, mỗi bài có thêm trường author_name được tính toán động từ đối tượng cha.
Quản lý và tạo Chỉ mục (Indexes)
Chỉ mục (Index) là cấu trúc dữ liệu giúp tăng tốc độ tìm kiếm, sắp xếp và liên kết. EdgeDB tự động tạo chỉ mục cho các trường Primary Key và Foreign Key, nhưng bạn cần tạo thủ công cho các trường thường xuyên dùng để lọc (filter).
Phân tích nhu cầu tạo Index
Nếu bạn thường xuyên lọc dữ liệu theo trường email hoặc published, hãy tạo chỉ mục cho các trường này.
Sử dụng lệnh CREATE INDEX trong Schema hoặc trực tiếp trong shell EdgeDB.
Tạo Index cho trường đơn
Tạo chỉ mục cho trường email của bộ sưu tập User để tăng tốc các truy vấn tìm kiếm người dùng.
CREATE INDEX User ON (.email);
Kết quả mong đợi: EdgeDB xác nhận chỉ mục đã được tạo thành công. Lưu ý: Việc tạo index sẽ mất thời gian nếu dữ liệu lớn.
Tạo Index cho liên kết (Link Index)
Tạo chỉ mục cho liên kết giữa Post và User để tăng tốc các truy vấn tìm bài viết theo tác giả.
CREATE INDEX Post ON (.user);
Kết quả mong đợi: Chỉ mục liên kết được tạo, giúp các truy vấn dạng SELECT Post FILTER .user == ... chạy nhanh hơn.
Xóa chỉ mục
Nếu chỉ mục không còn cần thiết hoặc gây tốn tài nguyên, hãy xóa nó.
DROP INDEX User ON (.email);
Kết quả mong đợi: Chỉ mục bị xóa khỏi schema.
Phân tích hiệu năng với EXPLAIN
Công cụ EXPLAIN trong EdgeDB cho phép bạn xem kế hoạch thực thi (Execution Plan) của một truy vấn. Điều này giúp phát hiện các nút cổ chai (bottleneck) như quét bảng (full table scan) hoặc thiếu index.
Chạy EXPLAIN cơ bản
Dùng EXPLAIN trước một lệnh SELECT để xem EdgeDB xử lý nó như thế nào.
EXPLAIN SELECT User FILTER .email = 'nguyenvana@example.com';
Kết quả mong đợi: Một cây kế hoạch hiển thị các bước: Scan bộ sưu tập -> Apply Filter -> Output. Nếu có Index, bạn sẽ thấy bước IndexScan thay vì CollectionScan.
Phân tích chi tiết với EXPLAIN (VERBOSE)
Sử dụng cờ VERBOSE để xem thông tin chi tiết về số lượng dòng ước tính, chi phí (cost) và cách thức truy cập dữ liệu.
EXPLAIN VERBOSE SELECT User FILTER .email = 'nguyenvana@example.com';
Kết quả mong đợi:
- Dòng CollectionScan: Chỉ ra việc quét toàn bộ bảng (chậm, nếu bảng lớn).
- Dòng IndexScan: Chỉ ra việc dùng index để tìm kiếm (nhanh).
- Các thông số rows (số dòng ước tính) và cost (chi phí ước tính).
Tối ưu hóa dựa trên EXPLAIN
Nếu kết quả EXPLAIN hiện thị CollectionScan trên một bộ sưu tập lớn với điều kiện lọc cụ thể, đây là dấu hiệu cần tạo Index.
Bước thực hiện:
1. Chạy EXPLAIN -> Thấy CollectionScan.
2. Tạo Index cho trường lọc: CREATE INDEX User ON (.email);.
3. Chạy lại EXPLAIN -> Kiểm tra xem đã chuyển sang IndexScan chưa.
EXPLAIN SELECT User FILTER .email = 'nguyenvana@example.com';
Kết quả mong đợi: Kế hoạch mới hiển thị IndexScan và chi phí (cost) thấp hơn đáng kể so với lần chạy trước khi có Index.
Verify kết quả tối ưu hóa
Sau khi đã thực hiện các bước tạo Index và tối ưu, cần kiểm chứng lại hiệu năng thực tế.
So sánh thời gian thực thi
Sử dụng lệnh EXPLAIN (ANALYZE) để đo thời gian thực thi thực tế (Actual Time) thay vì ước tính.
EXPLAIN (ANALYZE) SELECT User FILTER .email = 'nguyenvana@example.com';
Kết quả mong đợi:
- Xem dòng actual time trong output.
- Thời gian này nên giảm đáng kể so với khi chưa có Index (ví dụ: từ 50ms xuống 5ms).
Kiểm tra chỉ mục đã tồn tại
Danh sách tất cả chỉ mục hiện có trong database để đảm bảo cấu hình đúng.
SELECT Index;
Kết quả mong đợi: Danh sách các chỉ mục bao gồm chỉ mục tự động (Primary Key) và chỉ mục thủ công bạn vừa tạo (trên trường email).
Điều hướng series:
Mục lục: Series: Triển khai Database Edge-native với EdgeDB trên Ubuntu 24.04
« Phần 2: Thiết kế mô hình dữ liệu Schema với EdgeQL
Phần 4: Tích hợp EdgeDB với ứng dụng Python và Node.js »