Hiệu suất khác biệt cho COALESCE so với ISNULL?


48

Tôi đã thấy rất nhiều người sử dụng chức năng COALESCE thay cho ISNULL. Từ các tìm kiếm trên internet, tôi đã thấy rằng COALESCE là tiêu chuẩn ANSI, vì vậy có một lợi thế là chúng tôi biết những gì mong đợi khi sử dụng nó. Tuy nhiên, ISNULL có vẻ dễ đọc hơn vì dường như rõ ràng hơn những gì nó đang làm.

Tôi cũng nhận ra rằng ISNULL là một loại khó khăn vì nó hoạt động khác nhau trên các máy chủ cơ sở dữ liệu khác nhau và trong các ngôn ngữ khác nhau.

Tất cả điều đó, trong tâm trí của tôi, sôi sục theo phong cách và tiêu chuẩn. Cho rằng phong cách là chủ quan, có bất kỳ lý do để sử dụng COALESCE trên ISNULL (hoặc ngược lại)? Cụ thể, có lợi thế về hiệu suất của cái này hơn cái kia không?


1
Tôi không thấy được đề cập trong bất kỳ câu trả lời nào mà truy vấn phụ COALESCE được đánh giá hai lần.
Martin Smith

4
"ISNULL có vẻ dễ đọc hơn vì dường như rõ ràng hơn những gì nó đang làm" - thực sự? Tôi thấy cái tên không trực quan: Tôi hy vọng nó sẽ trả về Boolean cho biết liệu một biểu thức được giải quyết thành null hay không xác định. Tên COALESCEchỉ đơn thuần là không trực quan;)
onedaywhen

Câu trả lời:



40
  • ISNULL là Sybase / SQL Server cụ thể
  • COALESCE là xách tay

Sau đó

  • ISNULL nhận 2 đối số
  • COALESCE có các đối số 1-n

Cuối cùng, và một chút thú vị. Kiểu dữ liệu kết quả và độ dài / độ chính xác / tỷ lệ

  • ISNULL giống như đối số đầu tiên
  • COALESCE là cao nhất theo ưu tiên datatype

Bit cuối cùng này là lý do tại sao ISNULL thường được sử dụng vì nó dễ dự đoán hơn (?) Và COALESCE có thể thêm các chuyển đổi loại dữ liệu ngoài ý muốn: đó là nơi bit "chậm hơn" đến từ

DECLARE @len10 varchar(10); --leave it NULL
SELECT
    ISNULL(@len10, '0123456789ABCDEF'),     -- gives 0123456789
    COALESCE(@len10, '0123456789ABCDEF');   -- gives 0123456789ABCDEF

Tất cả các kiểu dữ liệu đều giống nhau, bạn sẽ không thấy bất kỳ sự khác biệt thực tế nào ...


22

Như Mark đã chỉ ra, bạn sẽ khó có thể tìm thấy sự khác biệt về hiệu suất; Tôi nghĩ các yếu tố khác sẽ quan trọng hơn. Đối với tôi, tôi luôn sử dụng COALESCE và hầu hết những điều này đã được bạn hoặc Mark đề cập:

  • COALESCE là tiêu chuẩn ANSI. Đó là một điều ít hơn tôi phải lo lắng nếu tôi sẽ chuyển mã của mình. Đối với cá nhân tôi, điều này không quan trọng lắm, vì tôi biết những cổng như vậy thực sự xảy ra bên ngoài thế giới lớp học của Celko như thế nào, nhưng với một số người thì đây là một lợi ích.
  • Trái với những gì bạn nói về khả năng đọc, tôi thấy việc đọc ISNULL khó hơn, đặc biệt là đối với người dùng đến từ các ngôn ngữ hoặc nền tảng khác nơi ISNULL trả về boolean (không tồn tại trong SQL Server). Cấp, COALESCE khó đánh vần hơn, nhưng ít nhất nó không dẫn đến các giả định không chính xác.
  • COALESCE linh hoạt hơn rất nhiều, vì tôi có thể nói COALESCE (a, b, c, d) trong khi với ISNULL tôi phải làm rất nhiều việc lồng nhau để đạt được điều tương tự.

Bạn cũng nên chắc chắn rằng bạn biết về cách ưu tiên loại dữ liệu được xử lý bằng hai hàm nếu bạn đang sử dụng nó với các loại / quy tắc dữ liệu khác nhau, v.v.

Ghi chú

Có một ngoại lệ. Chúng được xử lý khác nhau trong các phiên bản hiện tại của SQL Server:

SELECT COALESCE((SELECT some_aggregate_query),0); 

SELECT ISNULL((SELECT some_aggregate_query),0); 

Các COALESCEbiến thể sẽ thực sự thực hiện some_aggregate_queryhai lần (một lần để kiểm tra giá trị, và một lần để trả lại khi khác không), trong khi ISNULLsẽ chỉ thực hiện subquery một lần. Tôi nói về một vài sự khác biệt khác ở đây:

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.