Tại sao lại mất quá nhiều thời gian để thực hiện một truy vấn? Tại sao không có chỉ mục? Rất có thể bạn đã nghe về GIẢI THÍCH trong PostgreSQL. Tuy nhiên, vẫn còn nhiều người chưa biết cách sử dụng nó. Tôi hy vọng bài viết này sẽ giúp người dùng xử lý công cụ tuyệt vời này.
Bài viết này là bản sửa đổi tác giả của Hiểu GIẢI THÍCH bởi Guillaume Lelarge. Vì tôi đã bỏ lỡ một số thông tin, tôi thực sự khuyên bạn nên làm quen với tài liệu gốc.
Con quỷ không đen như vẽ
Điều quan trọng là phải hiểu logic của nhân PostgreSQL để tối ưu hóa các truy vấn. Tôi sẽ cố gắng giải thích. Nó thực sự không phức tạp như vậy.
EXPLAIN hiển thị thông tin cần thiết giải thích những gì hạt nhân làm cho từng truy vấn cụ thể.
Chúng ta hãy xem những gì lệnh EXPLAIN hiển thị và hiểu những gì chính xác xảy ra bên trong PostgreSQL. Bạn có thể áp dụng thông tin này cho PostgreSQL 9.2 và các phiên bản cao hơn.
Nhiệm vụ của chúng tôi:
- Tìm hiểu cách đọc và hiểu đầu ra của lệnh EXPLAIN
- Hiểu những gì sẽ xảy ra trong PostgreSQL khi một truy vấn được thực thi
Các bước đầu tiên
Chúng ta sẽ thực hành trên một bảng thử nghiệm có hàng triệu hàng.
CREATE TABLE foo (c1 integer, c2 text); INSERT INTO foo SELECT i, md5(random()::text) FROM generate_series(1, 1000000) AS i;
Cố gắng đọc dữ liệu
EXPLAIN SELECT * FROM foo;
Có thể đọc dữ liệu từ một bảng theo nhiều cách. Trong trường hợp của chúng tôi, EXPLAIN thông báo rằng Seq Scan được sử dụng - đọc dữ liệu bảng Foo tuần tự, từng khối.
chi phí là gì ?
Đó không phải là thời gian, mà là một khái niệm được thiết kế để ước tính chi phí của một ca phẫu thuật. Giá trị đầu tiên 0,00 là chi phí để có được hàng đầu tiên. Giá trị thứ hai 18334,00 là chi phí để có được tất cả các hàng.
Hàng là số hàng gần đúng được trả về khi thao tác Quét Seq được thực hiện. Bộ lập lịch trả về giá trị này. Trong trường hợp của tôi, nó khớp với số hàng thực tế trong bảng.
Chiều rộng là kích thước trung bình của một hàng tính bằng byte.
Hãy thử thêm 10 hàng.
INSERT INTO foo SELECT i, md5(random()::text) FROM generate_series(1, 10) AS i; EXPLAIN SELECT * FROM foo;
Giá trị của các hàng không được thay đổi. Bảng thống kê đã cũ. Để cập nhật số liệu thống kê, hãy gọi lệnh ANALYZE.
Bây giờ, hàng hiển thị số hàng chính xác.
Điều gì xảy ra khi thực thi ANALYZE?
- Một cách ngẫu nhiên, một số hàng được chọn và đọc từ bảng.
- Thống kê các giá trị theo từng cột được thu thập.
Số lượng hàng mà ANALYZE đọc phụ thuộc vào tham số default_st Statistics_target.
Dữ liệu thực tế
Mọi thứ chúng ta đã thấy ở trên trong đầu ra của lệnh EXPLAIN là những gì người lập kế hoạch mong đợi nhận được. Hãy thử so sánh chúng với kết quả trên dữ liệu thực tế. Để thực hiện việc này, hãy sử dụng GIẢI THÍCH (PHÂN TÍCH).
EXPLAIN (ANALYZE) SELECT * FROM foo;
Một truy vấn như vậy sẽ được thực hiện thực sự. Vì vậy, nếu bạn thực thi GIẢI THÍCH (ANALYZE) cho các câu lệnh INSERT, DELETE hoặc UPDATE, dữ liệu của bạn sẽ bị thay đổi. Hãy cẩn thận! Trong những trường hợp này, hãy sử dụng lệnh ROLLBACK.
Lệnh hiển thị các tham số bổ sung sau:
- thời gian thực tế là thời gian thực tế tính bằng mili giây dành cho hàng đầu tiên và tất cả các hàng, tương ứng.
- hàng là số lượng hàng thực tế nhận được với Seq Scan.
- vòng lặp là số lần thao tác Quét Seq phải được thực hiện.
- Tổng thời gian chạy là tổng thời gian thực hiện truy vấn.
Đọc thêm:
Tối ưu hóa truy vấn trong PostgreSQL. GIẢI THÍCH Khái niệm cơ bản - Phần 2
Tối ưu hóa truy vấn trong PostgreSQL. GIẢI THÍCH Khái niệm cơ bản - Phần 3