Bạn gặp khó khăn với SQL UNION? Nó xảy ra nếu kết quả bạn kết hợp đặt Máy chủ SQL của bạn vào bế tắc. Hoặc một báo cáo đang hoạt động trước khi bật lên một hộp có biểu tượng X màu đỏ. Lỗi “Cuộc đụng độ kiểu toán hạng” xảy ra khi trỏ đến một dòng có UNION. "Ngọn lửa" bắt đầu. Nghe quen không?
Cho dù bạn đã sử dụng SQL UNION được một thời gian hay chỉ mới bắt đầu sử dụng, thì một bảng gian lận hoặc một tập hợp các ghi chú ngắn gọn sẽ không ảnh hưởng gì. Đây là những gì bạn sẽ nhận được ngày hôm nay trong bài đăng này. Danh sách này cung cấp 10 lời khuyên hữu ích cho cả người mới và cựu chiến binh. Ngoài ra, sẽ có các ví dụ và một số thảo luận nâng cao.
[sendpulse-form id =”11900 ″]
Nhưng trước khi đi vào điểm đầu tiên, hãy làm rõ các điều khoản.
UNION là một trong những toán tử tập hợp trong SQL kết hợp 2 hoặc nhiều tập kết quả. Nó có thể hữu ích khi bạn cần kết hợp tên, số liệu thống kê hàng tháng và hơn thế nữa từ các nguồn khác nhau. Và cho dù bạn sử dụng SQL Server, MySQL hay Oracle, mục đích, hành vi và cú pháp sẽ rất giống nhau. Nhưng nó hoạt động như thế nào?
1. Sử dụng SQL UNION để kết hợp Duy nhất Hồ sơ
Sử dụng UNION để kết hợp các tập hợp kết quả sẽ loại bỏ các bản sao.
Tại sao điều này lại quan trọng?
Hầu hết thời gian, bạn không muốn có kết quả trùng lặp. Một báo cáo có các dòng trùng lặp gây lãng phí mực và giấy trong bìa cứng. Và điều này sẽ khiến người dùng của bạn tức giận.
Cách sử dụng
Bạn kết hợp kết quả của các câu lệnh SELECT với UNION ở giữa.
Trước khi bắt đầu với ví dụ, chúng ta hãy chuẩn bị dữ liệu mẫu của chúng tôi.
USE AdventureWorks
GO
IF OBJECT_ID ('dbo.Customer1', 'U') IS NOT NULL
DROP TABLE dbo.Customer1;
GO
IF OBJECT_ID ('dbo.Customer2', 'U') IS NOT NULL
DROP TABLE dbo.Customer2;
GO
IF OBJECT_ID ('dbo.Customer3', 'U') IS NOT NULL
DROP TABLE dbo.Customer3;
GO
-- Get 3 customer names with Andersen lastname
SELECT TOP 3
p.LastName
, p.FirstName
, c.AccountNumber
INTO dbo.Customer1
FROM Person.Person AS p
INNER JOIN Sales.Customer c
ON c.PersonID = p.BusinessEntityID
WHERE p.LastName = 'Andersen';
-- Make sure we have a duplicate in another table
SELECT
c.LastName
,c.FirstName
,c.AccountNumber
INTO dbo.Customer2
FROM Customer1 c
-- Seems it's not enough. Let's have a 3rd copy
SELECT
c.LastName
,c.FirstName
,c.AccountNumber
INTO dbo.Customer3
FROM Customer1 c
Chúng tôi sẽ sử dụng dữ liệu được tạo bởi mã trên cho đến mẹo thứ ba. Bây giờ chúng ta đã sẵn sàng, dưới đây là ví dụ:
SELECT
c.LastName
,c.FirstName
,c.AccountNumber
FROM dbo.Customer1 c
UNION
SELECT
c2.LastName
,c2.FirstName
,c2.AccountNumber
FROM dbo.Customer2 c2
UNION
SELECT
c3.LastName
,c3.FirstName
,c3.AccountNumber
FROM dbo.Customer3 c3
Chúng tôi có 3 bản sao tên của các khách hàng giống nhau và hy vọng rằng các bản ghi duy nhất sẽ biến mất. Xem kết quả:
Giải pháp dbForge Studio cho SQL Server mà chúng tôi sử dụng cho các ví dụ của mình chỉ hiển thị 3 bản ghi. Nó có thể là 9. Bằng cách áp dụng UNION, chúng tôi đã xóa các bản sao.
Nó hoạt động như thế nào?
Sơ đồ kế hoạch trong dbForge Studio tiết lộ cách SQL Server tạo ra kết quả được hiển thị trong Hình 1. Hãy xem:
Để diễn giải Hình 2, hãy bắt đầu từ phải sang trái:
- Chúng tôi đã truy xuất 3 bản ghi từ mỗi toán tử Quét bảng. Đó là 3 câu lệnh SELECT trong ví dụ trên. Mỗi dòng đi ra khỏi nó hiển thị "3", nghĩa là mỗi dòng có 3 bản ghi.
- Toán tử Kết hợp thực hiện việc kết hợp các kết quả. Dòng đi ra khỏi nó hiển thị "9" - kết quả của 9 bản ghi từ việc kết hợp các kết quả.
- Toán tử Sắp xếp Phân biệt đảm bảo các bản ghi duy nhất là đầu ra cuối cùng. Dòng đi ra khỏi nó hiển thị "3", phù hợp với số lượng bản ghi trong Hình 1.
Sơ đồ trên cho thấy cách UNION được SQL Server xử lý. Số lượng và loại toán tử được sử dụng có thể khác nhau tùy thuộc vào truy vấn và nguồn dữ liệu cơ bản. Nhưng tóm lại, UNION hoạt động như sau:
- Truy xuất kết quả của mỗi câu lệnh SELECT.
- Kết hợp các kết quả với một toán tử Nối.
- Nếu các kết quả được kết hợp không phải là duy nhất, SQL Server sẽ lọc ra các kết quả trùng lặp.
Tất cả các ví dụ thành công với UNION đều làm theo các bước cơ bản sau.
2. Sử dụng SQL UNION ALL để kết hợp các bản ghi với các bản sao
Sử dụng UNION ALL sẽ kết hợp các tập kết quả có bao gồm các bản sao.
Tại sao điều này lại quan trọng?
Bạn có thể muốn kết hợp các bộ kết quả và sau đó lấy các bản ghi có các bản sao để xử lý sau. Tác vụ này rất hữu ích để làm sạch dữ liệu của bạn.
Cách sử dụng
Bạn kết hợp kết quả của các câu lệnh SELECT với UNION ALL ở giữa. Hãy xem ví dụ:
SELECT
c.LastName
,c.FirstName
,c.AccountNumber
FROM dbo.Customer1 c
UNION ALL
SELECT
c2.LastName
,c2.FirstName
,c2.AccountNumber
FROM dbo.Customer2 c2
UNION ALL
SELECT
c3.LastName
,c3.FirstName
,c3.AccountNumber
FROM dbo.Customer3 c3
Đoạn mã trên xuất ra 9 bản ghi như trong Hình 3:
Nó hoạt động như thế nào?
Giống như trước đây, chúng tôi sử dụng sơ đồ Kế hoạch để biết cách hoạt động của nó:
Ngoại trừ Phân biệt Sắp xếp trong Hình 2, sơ đồ trên cũng giống như vậy. Điều đó phù hợp bởi vì chúng tôi không muốn lọc ra các bản sao.
Sơ đồ trên cho thấy UNION ALL hoạt động như thế nào. Tóm lại, đây là các bước mà SQL Server sẽ làm theo:
- Truy xuất kết quả của mỗi câu lệnh SELECT.
- Sau đó, kết hợp các kết quả với một toán tử Nối.
Các ví dụ thành công với UNION ALL đều tuân theo mô hình này.
3. Bạn có thể trộn SQL UNION và UNION TẤT CẢ trừ Nhóm chúng bằng dấu ngoặc đơn
Bạn có thể kết hợp việc sử dụng UNION và UNION ALL trong ít nhất ba câu lệnh SELECT.
Sử dụng nó như thế nào?
Bạn kết hợp kết quả của các câu lệnh SELECT với UNION hoặc UNION ALL ở giữa. Dấu ngoặc đơn nhóm các kết quả lại với nhau. Hãy sử dụng cùng một dữ liệu cho ví dụ tiếp theo:
SELECT
c.LastName
,c.FirstName
,c.AccountNumber
FROM dbo.Customer1 c
UNION ALL
(
SELECT
c2.LastName
,c2.FirstName
,c2.AccountNumber
FROM dbo.Customer2 c2
UNION
SELECT
c3.LastName
,c3.FirstName
,c3.AccountNumber
FROM dbo.Customer3 c3
)
Ví dụ trên kết hợp các kết quả của hai câu lệnh SELECT cuối cùng mà không có bản sao. Sau đó, nó kết hợp điều đó với kết quả của câu lệnh SELECT đầu tiên. Kết quả như hình 5 bên dưới:
4. Các cột của mỗi câu lệnh SELECT phải có kiểu dữ liệu tương thích
Các cột trong mỗi câu lệnh SELECT sử dụng UNION có thể có các kiểu dữ liệu khác nhau. Điều đó có thể chấp nhận được miễn là chúng tương thích và cho phép chuyển đổi ngầm đối với chúng. Kiểu dữ liệu cuối cùng của các kết quả được kết hợp sẽ sử dụng kiểu dữ liệu có mức độ ưu tiên cao nhất. Ngoài ra, cơ sở của kích thước dữ liệu cuối cùng là dữ liệu có kích thước lớn nhất. Trong trường hợp chuỗi, nó sẽ sử dụng dữ liệu có số ký tự lớn nhất.
Tại sao điều này lại quan trọng?
Nếu bạn cần chèn kết quả của các UNION vào một bảng, kiểu và kích thước dữ liệu cuối cùng sẽ xác định xem nó có phù hợp với cột của bảng mục tiêu hay không. Nếu không, một lỗi sẽ xảy ra. Ví dụ:một trong các cột trong UNION có kiểu cuối cùng là NVARCHAR (50). Nếu cột mục tiêu của bảng là VARCHAR (50), thì bạn không thể chèn nó vào bảng.
Nó hoạt động như thế nào?
Không có cách nào tốt hơn để giải thích điều đó ngoài một ví dụ:
SELECT N'김지수' AS FullName
UNION
SELECT N'김제니' AS KoreanName
UNION
SELECT N'박채영' AS KoreanName
UNION
SELECT N'ลลิษา มโนบาล' AS ThaiName
UNION
SELECT 'Kim Ji-soo' AS EnglishName
UNION
SELECT 'Jennie Kim' AS EnglishName
UNION
SELECT 'Roseanne Park' AS EnglishName
UNION
SELECT 'Lalisa Manoban' AS EnglishName
Mẫu trên chứa dữ liệu với tên ký tự tiếng Anh, tiếng Hàn và tiếng Thái. Tiếng Thái và tiếng Hàn là các ký tự Unicode. Các ký tự tiếng Anh không. Vì vậy, bạn nghĩ kiểu và kích thước dữ liệu cuối cùng sẽ là bao nhiêu? dbForge Studio hiển thị nó trong tập kết quả:
Bạn có nhận thấy kiểu dữ liệu cuối cùng trong Hình 6 không? Nó không thể là VARCHAR vì các ký tự Unicode. Vì vậy, nó phải là NVARCHAR. Trong khi đó, kích thước không được nhỏ hơn 14 vì dữ liệu có số ký tự lớn nhất có 14 ký tự. Xem chú thích màu đỏ trong Hình 6. Tốt hơn là nên bao gồm loại dữ liệu và kích thước trong tiêu đề cột trong dbForge Studio.
Đây là trường hợp không chỉ dành cho các kiểu dữ liệu chuỗi. Nó cũng áp dụng cho các con số và ngày tháng. Trong khi đó, nếu bạn cố gắng kết hợp dữ liệu với các kiểu dữ liệu không tương thích, lỗi sẽ xảy ra. Xem ví dụ bên dưới:
SELECT CAST('12/25/2020' AS DATE) AS col1
UNION
SELECT CAST('10' AS INT) AS col1
Chúng tôi không thể kết hợp ngày và số nguyên vào một cột. Vì vậy, có thể xảy ra lỗi như bên dưới:
5. Tên cột của kết quả kết hợp sẽ sử dụng tên cột của câu lệnh SELECT đầu tiên
Vấn đề này liên quan đến mẹo trước. Lưu ý các tên cột trong mã trong Mẹo số 4. Có các tên cột khác nhau trong mỗi câu lệnh SELECT. Tuy nhiên, chúng ta đã thấy tên cột cuối cùng trong kết quả tổng hợp ở Hình 6 trước đó. Do đó, cơ sở là tên cột của câu lệnh SELECT đầu tiên.
Tại sao điều này lại quan trọng?
Điều này có thể hữu ích khi bạn cần kết xuất kết quả của UNION trong một bảng tạm thời. Nếu bạn cần tham chiếu đến tên cột của nó trong các câu lệnh tiếp theo, bạn cần phải chắc chắn về các tên đó. Trừ khi bạn đang sử dụng trình chỉnh sửa mã nâng cao với IntelliSense, nếu không bạn sẽ gặp một lỗi khác trong mã T-SQL của mình.
Nó hoạt động như thế nào?
Xem Hình 8 để biết kết quả rõ ràng hơn khi sử dụng dbForge Studio:
6. Thêm ORDER BY trong câu lệnh SELECT cuối cùng với SQL UNION để sắp xếp kết quả
Bạn cần sắp xếp các kết quả kết hợp. Trong một loạt các câu lệnh SELECT có UNION ở giữa, bạn có thể thực hiện điều đó với mệnh đề ORDER BY trong câu lệnh SELECT cuối cùng.
Tại sao điều này lại quan trọng?
Người dùng muốn sắp xếp dữ liệu theo cách họ thích trong ứng dụng, trang web, báo cáo, bảng tính, v.v.
Cách sử dụng
Sử dụng ORDER BY trong câu lệnh SELECT cuối cùng. Đây là một ví dụ:
SELECT
e.BusinessEntityID
,p.FirstName
,p.MiddleName
,p.LastName
,'Employee' AS PersonType
FROM HumanResources.Employee e
INNER JOIN Person.Person p ON e.BusinessEntityID = p.BusinessEntityID
UNION
SELECT
c.PersonID
,p.FirstName
,p.MiddleName
,p.LastName
,'Customer' AS PersonType
FROM Sales.Customer c
INNER JOIN Person.Person p ON c.PersonID = p.BusinessEntityID
ORDER BY p.LastName, p.FirstName
Ví dụ trên làm cho nó trông giống như việc sắp xếp chỉ xảy ra trong câu lệnh SELECT cuối cùng. Nhưng không phải vậy. Nó sẽ hoạt động cho kết quả tổng hợp. Bạn sẽ gặp rắc rối nếu đặt nó trong mỗi câu lệnh SELECT. Xem kết quả:
Nếu không có ORDER BY, tập kết quả sẽ có tất cả Nhân viên Loại người trước tiên là tất cả Khách hàng Loại người . Tuy nhiên, Hình 9 chứng minh rằng các tên trở thành thứ tự sắp xếp của kết quả kết hợp.
Nếu bạn cố gắng đặt ORDER BY trong mỗi câu lệnh SELECT để sắp xếp, đây là điều sẽ xảy ra:
Bạn có nhìn thấy đường nguệch ngoạc trong Hình 10 không? Đó là một cảnh báo. Nếu bạn không nhận thấy và tiếp tục, một lỗi sẽ xuất hiện trong cửa sổ danh sách Lỗi của dbForge Studio.
7. Mệnh đề WHERE và GROUP BY có thể được sử dụng trong mỗi câu lệnh SELECT với SQL UNION
Mệnh đề ORDER BY không hoạt động trong mỗi câu lệnh SELECT với UNION ở giữa. Tuy nhiên, mệnh đề WHERE và GROUP BY hoạt động.
Tại sao điều này lại quan trọng?
Bạn có thể muốn kết hợp kết quả của các truy vấn khác nhau để lọc, đếm hoặc tóm tắt dữ liệu. Ví dụ:bạn có thể thực hiện việc này để nhận tổng số đơn đặt hàng cho tháng 1 năm 2012 và so sánh với tháng 1 năm 2013, tháng 1 năm 2014, v.v.
Cách sử dụng
Đặt mệnh đề WHERE và / hoặc GROUP BY trong mỗi câu lệnh SELECT. Hãy xem ví dụ dưới đây:
USE AdventureWorks
GO
-- Get the number of orders for January 2012, 2013, 2014 for comparison
SELECT
YEAR(soh.OrderDate) AS OrderYear
,COUNT(*) AS NumberOfJanuaryOrders
FROM Sales.SalesOrderHeader soh
WHERE soh.OrderDate BETWEEN '01/01/2012' AND '01/31/2012'
GROUP BY YEAR(soh.OrderDate)
UNION
SELECT
YEAR(soh.OrderDate) AS OrderYear
,COUNT(*) AS NumberOfJanuaryOrders
FROM Sales.SalesOrderHeader soh
WHERE soh.OrderDate BETWEEN '01/01/2013' AND '01/31/2013'
GROUP BY YEAR(soh.OrderDate)
UNION
SELECT
YEAR(soh.OrderDate) AS OrderYear
,COUNT(*) AS NumberOfJanuaryOrders
FROM Sales.SalesOrderHeader soh
WHERE soh.OrderDate BETWEEN '01/01/2014' AND '01/31/2014'
GROUP BY YEAR(soh.OrderDate)
Đoạn mã trên kết hợp số lượng đơn đặt hàng tháng Giêng trong ba năm liên tiếp. Bây giờ, hãy kiểm tra đầu ra:
Ví dụ này cho thấy rằng có thể sử dụng WHERE và GROUP BY trong mỗi câu lệnh trong ba câu lệnh SELECT với UNION.
8. SELECT INTO Hoạt động với SQL UNION
Khi bạn cần chèn kết quả của một truy vấn với SQL UNION vào một bảng, bạn có thể thực hiện việc này bằng cách sử dụng SELECT INTO.
Tại sao điều này lại quan trọng?
Sẽ có lúc bạn cần đặt kết quả của truy vấn với UNION vào một bảng để xử lý thêm.
Cách sử dụng
Đặt mệnh đề INTO trong câu lệnh SELECT đầu tiên. Đây là một ví dụ:
SELECT
YEAR(soh.OrderDate) AS OrderYear
,COUNT(*) AS NumberOfJanuaryOrders
INTO JanuaryOrders
FROM Sales.SalesOrderHeader soh
WHERE soh.OrderDate BETWEEN '01/01/2012' AND '01/31/2012'
GROUP BY YEAR(soh.OrderDate)
UNION
SELECT
YEAR(soh.OrderDate) AS OrderYear
,COUNT(*) AS NumberOfJanuaryOrders
FROM Sales.SalesOrderHeader soh
WHERE soh.OrderDate BETWEEN '01/01/2013' AND '01/31/2013'
GROUP BY YEAR(soh.OrderDate)
UNION
SELECT
YEAR(soh.OrderDate) AS OrderYear
,COUNT(*) AS NumberOfJanuaryOrders
FROM Sales.SalesOrderHeader soh
WHERE soh.OrderDate BETWEEN '01/01/2014' AND '01/31/2014'
GROUP BY YEAR(soh.OrderDate)
Hãy nhớ chỉ đặt một mệnh đề INTO vào câu lệnh SELECT đầu tiên.
Nó hoạt động như thế nào
SQL Server tuân theo mô hình xử lý UNION. Sau đó, nó sẽ chèn kết quả vào bảng được chỉ định trong mệnh đề INTO.
9. Phân biệt SQL UNION với SQL JOIN
Cả SQL UNION và SQL JOIN đều kết hợp dữ liệu bảng, nhưng sự khác biệt về cú pháp và kết quả giống như đêm và ngày.
Tại sao điều này lại quan trọng?
Nếu báo cáo của bạn hoặc bất kỳ yêu cầu nào cần có THAM GIA nhưng bạn đã có ĐOÀN KẾT, kết quả đầu ra sẽ sai.
Cách sử dụng SQL UNION và SQL JOIN
Đó là SQL UNION so với JOIN. Đây là một trong những truy vấn tìm kiếm có liên quan và câu hỏi mà một người mới sử dụng Google thực hiện khi tìm hiểu về SQL UNION. Dưới đây là bảng về sự khác biệt:
LIÊN MINH SQL | THAM GIA SQL | |
Kết hợp là gì | Hàng | Các cột (sử dụng một phím) |
Số cột trên mỗi bảng | Giống nhau cho tất cả các bảng | Biến (Từ 0 đến tất cả các cột / bảng) |
Trong tất cả các dự án mà tôi đã tham gia, SQL JOIN hầu hết đều được áp dụng. Tôi chỉ gặp một số trường hợp sử dụng SQL UNION. Nhưng như bạn đã thấy cho đến nay, SQL UNION không còn là thứ vô dụng.
10. SQL UNION ALL nhanh hơn UNION
Sơ đồ kế hoạch trong Hình 2 và Hình 4 trước đó gợi ý rằng UNION yêu cầu thêm một nhà điều hành để đảm bảo các kết quả duy nhất. Đó là lý do tại sao UNION ALL nhanh hơn.
Tại sao điều này lại quan trọng?
Bạn, người dùng của bạn, khách hàng của bạn, sếp của bạn, tất cả đều muốn có kết quả nhanh chóng. Biết rằng UNION ALL nhanh hơn UNION khiến bạn tự hỏi phải làm gì nếu bạn cần kết quả tổng hợp duy nhất. Có một giải pháp, như bạn sẽ thấy ở phần sau.
SQL UNION ALL so với hiệu suất UNION
Hình 2 và Hình 4 đã cho bạn ý tưởng về cách nào nhanh hơn. Nhưng các mẫu mã được sử dụng rất đơn giản với một tập kết quả nhỏ. Hãy thêm một số so sánh khác bằng cách sử dụng hàng triệu bản ghi để làm cho nó trở nên hấp dẫn.
Để bắt đầu, hãy chuẩn bị dữ liệu:
SELECT TOP (2000000)
val = ROW_NUMBER() OVER (ORDER BY sod.SalesOrderDetailID)
INTO dbo.TestNumbers
FROM AdventureWorks.Sales.SalesOrderDetail sod
CROSS JOIN AdventureWorks.Sales.SalesOrderDetail sod2
Đó là 2 triệu bản ghi. Tôi hy vọng điều đó đủ hấp dẫn. Bây giờ, hãy xem hai mẫu truy vấn tiếp theo bên dưới.
-- Using UNION ALL
SELECT
val
FROM TestNumbers tn
UNION ALL
SELECT
val
FROM TestNumbers tn
-- Using UNION
SELECT
val
FROM TestNumbers tn
UNION
SELECT
val
FROM TestNumbers tn
Hãy kiểm tra các quy trình liên quan đến các truy vấn này bắt đầu với quy trình nhanh hơn.
Phân tích sơ đồ kế hoạch
Sơ đồ trong Hình 12 là điển hình của quy trình UNION ALL. Tuy nhiên, kết quả là 4 triệu kết quả tổng hợp. Xem mũi tên đi ra khỏi toán tử Nối. Tuy nhiên, điều này thường là do nó không xử lý các bản sao.
Bây giờ, hãy có sơ đồ của truy vấn UNION trong Hình 13:
Cái này không còn điển hình nữa. Kế hoạch trở thành một kế hoạch truy vấn song song để giải quyết việc loại bỏ các bản sao trong bốn triệu hàng. Kế hoạch truy vấn song song có nghĩa là SQL Server cần chia quá trình theo số lượng lõi bộ xử lý có sẵn cho nó.
Hãy diễn giải nó, bắt đầu từ các toán tử bên phải sang bên trái:
- Vì chúng tôi đang kết hợp một bảng với chính nó, nên SQL Server cần truy xuất nó hai lần. Xem hai chế độ quét bảng với hai triệu bản ghi mỗi lần.
- Các nhà khai thác Luồng phân vùng lại sẽ kiểm soát việc phân phối từng hàng cho luồng có sẵn tiếp theo.
- Phép ghép nhân đôi kết quả lên bốn triệu. Chúng tôi vẫn đang xem xét số lượng lõi xử lý.
- Kết hợp băm áp dụng để loại bỏ các bản sao. Đây là một quá trình tốn kém với 65,8% chi phí vận hành. Kết quả là, hai triệu bản ghi đã bị loại bỏ.
- Thu thập Luồng kết hợp lại các kết quả được thực hiện trong mỗi lõi hoặc chuỗi bộ xử lý thành một.
Đó là quá nhiều công việc mặc dù quy trình được chia thành nhiều chuỗi. Do đó, bạn sẽ kết luận rằng nó sẽ chạy chậm hơn. Nhưng điều gì sẽ xảy ra nếu có một giải pháp để có được các bản ghi duy nhất với UNION ALL nhưng nhanh hơn thế này?
Kết quả duy nhất nhưng khắc phục nhanh hơn với UNION ALL - Làm thế nào?
Tôi sẽ không bắt bạn phải đợi. Đây là mã:
SELECT DISTINCT
val
FROM
(
SELECT
val
FROM TestNumbers tn
UNION ALL
SELECT
val
FROM TestNumbers tn
) AS uniqtn
Đây có thể là một giải pháp khập khiễng. Nhưng hãy xem Sơ đồ kế hoạch của nó trong Hình 14:
Vì vậy, điều gì đã làm cho nó tốt hơn? Nếu bạn so sánh nó với Hình 13, bạn sẽ thấy các toán tử Repartition Stream đã biến mất. Tuy nhiên, nó vẫn sử dụng nhiều luồng để hoàn thành công việc. Mặt khác, nó ngụ ý rằng trình tối ưu hóa truy vấn coi quá trình này đơn giản hơn để thực hiện so với truy vấn sử dụng UNION.
Chúng ta có thể kết luận một cách an toàn rằng chúng ta nên tránh sử dụng UNION và thay vào đó sử dụng phương pháp này không? Không có gì! Luôn kiểm tra sơ đồ kế hoạch thực thi! Nó luôn phụ thuộc vào những gì bạn muốn SQL Server cung cấp cho bạn. Điều này chỉ cho thấy rằng nếu bạn gặp phải một bức tường hiệu suất, bạn cần phải thay đổi cách tiếp cận truy vấn của mình.
Làm thế nào về Thống kê I / O?
Chúng tôi không thể loại bỏ lượng tài nguyên SQL Server cần để xử lý các ví dụ truy vấn của chúng tôi. Đó là lý do tại sao chúng ta cũng cần kiểm tra IO THỐNG KÊ của họ. So sánh ba truy vấn ở trên, chúng tôi nhận được các bài đọc logic bên dưới:
Từ Hình 15, chúng ta vẫn có thể kết luận rằng UNION ALL nhanh hơn UNION mặc dù các phép đọc logic là như nhau. Sự hiện diện của Bàn làm việc và Workfile hiển thị bằng tempdb để hoàn thành công việc. Trong khi đó, khi chúng tôi sử dụng SELECT DISTINCT từ bảng dẫn xuất với UNION ALL, tempdb sử dụng ít hơn so với UNION. Điều này khẳng định thêm rằng phân tích của chúng tôi từ Sơ đồ kế hoạch trước đó là chính xác.
Làm thế nào về thống kê thời gian?
Mặc dù thời gian trôi qua có thể thay đổi trong mọi lần thực hiện chúng tôi thực hiện với các truy vấn giống nhau, nhưng nó có thể cung cấp cho chúng tôi một số ý tưởng và thêm bằng chứng vào phân tích của chúng tôi. dbForge Studio hiển thị sự khác biệt về thời gian của ba truy vấn trên. So sánh này phù hợp với phân tích trước đây mà chúng tôi đã thực hiện.
Kết luận
Chúng tôi đã trình bày rất nhiều thông tin cơ bản để cung cấp những gì bạn cần để sử dụng SQL UNION và UNION ALL. Bạn có thể không nhớ mọi thứ sau khi đọc bài đăng này, vì vậy hãy nhớ đánh dấu trang này.
Nếu bạn thích bài đăng, hãy chia sẻ nó trên phương tiện truyền thông xã hội.