Bài 20: Tối ưu Query với Query Rewrite

Query rewrite (viết lại truy vấn) là một kỹ thuật tối ưu hóa truy vấn SQL bằng cách thay đổi cấu trúc hoặc logic của truy vấn để cải thiện hiệu suất mà không thay đổi kết quả đầu ra. Kỹ thuật này đặc biệt hữu ích khi làm việc với các truy vấn phức tạp, dữ liệu lớn hoặc các hệ thống có yêu cầu hiệu suất cao. Bài viết này sẽ đi sâu vào khái niệm query rewrite, các kỹ thuật phổ biến, và cách áp dụng chúng để tối ưu hóa truy vấn.


20.1. Query Rewrite là gì?

Query rewrite là quá trình thay đổi cấu trúc hoặc logic của một truy vấn SQL để cải thiện hiệu suất mà vẫn đảm bảo kết quả đầu ra không thay đổi. Kỹ thuật này có thể được thực hiện thủ công bởi người phát triển hoặc tự động bởi hệ thống cơ sở dữ liệu.

20.1.1. Cách sử dụng query rewrite
  • Mục tiêu: Giảm thời gian thực thi, giảm tải tài nguyên (CPU, I/O), và tận dụng tối đa các chỉ mục và cấu trúc dữ liệu.

  • Phương pháp: Thay đổi cấu trúc truy vấn, sử dụng các kỹ thuật như tối ưu hóa JOIN, loại bỏ các phép toán không cần thiết, hoặc sử dụng các cấu trúc dữ liệu tối ưu hơn.

20.1.2. Lợi ích của query rewrite
  • Cải thiện hiệu suất: Giảm thời gian thực thi và tải tài nguyên.

  • Tận dụng chỉ mục: Tối ưu hóa việc sử dụng các chỉ mục hiện có.

  • Dễ bảo trì: Làm cho truy vấn dễ đọc và dễ hiểu hơn.


20.2. Các kỹ thuật query rewrite

Có nhiều kỹ thuật query rewrite khác nhau, tùy thuộc vào loại truy vấn và cấu trúc dữ liệu. Dưới đây là một số kỹ thuật phổ biến:

20.2.1. Viết lại query để tối ưu
  • Tối ưu hóa JOIN: Thay đổi thứ tự JOIN hoặc sử dụng các loại JOIN phù hợp (INNER JOIN, LEFT JOIN, v.v.).

    • Ví dụ không tối ưu:

        SELECT * FROM orders o
        JOIN customers c ON o.customer_id = c.customer_id
        JOIN products p ON o.product_id = p.product_id
        WHERE c.country = 'USA';
      
    • Ví dụ tối ưu:

        SELECT * FROM customers c
        JOIN orders o ON c.customer_id = o.customer_id
        JOIN products p ON o.product_id = p.product_id
        WHERE c.country = 'USA';
      
  • Loại bỏ các phép toán không cần thiết: Tránh sử dụng các phép toán hoặc hàm không cần thiết trong truy vấn.

    • Ví dụ không tối ưu:

        SELECT * FROM employees WHERE YEAR(hire_date) = 2023;
      
    • Ví dụ tối ưu:

        SELECT * FROM employees WHERE hire_date BETWEEN '2023-01-01' AND '2023-12-31';
      
  • Sử dụng subquery hoặc CTE: Chia nhỏ truy vấn phức tạp thành các phần nhỏ hơn, dễ quản lý hơn.

    • Ví dụ không tối ưu:

        SELECT * FROM orders WHERE customer_id IN (SELECT customer_id FROM customers WHERE country = 'USA');
      
    • Ví dụ tối ưu:

        WITH usa_customers AS (
            SELECT customer_id FROM customers WHERE country = 'USA'
        )
        SELECT * FROM orders WHERE customer_id IN (SELECT customer_id FROM usa_customers);
      
20.2.2. Sử dụng query rewrite với indexed views
  • Vấn đề: Các truy vấn phức tạp với nhiều JOIN và GROUP BY có thể làm chậm hiệu suất.

  • Giải pháp: Sử dụng indexed views để lưu trữ kết quả của các truy vấn phức tạp, sau đó viết lại truy vấn để sử dụng indexed views.

    • Ví dụ không tối ưu:

        SELECT d.department_id, d.department_name, SUM(s.amount) AS total_sales
        FROM departments d
        JOIN sales s ON d.department_id = s.department_id
        GROUP BY d.department_id, d.department_name;
      
    • Ví dụ tối ưu:

        CREATE VIEW SalesByDepartment WITH SCHEMABINDING AS
        SELECT d.department_id, d.department_name, SUM(s.amount) AS total_sales
        FROM departments d
        JOIN sales s ON d.department_id = s.department_id
        GROUP BY d.department_id, d.department_name;
        CREATE UNIQUE CLUSTERED INDEX idx_SalesByDepartment ON SalesByDepartment(department_id);
      
        SELECT * FROM SalesByDepartment WHERE department_name = 'Sales';
      

20.3. Khi nào nên sử dụng query rewrite

20.3.1. Trường hợp phù hợp cho query rewrite
  • Truy vấn phức tạp: Query rewrite phù hợp cho các truy vấn phức tạp với nhiều JOIN, GROUP BY, hoặc các phép toán tổng hợp.

  • Dữ liệu lớn: Query rewrite giúp cải thiện hiệu suất khi làm việc với các bảng có lượng dữ liệu lớn.

  • Yêu cầu hiệu suất cao: Query rewrite là một kỹ thuật quan trọng trong các hệ thống có yêu cầu hiệu suất cao.

20.3.2. Đánh đổi giữa query rewrite và query tuning
  • Query Rewrite:

    • Ưu điểm: Cải thiện hiệu suất bằng cách thay đổi cấu trúc truy vấn.

    • Nhược điểm: Yêu cầu kiến thức sâu về SQL và cấu trúc dữ liệu.

  • Query Tuning:

    • Ưu điểm: Tối ưu hóa hiệu suất bằng cách điều chỉnh các tham số hệ thống hoặc cấu trúc dữ liệu.

    • Nhược điểm: Có thể không hiệu quả với các truy vấn phức tạp.


Kết luận

Query rewrite là một kỹ thuật mạnh mẽ giúp tối ưu hóa các truy vấn SQL bằng cách thay đổi cấu trúc hoặc logic của truy vấn để cải thiện hiệu suất. Bằng cách sử dụng các kỹ thuật như tối ưu hóa JOIN, loại bỏ các phép toán không cần thiết, và sử dụng indexed views, bạn có thể giảm thời gian thực thi và tải tài nguyên của hệ thống. Tuy nhiên, việc sử dụng query rewrite cần được cân nhắc kỹ lưỡng để đảm bảo tính nhất quán và chính xác của dữ liệu. Trong các bài tiếp theo, chúng ta sẽ đi sâu vào các kỹ thuật tối ưu hóa khác, chẳng hạn như parallel processing và query hints.


Từ vựng chuyên môn (Glossary)

  • Query Rewrite: Viết lại truy vấn.

  • Query Tuning: Điều chỉnh truy vấn.

  • Indexed Views: Views được đánh chỉ mục.

  • JOIN Optimization: Tối ưu hóa JOIN.

  • Subquery: Truy vấn con.

  • CTE (Common Table Expressions): Biểu thức bảng chung.

  • Data Aggregation: Tổng hợp dữ liệu.

  • Performance Improvement: Cải thiện hiệu suất.

  • Resource Utilization: Sử dụng tài nguyên.

  • Execution Plan: Kế hoạch thực thi.