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

Làm thế nào để chuyển một tập hợp các hàng từ một hàm này sang một hàm khác?

Các chức năng của bảng

Tôi thực hiện di chuyển cơ sở dữ liệu phức tạp, tốc độ rất cao để kiếm sống, sử dụng SQL làm cả ngôn ngữ máy khách và máy chủ (không sử dụng ngôn ngữ nào khác), tất cả đều chạy phía máy chủ, nơi mã hiếm khi xuất hiện từ cơ sở dữ liệu. Các hàm của bảng đóng một vai trò LỚN trong công việc của tôi . Tôi không sử dụng "con trỏ" vì chúng quá chậm để đáp ứng các yêu cầu về hiệu suất của tôi và mọi thứ tôi làm là theo định hướng tập hợp kết quả. Các hàm bảng đã giúp tôi rất nhiều trong việc loại bỏ hoàn toàn việc sử dụng con trỏ, đạt được tốc độ rất cao và đã góp phần đáng kể vào việc giảm khối lượng mã và cải thiện tính đơn giản.

Tóm lại, bạn sử dụng một truy vấn tham chiếu đến hai (hoặc nhiều) hàm bảng để chuyển dữ liệu từ một hàm bảng sang hàm tiếp theo. Tập hợp kết quả truy vấn chọn gọi các hàm bảng đóng vai trò là đường dẫn để truyền dữ liệu từ một hàm bảng sang hàm tiếp theo. Trên nền tảng / phiên bản DB2 mà tôi đang làm việc, và nó xuất hiện dựa trên việc xem nhanh sổ tay 9.1 Postgres rằng điều này cũng đúng ở đó, bạn chỉ có thể chuyển một hàng giá trị cột duy nhất làm đầu vào cho bất kỳ lệnh gọi hàm bảng nào, như bạn đã khám phá. Tuy nhiên, vì lệnh gọi hàm bảng xảy ra ở giữa quá trình xử lý tập hợp kết quả của truy vấn, bạn đạt được hiệu quả tương tự khi chuyển toàn bộ tập hợp kết quả cho mỗi lệnh gọi hàm bảng, mặc dù, trong hệ thống ống nước của công cụ cơ sở dữ liệu, dữ liệu được chuyển chỉ một hàng tại một thời điểm cho mỗi chức năng của bảng.

Các hàm trong bảng chấp nhận một hàng cột đầu vào và trả về một tập hợp kết quả duy nhất trở lại truy vấn gọi (tức là chọn) được gọi là hàm. Các cột của tập hợp kết quả được trả về từ một hàm bảng sẽ trở thành một phần của tập kết quả của truy vấn đang gọi và do đó có sẵn dưới dạng đầu vào cho hàm bảng tiếp theo , được tham chiếu sau đó trong cùng một truy vấn, thường là một phép nối tiếp theo. Các cột kết quả của hàm bảng đầu tiên được cung cấp dưới dạng đầu vào (một hàng tại một thời điểm) cho hàm bảng thứ hai, trả về các cột tập hợp kết quả của nó vào tập kết quả của truy vấn đang gọi. Cả hai cột kết quả của hàm bảng thứ nhất và thứ nhất hiện là một phần của tập kết quả của truy vấn đang gọi và hiện có sẵn dưới dạng đầu vào (một hàng tại một thời điểm) cho hàm bảng thứ ba. Mỗi lệnh gọi hàm bảng mở rộng tập hợp kết quả của truy vấn gọi thông qua các cột mà nó trả về. Điều này có thể tiếp diễn cho đến khi bạn bắt đầu đạt đến giới hạn về chiều rộng của tập kết quả, có thể thay đổi từ một công cụ cơ sở dữ liệu sang công cụ tiếp theo.

Hãy xem xét ví dụ này (có thể không phù hợp với các yêu cầu hoặc khả năng cú pháp của Postgres khi tôi làm việc trên DB2). Đây là một trong nhiều mẫu thiết kế mà tôi sử dụng các hàm bảng, là một trong những mẫu đơn giản hơn, mà tôi nghĩ là rất minh họa và một mẫu mà tôi dự đoán sẽ có sức hấp dẫn rộng rãi nếu các hàm bảng được sử dụng phổ biến (theo hiểu biết của tôi thì không, nhưng tôi nghĩ chúng đáng được chú ý hơn những gì chúng đang nhận được).

Trong ví dụ này, các hàm bảng đang được sử dụng là:VALIDATE_TODAYS_ORDER_BATCH, POST_TODAYS_ORDER_BATCH và DATA_WAREHOUSE_TODAYS_ORDER_BATCH. Trên phiên bản DB2 mà tôi đang làm việc, bạn bọc hàm bảng bên trong "TABLE (đặt lệnh gọi hàm bảng và các tham số ở đây)", nhưng dựa trên việc xem nhanh sách hướng dẫn Postgres, có vẻ như bạn đã bỏ qua trình bao bọc "TABLE ()".

create table TODAYS_ORDER_PROCESSING_EXCEPTIONS as (

select      TODAYS_ORDER_BATCH.*
           ,VALIDATION_RESULT.ROW_VALID
           ,POST_RESULT.ROW_POSTED
           ,WAREHOUSE_RESULT.ROW_WAREHOUSED

from        TODAYS_ORDER_BATCH

cross join  VALIDATE_TODAYS_ORDER_BATCH ( ORDER_NUMBER, [either pass the remainder of the order columns or fetch them in the function]  ) 
              as VALIDATION_RESULT ( ROW_VALID )  --example: 1/0 true/false Boolean returned

left join   POST_TODAYS_ORDER_BATCH ( ORDER_NUMBER, [either pass the remainder of the order columns or fetch them in the function] )
              as POST_RESULT ( ROW_POSTED )  --example: 1/0 true/false Boolean returned
      on    ROW_VALIDATED = '1'

left join   DATA_WAREHOUSE_TODAYS_ORDER_BATCH ( ORDER_NUMBER, [either pass the remainder of the order columns or fetch them in the function] )
              as WAREHOUSE_RESULT ( ROW_WAREHOUSED )  --example: 1/0 true/false Boolean returned
      on    ROW_POSTED = '1'

where       coalesce( ROW_VALID,      '0' ) = '0'   --Capture only exceptions and unprocessed work.  
      or    coalesce( ROW_POSTED,     '0' ) = '0'   --Or, you can flip the logic to capture only successful rows.
      or    coalesce( ROW_WAREHOUSED, '0' ) = '0'

) with data
  1. Nếu bảng TODAYS_ORDER_BATCH chứa 1.000.000 hàng, thìVALIDATE_TODAYS_ORDER_BATCH sẽ được gọi 1.000.000 lần, sau khi bỏ qua hàng.
  2. Nếu 900.000 hàng vượt qua xác thực bên trong VALIDATE_TODAYS_ORDER_BATCH, thì POST_TODAYS_ORDER_BATCH sẽ được gọi là 900.000 lần.
  3. Nếu chỉ có 850.000 hàng đăng thành công, thì VALIDATE_TODAYS_ORDER_BATCH cần một số sơ hở để đóng LOL và DATA_WAREHOUSE_TODAYS_ORDER_BATCH sẽ được gọi 850.000 lần.
  4. Nếu 850.000 hàng được đưa vào Kho dữ liệu thành công (tức là không có ngoại lệ bổ sung nào được tạo), thì bảng TODAYS_ORDER_PROCESSING_EXCEPTIONS sẽ có 1.000.000 - 850.000 =150.000 hàng ngoại lệ.

Các lệnh gọi hàm bảng trong ví dụ này chỉ trả về một cột duy nhất, nhưng chúng có thể trả về nhiều cột. Ví dụ:hàm bảng xác thực một hàng đơn hàng có thể trả về lý do tại sao một đơn hàng không xác thực được.

Trong thiết kế này, hầu như tất cả các cuộc nói chuyện giữa một HLL và cơ sở dữ liệu bị loại bỏ, vì người yêu cầu HLL đang yêu cầu cơ sở dữ liệu xử lý toàn bộ lô trong MỘT yêu cầu. Điều này dẫn đến việc giảm hàng triệu yêu cầu SQL tới cơ sở dữ liệu, loại bỏ KHỔNG LỒ hàng triệu lệnh gọi thủ tục hoặc phương thức HLL và kết quả là cải thiện thời gian chạy LỚN. Ngược lại, mã kế thừa thường xử lý một hàng tại một thời điểm, thường sẽ gửi 1.000.000 yêu cầu SQL tìm nạp, 1 cho mỗi hàng trong TODAYS_ORDER_BATCH, cộng với ít nhất 1.000.000 yêu cầu HLL và / hoặc SQL cho mục đích xác thực, cộng với ít nhất 1.000.000 HLL và / hoặc SQL yêu cầu cho mục đích đăng, cộng với 1.000.000 yêu cầu HLL và / hoặc SQL để gửi đơn đặt hàng đến kho dữ liệu. Được cấp, sử dụng thiết kế hàm bảng này, bên trong các hàm bảng Các yêu cầu SQL đang được gửi đến cơ sở dữ liệu, nhưng khi cơ sở dữ liệu thực hiện các yêu cầu cho chính nó (tức là từ bên trong một hàm bảng), các yêu cầu SQL được phục vụ nhanh hơn nhiều (đặc biệt là so với một tình huống kế thừa trong đó người yêu cầu HLL đang thực hiện xử lý hàng đơn từ một hệ thống từ xa, với trường hợp xấu nhất là qua mạng WAN - OMG vui lòng không làm điều đó).

Bạn có thể dễ dàng gặp phải các vấn đề về hiệu suất nếu bạn sử dụng một hàm bảng để "tìm nạp một tập hợp kết quả" và sau đó nối tập kết quả đó với các bảng khác. Trong trường hợp đó, trình tối ưu hóa SQL không thể dự đoán tập hợp hàng nào sẽ được trả về từ hàm bảng và do đó nó không thể tối ưu hóa việc kết hợp với các bảng tiếp theo. Vì lý do đó, tôi hiếm khi sử dụng chúng để tìm nạp tập kết quả, trừ khi tôi biết tập kết quả đó sẽ là một số rất nhỏ hàng, do đó không gây ra sự cố về hiệu suất hoặc tôi không cần tham gia vào các bảng tiếp theo.

Theo ý kiến ​​của tôi, một lý do tại sao các hàm bảng không được tận dụng là chúng thường được coi là công cụ chỉ để tìm nạp một tập kết quả, thường hoạt động kém, vì vậy chúng bị coi là một công cụ "kém" để sử dụng.

Các hàm bảng vô cùng hữu ích để đẩy nhiều chức năng hơn cho máy chủ, để loại bỏ hầu hết các cuộc nói chuyện giữa máy chủ cơ sở dữ liệu và các chương trình trên hệ thống từ xa và thậm chí để loại bỏ các cuộc nói chuyện giữa máy chủ cơ sở dữ liệu và các chương trình bên ngoài trên cùng một máy chủ. Ngay cả việc trò chuyện giữa các chương trình trên cùng một máy chủ cũng mang lại nhiều chi phí hơn nhiều người nhận ra, và phần lớn là không cần thiết. Trọng tâm của sức mạnh của các hàm bảng nằm ở việc sử dụng chúng để thực hiện các hành động bên trong quá trình xử lý tập kết quả.

Có nhiều mẫu thiết kế nâng cao hơn để sử dụng các hàm bảng dựa trên mẫu trên, nơi bạn có thể tối đa hóa quá trình xử lý tập hợp kết quả hơn nữa, nhưng bài đăng này còn rất nhiều thứ mà hầu hết mọi người đều phải hấp thụ.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cách make_interval () hoạt động trong PostgreSQL

  2. FATAL:vai trò gốc không tồn tại

  3. PostgreSQL 11:Có gì mới

  4. Chạy PostgreSQL CLI (psql) trong tập lệnh bash mà không có lời nhắc mật khẩu?

  5. Hàm MIN () trong PostgreSQL