Apakah permintaan cache MySQL?

19

Saya menghubungkan database MySQL dengan PHP Data Objects (PDO) dan mengeksekusi query SQL yang luas. Biasanya, dibutuhkan sekitar 1500 ms; Saya masih perlu mengoptimalkannya. Ketika saya menjalankan skrip PHP dua kali dengan interval pendek di antaranya, kueri hanya membutuhkan waktu sekitar 90 ms. Kueri dalam kedua kasus sama. Ketika saya menjalankan skrip, dengan permintaan yang sama, setelah beberapa waktu lagi, dibutuhkan 1500 ms lagi.

Mengapa demikian? Apakah basis data cache secara otomatis? Apakah ada waktu database menyimpan cache dan kemudian secara otomatis menghapusnya?

Saya berasumsi hasilnya tidak dapat di-cache oleh PHP, karena ini terjadi dalam dua utas yang berbeda. Saya tidak akan berpikir PHP akan men-cache hasil, karena tidak dapat mengetahui apakah database telah berubah.

Saya memiliki skrip yang berjalan setiap menit untuk menyisipkan baris baru ke database. Ini mungkin juga menjadi alasan bahwa dibutuhkan 1500 ms lagi setelah beberapa waktu; cache sudah dihapus, karena tabel yang relevan tidak sama lagi.

Peter Mortensen
sumber
Tunjukkan kode Anda. Saya tidak membutuhkan permintaan Anda, hanya bagaimana Anda mengujinya.
3
Ya, mySQL menyimpan kueri. Pintar seperti itu.
@Kasyx kode apa? Ini hanya PDO dasar, tapi saya pikir PHP tidak bisa menyimpannya karena saya menjalankan skrip PHP dua kali, saya tidak menjalankan kueri dua kali dalam satu skrip. Bisakah Anda menjelaskan mengapa Anda mengedit pdo sementara itu tidak benar-benar relevan dengan pertanyaan?
3
Semua DBMS memiliki semacam cache tingkat halaman. Banyak melampaui itu dengan caching rencana eksekusi permintaan atau bahkan hasil query (termasuk MySQL ). Saya menduga hal terakhir ini adalah penyebab utama perilaku Anda yang diamati.
Branko Dimitrijevic
Anda melakukan sisipan setiap menit? Atasi itu dulu!
Berikan Thomas

Jawaban:

15

Ini kemungkinan merupakan artefak dari Cache MySQL Query .

Anda menjalankan query SQL, cache hasil dan eksekusi berikutnya jika cepat. Saat Anda menjalankan skrip untuk memasukkan data dalam tabel yang dirujuk oleh kueri Anda, cache hasil menjadi tidak valid dan kueri harus dieksekusi "nyata" di waktu berikutnya.

Dari dokumentasi MySQL yang ditautkan di atas:

Campuran kueri yang terdiri hampir seluruhnya dari sekumpulan statemen SELECT yang tetap jauh lebih mungkin diuntungkan dari mengaktifkan cache daripada campuran di mana pernyataan INSERT yang sering menyebabkan pembatalan hasil yang terus-menerus dalam cache.

Branko Dimitrijevic
sumber
5

Ya, mySQL (yang sama dengan semua produk basis data populer lainnya) membuat cache kueri yang dibuat untuk itu.

Caching ini cukup pintar - sering dapat menggunakan cache untuk kueri bahkan jika parameter persis kueri tidak sama. Ini dapat membuat perbedaan besar untuk kinerja.

Caching dikendalikan sepenuhnya di dalam perangkat lunak server DB; Anda tidak memiliki visibilitas apa pun dari cache berisi, atau berapa lama item yang diberikan tetap dalam cache; itu bisa ditimpa pada saat tertentu tergantung pada pertanyaan apa yang dipanggil, dll. Itu ada untuk membantu kinerja, tetapi tidak boleh diandalkan untuk kinerja.

Anda dapat membaca lebih lanjut tentang ini di sini di manual MySQL .

Selain itu, menggunakan PDO memungkinkan Anda untuk menulis kueri Anda sebagai "Pernyataan yang disiapkan", mengikat parameter daripada mengkodekannya menjadi string kueri teks biasa. Ini juga memiliki implikasi caching pada server DB dan untuk permintaan yang diulang, juga akan meningkatkan kinerja.


sumber
2
"Pada MySQL 5.1.17, cache kueri digunakan untuk pernyataan yang disiapkan di bawah kondisi yang dijelaskan dalam Bagian 8.6.3.1," Bagaimana Cache Query Beroperasi ". Sebelum 5.1.17, cache kueri tidak digunakan untuk laporan yang disiapkan." dev.mysql.com/doc/refman/5.1/en/query-cache.html
1
" sama dengan semua produk database populer lainnya ": itu agak menyesatkan. Hampir tidak ada DBMS yang secara aktif menyimpan hasil kueri seperti yang dilakukan MySQL. DBMS biasanya hanya tabel cache (atau indeks) Data , bukan hasil query . Kebanyakan dari mereka melakukan cache rencana exeution kueri (dan kueri "sumber")
a_horse_with_no_name
3
"sering dapat menggunakan cache untuk kueri bahkan jika parameter tepat kueri tidak sama" benar-benar salah. Permintaan harus byte-untuk-byte yang identik dengan query yang sebelumnya dieksekusi dan masih di-cache untuk dilayani dari cache. Bahkan perbedaan antara SELECT *dan select *berarti permintaan yang identik tidak akan dilayani dari cache. dev.mysql.com/doc/refman/5.1/en/query-cache-operation.html . Diposting tautan 5.1 untuk konsistensi, tetapi berlaku untuk semua versi.
Michael - sqlbot