Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

SQL UNION ALL để loại bỏ các bản sao

Nhưng trong ví dụ, truy vấn đầu tiên có điều kiện trên cột a , trong khi truy vấn thứ hai có một điều kiện trên cột b . Điều này có thể đến từ một truy vấn khó tối ưu hóa:

SELECT * FROM mytable WHERE a=X OR b=Y

Truy vấn này khó tối ưu hóa với việc lập chỉ mục cây B đơn giản. Công cụ có tìm kiếm chỉ mục trên cột a không ? Hoặc trên cột b ? Dù bằng cách nào, việc tìm kiếm cụm từ khác cũng yêu cầu quét bảng.

Do đó, mẹo sử dụng UNION để tách thành hai truy vấn cho một thuật ngữ. Mỗi truy vấn con có thể sử dụng chỉ mục tốt nhất cho mỗi cụm từ tìm kiếm. Sau đó, kết hợp các kết quả bằng cách sử dụng UNION.

Nhưng hai tập hợp con có thể trùng nhau, vì một số hàng trong đó b=Y cũng có thể có a=X trong trường hợp đó các hàng như vậy xảy ra trong cả hai tập hợp con. Do đó, bạn phải thực hiện loại bỏ trùng lặp, nếu không sẽ thấy một số hàng hai lần trong kết quả cuối cùng.

SELECT * FROM mytable WHERE a=X 
UNION DISTINCT
SELECT * FROM mytable WHERE b=Y

UNION DISTINCT tốn kém bởi vì các triển khai điển hình sắp xếp các hàng để tìm các bản sao. Giống như nếu bạn sử dụng SELECT DISTINCT ... .

Chúng tôi cũng có nhận thức rằng công việc thậm chí còn "lãng phí" hơn nếu hai tập hợp con của các hàng mà bạn đang hợp nhất có nhiều hàng xuất hiện trong cả hai tập hợp con. Có rất nhiều hàng cần loại bỏ.

Nhưng không cần phải loại bỏ các bản sao nếu bạn có thể đảm bảo rằng hai tập hợp hàng đã khác biệt. Đó là, nếu bạn đảm bảo không có sự trùng lặp. Nếu bạn có thể dựa vào đó, thì việc loại bỏ trùng lặp sẽ luôn là điều không cần thiết, và do đó truy vấn có thể bỏ qua bước đó và do đó bỏ qua việc sắp xếp tốn kém.

Nếu bạn thay đổi các truy vấn để chúng được đảm bảo chọn các tập hợp con không trùng lặp của các hàng, thì đó là một chiến thắng.

SELECT * FROM mytable WHERE a=X 
UNION ALL 
SELECT * FROM mytable WHERE b=Y AND a!=X

Hai bộ này được đảm bảo không có sự trùng lặp. Nếu tập hợp đầu tiên có các hàng trong đó a=X và tập hợp thứ hai có các hàng trong đó a!=X thì không thể có hàng nào trong cả hai bộ.

Do đó, truy vấn thứ hai chỉ bắt được some trong số các hàng mà b=Y , nhưng bất kỳ hàng nào trong đó a=X AND b=Y đã được đưa vào tập hợp đầu tiên.

Vì vậy, truy vấn đạt được tìm kiếm được tối ưu hóa cho hai OR các điều khoản, không tạo bản sao và không yêu cầu UNION DISTINCT hoạt động.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. mysql ... trong đó mệnh đề không rõ ràng

  2. Giá trị hạt giống MySQL RAND () gần như lặp lại

  3. ini_set, set_time_limit, (max_execution_time) - không hoạt động

  4. Thực thi Python + MySQLdb

  5. MySql SELECT liên minh cho các cột khác nhau?