Giới thiệu
Trong thế giới của các hệ thống Quản lý Cơ sở Dữ liệu Quan hệ (RDBMS) như Oracle, MySQL, PostgreSQL và SQL Server, việc tối ưu hóa hiệu suất khi thực hiện các câu truy vấn SQL là cực kỳ quan trọng. Thông qua bài viết này, chúng ta sẽ cùng tìm hiểu quy trình xử lý của SQL, từ khi nhấn "Enter" cho đến khi nhận được kết quả.
Bài toán thực tiễn
Hãy cùng xem xét một bài toán cụ thể: Giả sử chúng ta có một bảng employees
chỉ với một cột là employee_id
. Để thêm 1 triệu dòng vào bảng này, chúng ta có hai cách thực hiện như sau:
Cách 1: Sử dụng Statement
java
Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
Statement stmt = conn.createStatement();
for (int i = 1; i <= 1000000; i++) {
String sql = "INSERT INTO employees (employee_id) VALUES (" + i + ")";
stmt.executeUpdate(sql);
}
Thời gian thực hiện cho cách này là khoảng 80 giây.
Cách 2: Sử dụng PreparedStatement
java
Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
String sql = "INSERT INTO employees (employee_id) VALUES (?)";
PreparedStatement pstmt = conn.prepareStatement(sql);
for (int i = 1; i <= 1000000; i++) {
pstmt.setInt(1, i);
pstmt.addBatch();
}
pstmt.executeBatch();
Với cách này, thời gian thực thi giảm đáng kể xuống chỉ còn 4 giây. Để lý giải điều này, chúng ta sẽ xem xét quá trình xử lý câu truy vấn trong SQL.
Quy trình Xử lý SQL
Bước 1: Kiểm tra cú pháp
Hệ thống đầu tiên sẽ kiểm tra xem cú pháp của câu lệnh có đúng không. Ví dụ: selectt * from employeess
có cú pháp sai và sẽ gây ra lỗi.
Bước 2: Xác thực
Sau khi cú pháp đúng, hệ thống tiếp tục kiểm tra xem các bảng và cột có tồn tại hay không, và liệu người dùng có quyền truy cập vào bảng này hay không.
Bước 3 và Bước 4: Shared Pool
Hệ thống sẽ kiểm tra xem câu lệnh đã tồn tại trong shared pool (vùng lưu trữ tạm thời để lưu trữ execution plans) hay chưa. Nếu có, bước này sẽ được bỏ qua và câu lệnh sẽ được thực thi ngay lập tức.
Bước 5: Tối ưu hóa
Optimizer sẽ tính toán các phương án khác nhau để thực thi câu hỏi của bạn và tìm ra phương án tối ưu nhất. Đây là bước tiêu tốn nhiều tài nguyên như CPU, bộ nhớ, I/O,...
Bước 6: Kế hoạch thực thi
Cuối cùng, optimizer sẽ cung cấp cho bạn một execution plan, phương án tối ưu nhất để thực hiện câu lệnh.
Phân tích hai cách thực hiện
Cách 1:
Trong ví dụ về cách 1, mỗi lần thực thi câu lệnh insert sẽ tạo ra một chuỗi riêng biệt, dẫn đến việc hệ thống phải thực hiện đến 1 triệu lần tối ưu hóa. Đó chính là lý do thời gian thực hiện rất lâu.
Cách 2:
Trong cách 2, chỉ có một câu lệnh duy nhất được tối ưu hóa, và chỉ cần phân tích một lần. Do đó, việc thực thi nhanh chóng và hiệu quả hơn nhiều.
Kết luận
Qua bài viết này, hy vọng bạn đã hiểu rõ hơn về tầm quan trọng của việc sử dụng PreparedStatement và quy trình mà một câu truy vấn SQL trải qua trước khi nhận được kết quả. Hiểu biết này sẽ giúp bạn tối ưu hóa hiệu suất truy vấn và làm việc hiệu quả hơn với các cơ sở dữ liệu.
source: viblo