2010-01-11 28 views
13

Tôi đã học về các câu lệnh chuẩn bị khi tạo một ứng dụng Java có hỗ trợ JDBC và ứng dụng của tôi sử dụng lớp kết nối kết nối đảm bảo với tôi rằng các câu lệnh đã chuẩn bị được lưu trữ phía máy chủ và điều này mang lại lợi ích hiệu suất.Các câu lệnh chuẩn bị được lưu trữ phía máy chủ có được tải trên nhiều trang với PHP không?

Tuy nhiên, với tất cả mọi thứ PHP tôi đã đọc nói rằng chúng chỉ được lưu trong bộ nhớ cache cho thời gian tải trang. Nói chung tôi không lặp lại cùng một truy vấn nhiều lần, nhưng chạy một số truy vấn khác nhau, trên một lần tải trang nhất định, nhưng sẽ lặp lại chúng trên nhiều lần tải trang.

Khi các quy trình PHP của tôi liên tục (nghĩa là chúng sẽ phục vụ hàng trăm trang trong vòng đời của chúng thay vì chỉ sử dụng PHP-FPM), tôi tự hỏi liệu chúng có sử dụng lại các kết nối cơ sở dữ liệu hay không. tắt cho mỗi lần truy cập.

  1. Việc sử dụng PHP-FPM với mysqli hoặc PDO có giữ kết nối lâu hơn một lần tải trang không?
  2. Nếu không, tôi có thể làm được không?
  3. Nếu có, hoặc tôi làm # 2, điều này sẽ tiếp tục lưu bộ nhớ cache của các câu lệnh đã chuẩn bị lâu hơn chỉ một lần tải trang không?

Edit:

Chỉ cần làm rõ, tôi không nói về bộ nhớ cache truy vấn, mà là con thú hoàn toàn khác, hoặc bộ nhớ đệm đầu ra của truy vấn. Tôi muốn cache câu lệnh đã chuẩn bị đã biên dịch và phía máy chủ kế hoạch thực hiện của nó.

Trả lời

12

Khi một yêu cầu được phục vụ php "làm sạch" các trường hợp và giải phóng tài nguyên và các biến khác. Điều này được thực hiện trong một vài bước. Kể từ fastcgi giữ cho quá trình còn sống sau khi một yêu cầu không phải tất cả các bước được thực hiện và không phải tất cả bộ nhớ được giải phóng. Có ví dụ EG (persistent_list) được sử dụng bởi mysql_pconnect(), pg_pconnect(), ... Danh sách này không được dọn sạch giữa các yêu cầu miễn là quá trình này vẫn còn sống (có thể, tùy thuộc vào việc thực hiện thực tế, nhưng điều đó sẽ thách thức mục đích của EG (persistent_list))). Nếu bạn sử dụng kết nối liên tục, tập lệnh của bạn có thể nhận được kết nối "được sử dụng lại" được thiết lập trong yêu cầu trước đó.
Để (lại) sử dụng câu lệnh đã chuẩn bị trực tiếp, bạn cần số nhận dạng cho câu lệnh đó (và kết nối đó). Khi sử dụng postgresql (php-), đây chỉ đơn giản là chuỗi duy nhất (kết nối khôn ngoan) mà bạn chuyển đến pg_execute(), do đó, tập lệnh của bạn không có vấn đề gì để truy cập vào câu lệnh đã được chuẩn bị trước đó (sử dụng cùng kết nối).
Sử dụng mysqli hoặc PDO-mysql bạn cần tài nguyên/đối tượng làm định danh tuyên bố. Đó là một vấn đề vì cả mysqli lẫn phần mở rộng pdo đều không cung cấp cách lưu trữ tài nguyên trong EG (persist_list) giữa các yêu cầu và bạn cũng không thể tạo lại nó. Trừ khi php-fpm cung cấp một "dịch vụ" như vậy, có vẻ như không thể tái sử dụng câu lệnh chuẩn bị mysql trực tiếp.
Tất cả những gì bạn có thể hy vọng là số server-side query cache của MySQL. Trong các phiên bản gần đây (xem liên kết), nó có thể nhận ra câu lệnh khi sử dụng các câu lệnh đã chuẩn bị. Nhưng ngay cả khi nó không tái sử dụng câu lệnh chuẩn bị thực tế:

Đối với câu lệnh chuẩn bị được thực hiện qua giao thức nhị phân, so sánh với câu lệnh trong bộ nhớ truy vấn dựa trên văn bản của câu lệnh sau khi mở rộng? dấu tham số. Câu lệnh được so sánh chỉ với các câu lệnh được lưu trong bộ nhớ cache khác đã được thực thi thông qua giao thức nhị phân. Đó là, cho các mục đích bộ nhớ cache truy vấn, các câu lệnh được phát hành thông qua giao thức nhị phân là khác biệt với các câu lệnh được phát hành thông qua giao thức văn bản.

Vì vậy, nếu tôi không nhầm, hiện tại bạn không thể sử dụng lại câu lệnh mysql được chuẩn bị trong một yêu cầu trước đó trong php.

+0

Nếu tôi đang sử dụng postgresql, sẽ chuẩn bị một câu lệnh đã được chuẩn bị tự động truy cập vào câu lệnh đã được chuẩn bị trước đó, hoặc tôi sẽ phải thực hiện một số phép thuật để phát hiện xem câu lệnh đã được chuẩn bị chưa? Tôi sẽ sẵn sàng để chuyển từ MySQL cho việc này. – ZoFreX

+0

Mã nhận diện câu lệnh bạn chuyển tới pq_prepare() phải là duy nhất cho mỗi kết nối. I E. nếu trường hợp thứ hai (hoặc Nth) của tập lệnh cố gắng chuẩn bị câu lệnh một lần nữa với cùng tên, một lỗi cụ thể sẽ xảy ra. Kịch bản lệnh của bạn có thể xử lý mã lỗi đó và giả sử rằng câu lệnh (phải) đã được chuẩn bị và sẵn sàng sử dụng. Nó vẫn còn một chút chi phí và bạn có thể muốn chuẩn cho hiệu ứng ròng mà bạn có thể mong đợi trước khi đầu tư quá nhiều tiền. – VolkerK

-1

Báo cáo được chuẩn bị không có gì liên quan đến bộ nhớ đệm kết quả.

Kết quả bộ nhớ đệm có thể được kiểm soát thông qua cấu hình máy chủ db hoặc bị buộc qua memcached và tương tự.

Tôi đề nghị bạn nhìn vào memcached, đặc biệt là cho PHP http://www.php.net/manual/en/book.memcached.php

+0

Tôi đang tìm câu lệnh chuẩn bị bộ nhớ cache truy vấn có thể nhận được. Biên dịch các câu lệnh và lưu vào bộ nhớ đệm "kế hoạch thực hiện" (đúng thuật ngữ xin vui lòng?) Là rất nhiều lợi ích mà các câu lệnh chuẩn bị có thể cung cấp. Tôi đã sử dụng memcached cho bộ nhớ đệm kết quả và nó thực sự là tuyệt vời! – ZoFreX

2

Nếu ứng dụng PHP của bạn sử dụng kết nối tổng hợp cơ sở dữ liệu, và lưu trữ cơ sở dữ liệu chuẩn bị báo cáo, sau đó có, bộ nhớ đệm sẽ tồn tại giữa các trang. Nếu bộ nhớ đệm báo cáo đã chuẩn bị được thực hiện bởi thư viện máy khách, thì điều này là vô nghĩa.

Bạn cần xem tài liệu về PHP-FPM và/hoặc PDO để xem cách yêu cầu họ sử dụng kết nối tổng hợp. Nên có một lựa chọn trong cả hai để làm điều đó.

Bạn nên biết rằng thiết lập kết nối MySQL và teardown thực sự là rất nhanh và nhiều cài đặt PHP không sử dụng kết nối tổng hợp vì điều này. Dù bằng cách nào, bạn cũng nên đầu tư thời gian vào cài đặt máy chủ của mình, đặc biệt là thông số wait_timeout. PHP cũng được thiết kế xung quanh ý tưởng rằng bạn tạo mọi thứ bạn cần khi trang của bạn bắt đầu và tất cả đều biến mất khi trang kết thúc. Hầu hết các mã PHP và thư viện giả định đây là trường hợp. Đó là một mô hình hoàn toàn khác với Java.

+0

Tôi có nên sử dụng PDO và không phải mysqli sau đó? – ZoFreX

+0

Cả hai cung cấp các API hơi khác nhau; nó không phải là một trường hợp đơn giản của một trong hai hoặc. Tôi, cá nhân, sẽ sử dụng mysqli, nhưng sau đó đó là bởi vì tôi có bộ xử lý của riêng tôi mà mở rộng mysqli theo cách tôi muốn. – staticsan

2

Câu trả lời đúng duy nhất là phụ thuộc vào.

Báo cáo chuẩn bị là những con thú khó tính khi nói đến MySQL. Có một số lượng lớn các yếu tố xác định liệu một câu lệnh chuẩn bị có được lưu trữ hay không.

Ý tưởng chung là nếu phiên bản của bạn là < 5.1.17, câu lệnh đã chuẩn bị là không bao giờ được lưu trong bộ nhớ cache truy vấn và nếu sử dụng> = 5.1.17, nó phụ thuộc.

Vui lòng xem trang sau trong 5.1 dẫn sử dụng MySQL:

http://dev.mysql.com/doc/refman/5.1/en/query-cache-operation.html

-1

PHP không lưu trữ truy vấn cũng như kết quả truy vấn trong hầu hết các trường hợp. MySQL sẽ thực hiện loại bộ nhớ đệm này bất kể hoặc chuỗi hoặc kết nối nào đang phát hành truy vấn.

Nếu bạn muốn lưu trữ phía máy chủ qua nhiều lần tải trang hoặc nhiều máy chủ, hãy sử dụng bộ đệm truy vấn MySQL và bộ nhớ đệm phía máy chủ (APC, bộ nhớ đệm dựa trên tệp, memcached, v.v.).

4

Bạn đang bối rối những gì đang xảy ra ở cấp PHP/Java với những gì xảy ra trong cơ sở dữ liệu.

Có, sử dụng câu lệnh chuẩn bị (thường) có nghĩa là kế hoạch thực hiện được lưu vào bộ nhớ cache bởi chính cơ sở dữ liệu (KHÔNG phải lớp PHP/Java). Tuy nhiên nó không làm theo đó điều này luôn luôn dẫn đến hiệu suất tốt hơn - và một lời giải thích về điều này sẽ mất vài trăm trang. Tuy nhiên tôi suy ra từ những gì bạn đã nói ở nơi khác bạn đang sử dụng MySQL như DBMS mà làm cho các cuộc thảo luận hơi đơn giản (IIRC không có công cụ lưu trữ thực hiện biểu đồ). Thông thường MySQL sẽ có thể lưu trữ đủ thông tin về một lược đồ để có thể tạo ra một kế hoạch mà không có bất kỳ đĩa I/O nào. OTOH, sử dụng câu lệnh chuẩn bị có nghĩa là tối thiểu ba chuyến đi vòng tới DBMS cho mỗi truy vấn (câu lệnh hiện tại, tham số hiện tại, truy xuất kết quả) trong khi sử dụng giá trị nội tuyến loại bỏ trên các chuyến đi khứ hồi này.Trong trường hợp không có chỉ mục biểu đồ, giá trị của các biến không liên quan đến kế hoạch tối ưu có thể phát hiện được bởi trình tối ưu hóa.

Thực tế là bạn đang sử dụng PHP, hoặc PHP-FPM hoặc Java với các kết nối đơn hoặc liên tục hoặc gộp lại không liên quan đến việc các câu lệnh chuẩn bị có được lưu trữ/tái sử dụng bởi DBMS hay không.

HTH

C.

+0

Lưu ý PHP-FPM không hoạt động như một máy chủ ứng dụng java. Các cấu trúc dữ liệu người dùng vẫn bị hủy ở cuối mỗi yêu cầu. Nhưng điều này vẫn không liên quan đến bộ nhớ đệm báo cáo. – symcbean

2

bạn có thể buộc mysqli để tạo ra một kết nối liên tục bởi prepending p: đến hostname, theo php doc: http://www.php.net/manual/en/mysqli.persistconns.php

Tuy nhiên, báo cáo chuẩn bị luôn đóng giữa các lần tải trang, như được thảo luận tại đây: http://dev.mysql.com/doc/refman/5.0/en/apis-php-mysqli.persistconns.html

Xin lỗi, bạn không thể thực hiện theo như tôi biết. Các câu lệnh được chuẩn bị chỉ dành cho một lần tải trang.

+0

Chỉ cần là một người đi bộ ... Bạn cần phải thêm vào trước "p:" không nối thêm – Basic

Các vấn đề liên quan