2010-08-24 34 views
5

Trong cơ sở dữ liệu của tôi tại một số địa điểm, nhà phát triển đã sử dụng sql động thay vì tĩnh. Và họ đang nói lý do cho điều này là để cải thiện hiệu suất. Ai đó có thể cho tôi biết nếu sql động thực sự có thể tăng hiệu suất trong thủ tục lưu trữ hoặc khối plsql?Static vs dynamic sql

Việc nào sẽ thực thi nhanh hơn và tại sao?
1.

begin 
    execute immediate 'delete from X'; 
end; 

2.

begin 
    delete from X; 
end; 
+2

http://publib.boulder.ibm.com/infocenter/db2luw/v8/index.jsp?topic=/com.ibm.db2.udb.doc/ad/c0005785.htm – DumbCoder

+0

Tôi không chắc chắn về các truy vấn như 'xóa khỏi X', nhưng nói chung nếu truy vấn của bạn có thông số, truy vấn động có thể hoạt động nhanh hơn, tôi đã thấy rất nhiều lần. Tại sao? Hình như khi bạn biên dịch DBB của bạn không biết những gì các tham số có thể được và kế hoạch sai có thể được lựa chọn. Trong trường hợp truy vấn động, khi tôi tạo chuỗi với truy vấn và sau đó thực thi nó, tất cả các tham số được chèn vào và kế hoạch thực hiện tốt hơn. Nghe có vẻ kỳ lạ, nhưng khi hiệu suất thì tôi cũng làm theo cách này. Quay lại câu hỏi của bạn -> là các truy vấn của bạn như bạn đã viết, hoặc chúng phức tạp hơn (với các tham số được chèn bởi sproc)? – Maxym

+0

hầu hết các truy vấn đều đơn giản và có thể được viết theo cách tĩnh. Đó là lý do tại sao tôi đã tự hỏi tại sao để đi cho truy vấn động khi nó có thể được viết theo một cách tĩnh. –

Trả lời

12

Mã ví dụ của bạn quá đơn giản nên sẽ có ít sự khác biệt, nhưng trong trường hợp đó, phiên bản tĩnh sẽ có khả năng thực thi tốt hơn.

Lý do chính để sử dụng SQL động cho hiệu suất là khi câu lệnh SQL có thể thay đổi theo cách đáng kể - nghĩa là bạn có thể thêm mã bổ sung vào mệnh đề WHERE tại thời gian chạy dựa trên trạng thái của hệ thống một truy vấn phụ trên Địa chỉ, nếu Địa chỉ đã nhập, v.v.).

Lý do khác là đôi khi sử dụng các biến Bind làm tham số có thể phản tác dụng.

Ví dụ là nếu bạn có thứ gì đó như trường trạng thái, nơi dữ liệu không được phân phối đồng đều (nhưng được lập chỉ mục).

Hãy xem xét 3 câu sau đây, khi 95% dữ liệu được 'P'rocessed

SELECT col FROM table 
    WHERE status = 'U'-- unprocessed 
    AND company = :company 

    SELECT col FROM table 
    WHERE status = 'P' -- processed 
    AND company = :company 

    SELECT col FROM table 
    WHERE status = :status 
    AND company = :company 

Trong phiên bản cuối cùng, Oracle sẽ chọn một kế hoạch chung giải thích. Trong phiên bản đầu tiên, nó có thể quyết định kế hoạch tốt nhất là bắt đầu với chỉ mục về trạng thái (biết rằng 'Các mục nhập chưa được xử lý là một phần rất nhỏ trong tổng số).

Bạn có thể thực hiện điều đó thông qua các câu lệnh tĩnh khác nhau, nhưng khi bạn có các câu lệnh phức tạp hơn chỉ thay đổi bằng một vài ký tự, SQL động có thể là một lựa chọn tốt hơn.

Nhược điểm

Mỗi lặp lại của câu lệnh SQL động cùng gánh chịu một phân tích cú pháp mềm, mà là một chi phí nhỏ so với một tuyên bố tĩnh, nhưng vẫn còn một chi phí.

Mỗi câu lệnh sql MỚI (động hoặc tĩnh) cũng phát sinh một khóa trên SGA (bộ nhớ dùng chung) và có thể dẫn đến các câu lệnh 'cũ'.

Thiết kế hệ thống xấu, nhưng phổ biến là dành cho ai đó sử dụng SQL động để tạo các lựa chọn đơn giản chỉ thay đổi theo khóa - tức là

SELECT col FROM table WHERE id = 5 
SELECT col FROM table WHERE id = 20 
SELECT col FROM table WHERE id = 7 

Báo cáo cá nhân sẽ nhanh chóng, nhưng hiệu suất của toàn bộ hệ thống sẽ xấu đi vì nó đang giết chết tài nguyên được chia sẻ.

Ngoài ra - còn rất khó để bẫy lỗi tại thời gian biên dịch với SQL động. Nếu sử dụng PL/SQL, điều này sẽ làm mất đi một kiểm tra thời gian biên dịch tốt. Ngay cả khi sử dụng một cái gì đó như JDBC (nơi bạn di chuyển tất cả các mã cơ sở dữ liệu của bạn thành chuỗi - ý tưởng tốt!), Bạn có thể nhận được các trình phân tích cú pháp trước để xác thực nội dung JDBC. SQL động = chỉ thử nghiệm thời gian chạy.

phí đầu vào

Các nguyên cần thiết của thực thi ngay lập tức là nhỏ - đó là trong phần nghìn của một giây - tuy nhiên, nó có thể tăng lên nếu điều này là bên trong một vòng lặp/trên một phương pháp gọi là một lần mỗi đối tượng/etc Tôi đã từng cải tiến tốc độ gấp 10 lần bằng cách thay thế SQL động bằng SQL tĩnh được tạo. Tuy nhiên, điều này phức tạp mã, và chỉ được thực hiện bởi vì chúng tôi yêu cầu tốc độ.

+1

JulesLt có những điểm tốt trong câu trả lời và gợi ý về điều gì đó trong việc thảo luận chi phí cần phải nói một cách rõ ràng - đưa ra các cân nhắc biến liên kết, phân tích cú pháp, v.v., THỰC HIỆN NGAY LẬP TỨC trong khối PL/SQL sẽ luôn có bất lợi trên PL tương đương/SQL gọi vì thực thi sẽ liên quan đến một chuyển đổi ngữ cảnh cho công cụ SQL. – dpbradley

0

Thật không may, điều này không khác nhau trên cơ sở từng trường hợp cụ thể.

Đối với các ví dụ cụ thể của bạn, có thể không có sự khác biệt có thể đo lường được. Nhưng đối với một ví dụ phức tạp hơn, bạn có thể muốn kiểm tra mã của riêng bạn.

Liên kết @DumbCoder đưa ra trong các nhận xét có một số quy tắc tuyệt vời của ngón tay cái cũng áp dụng cho Oracle cho hầu hết các phần. Bạn có thể sử dụng một cái gì đó như thế này để hỗ trợ bạn trong việc quyết định, nhưng không có quy tắc đơn giản như "động nhanh hơn tĩnh".