mata utama
EXPLAIN
EXPLAIN
untuk mempercepat pengambilan data dan meningkatkan prestasi pertanyaan. WHERE
LIKE
ORDER BY
, kerana ia boleh mengimbangi kelebihan prestasi yang mengehadkan hasil, terutamanya jika indeks tidak digunakan dengan berkesan. LIMIT
Alat mudah dan berkesan ialah analisis pertanyaan. Analisis yang membolehkan membolehkan anggaran yang lebih tepat mengenai masa larian pertanyaan. Ini adalah proses dua langkah: pertama, membolehkan analisis;
show profiles
Katakan operasi penyisipan berikut wujud dalam pangkalan data (dan mengandaikan bahawa Pengguna 1 dan Galeri 1 telah dibuat):
Sejumlah kecil data tidak akan menyebabkan masalah, tetapi kita boleh menggunakannya untuk analisis mudah. Pertimbangkan pertanyaan berikut:
INSERT INTO `homestead`.`images` (`id`, `gallery_id`, `original_filename`, `filename`, `description`) VALUES (1, 1, 'me.jpg', 'me.jpg', 'A photo of me walking down the street'), (2, 1, 'dog.jpg', 'dog.jpg', 'A photo of my dog on the street'), (3, 1, 'cat.jpg', 'cat.jpg', 'A photo of my cat walking down the street'), (4, 1, 'purr.jpg', 'purr.jpg', 'A photo of my cat purring');
Jika terdapat banyak entri foto, pertanyaan ini mungkin menjadi masalah pada masa akan datang.
SELECT * FROM `homestead`.`images` AS i WHERE i.description LIKE '%street%';
Untuk mendapatkan masa berjalan tepat pertanyaan ini, anda boleh menggunakan SQL berikut:
Hasilnya adalah seperti berikut:
set profiling = 1; SELECT * FROM `homestead`.`images` AS i WHERE i.description LIKE '%street%'; show profiles;
Perintah
show profiles;
bukan sahaja memaparkan masa pertanyaan asal, tetapi juga masa semua pertanyaan lain, supaya pertanyaan dapat dianalisis dengan tepat.
bagaimana untuk meningkatkan pertanyaan?
Anda boleh bergantung pada pengetahuan SQL untuk memperbaiki, atau bergantung pada perintah MySQL EXPLAIN
dan meningkatkan prestasi pertanyaan berdasarkan maklumat sebenar.
EXPLAIN
digunakan untuk mendapatkan pelan pelaksanaan pertanyaan, iaitu, bagaimana MySQL melaksanakan pertanyaan. Ia sesuai untuk SELECT
, DELETE
, INSERT
, REPLACE
, dan UPDATE
pernyataan dan memaparkan maklumat mengenai pelan pelaksanaan pernyataan oleh pengoptimum. Dokumentasi rasmi menerangkan dengan baik bagaimana EXPLAIN
bagaimana
untuk memeriksa sama ada pengoptimal menyertai jadual dalam urutan terbaik.
EXPLAIN
denganEXPLAIN
, anda dapat melihat jadual mana yang harus anda tambahkan indeks supaya pernyataan dapat dilaksanakan dengan lebih cepat dengan menggunakan indeks untuk mencari baris. Anda juga boleh menggunakan
EXPLAIN
Untuk memberi contoh untuk menggambarkan penggunaan UserManager.php
, kami akan menggunakan pertanyaan untuk mencari e -mel pengguna dalam
INSERT INTO `homestead`.`images` (`id`, `gallery_id`, `original_filename`, `filename`, `description`) VALUES (1, 1, 'me.jpg', 'me.jpg', 'A photo of me walking down the street'), (2, 1, 'dog.jpg', 'dog.jpg', 'A photo of my dog on the street'), (3, 1, 'cat.jpg', 'cat.jpg', 'A photo of my cat walking down the street'), (4, 1, 'purr.jpg', 'purr.jpg', 'A photo of my cat purring');
EXPLAIN
untuk menggunakan perintah SELECT
, tambahkannya sebelum pertanyaan jenis
SELECT * FROM `homestead`.`images` AS i WHERE i.description LIKE '%street%';
Hasilnya adalah seperti berikut (tatal ke kanan untuk melihat segala -galanya):
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | users | NULL | const | UNIQ_1483A5E9E7927C74 | UNIQ_1483A5E9E7927C74 | 182 | const | 1 | 100.00 | NULL |
Keputusan ini tidak mudah difahami pada mulanya, mari kita lihat dengan lebih dekat setiap satu:
id
: Ini adalah pengecam berurutan untuk setiap pertanyaan dalam SELECT
. select_type
: SELECT
Jenis pertanyaan. Bidang ini boleh mengambil pelbagai nilai yang berbeza, jadi kami akan memberi tumpuan kepada yang paling penting: SIMPLE
: pertanyaan mudah tanpa subqueries atau kesatuan PRIMARY
: select
terletak di pertanyaan paling luar dalam sambungan DERIVED
: select
adalah sebahagian daripada pertanyaan neutron from
SUBQUERY
select
UNION
adalah pernyataan kesatuan kedua atau berikutnya.
Senarai lengkap nilai select
medan boleh didapati di sini. select_type
table
type
. Ia boleh menunjukkan indeks yang hilang, atau ia dapat menunjukkan bagaimana pertanyaan ditindih. Nilai yang mungkin untuk medan ini adalah seperti berikut (disusun dari yang terbaik ke jenis terburuk): EXPLAIN
system
const
eq_ref
atau PRIMARY_KEY
. UNIQUE NOT NULL
ref
atau pengendali. =
fulltext
ref_or_null
, tetapi juga mengandungi baris dari nilai ref
lajur. NULL
index_merge
EXPLAIN
akan mengandungi kekunci yang digunakan. KEY
unique_subquery
subquery mengembalikan hanya satu hasil dari meja dan menggunakan kunci utama. IN
range
index
ALL
possible_keys
keys
tetapi lebih baik. possible_keys
key_len
ref
.rows
: Menyenaraikan bilangan rekod yang diperiksa untuk menjana output. Ini adalah penunjuk yang sangat penting; Extra
: Mengandungi maklumat lain. Bersamaan Using filesort
atau Using temporary
dalam lajur ini boleh menunjukkan pertanyaan yang dipersoalkan. EXPLAIN
Dokumentasi lengkap format output boleh didapati di halaman MySQL rasmi.
Kembali ke pertanyaan mudah kami: ia adalah SIMPLE
taip select
dengan sambungan const
jenis. Ini adalah kes pertanyaan terbaik yang mungkin kita ada. Tetapi apa yang berlaku apabila kita memerlukan pertanyaan yang lebih besar dan lebih kompleks?
Kembali ke mod aplikasi kami, kami mungkin ingin mendapatkan semua imej galeri. Kami juga mungkin mahu memasukkan hanya foto dengan perkataan "kucing" dalam keterangan. Ini pastinya situasi yang dapat kita temukan dalam keperluan projek. Mari lihat pertanyaan:
INSERT INTO `homestead`.`images` (`id`, `gallery_id`, `original_filename`, `filename`, `description`) VALUES (1, 1, 'me.jpg', 'me.jpg', 'A photo of me walking down the street'), (2, 1, 'dog.jpg', 'dog.jpg', 'A photo of my dog on the street'), (3, 1, 'cat.jpg', 'cat.jpg', 'A photo of my cat walking down the street'), (4, 1, 'purr.jpg', 'purr.jpg', 'A photo of my cat purring');
Dalam keadaan yang lebih kompleks ini, kita harus mendapatkan lebih banyak maklumat dalam EXPLAIN
untuk menganalisis:
SELECT * FROM `homestead`.`images` AS i WHERE i.description LIKE '%street%';
ini akan memberikan hasil berikut (tatal ke kanan untuk melihat semua sel):
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | users | NULL | index | PRIMARY,UNIQ_1483A5E9BF396750 | UNIQ_1483A5E9BF396750 | 108 | NULL | 1 | 100.00 | Using index |
1 | SIMPLE | gal | NULL | ref | PRIMARY,UNIQ_F70E6EB7BF396750,IDX_F70E6EB7A76ED395 | UNIQ_1483A5E9BF396750 | 108 | homestead.users.id | 1 | 100.00 | NULL |
1 | SIMPLE | img | NULL | ref | IDX_E01FBE6A4E7AF8F | IDX_E01FBE6A4E7AF8F | 109 | homestead.gal.id | 1 | 25.00 | Using where |
mari kita lihat lebih dekat dan lihat apa yang dapat kita tingkatkan dalam pertanyaan.
Seperti yang dinyatakan sebelum ini, lajur utama yang harus dilihat terlebih dahulu ialah lajur type
dan rows
lajur. Matlamatnya adalah untuk mendapatkan nilai yang lebih baik dalam lajur type
dan meminimumkan nilai lajur rows
.
Hasil pertanyaan pertama ialah index
, yang bukan hasil yang baik sama sekali. Ini bermakna kita mungkin dapat memperbaikinya.
Lihat pertanyaan kami, terdapat dua cara untuk menyelesaikannya. Pertama, jadual Users
tidak digunakan. Kami sama ada memperluaskan pertanyaan untuk memastikan kami mensasarkan pengguna atau kami harus memadamkan bahagian pengguna pertanyaan sepenuhnya. Ia hanya meningkatkan kerumitan dan masa prestasi keseluruhan kami.
INSERT INTO `homestead`.`images` (`id`, `gallery_id`, `original_filename`, `filename`, `description`) VALUES (1, 1, 'me.jpg', 'me.jpg', 'A photo of me walking down the street'), (2, 1, 'dog.jpg', 'dog.jpg', 'A photo of my dog on the street'), (3, 1, 'cat.jpg', 'cat.jpg', 'A photo of my cat walking down the street'), (4, 1, 'purr.jpg', 'purr.jpg', 'A photo of my cat purring');
Jadi sekarang kita mendapat hasil yang sama. Mari kita lihat EXPLAIN
:
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | gal | NULL | ALL | PRIMARY,UNIQ_1483A5E9BF396750 | NULL | NULL | NULL | 1 | 100.00 | NULL |
1 | SIMPLE | img | NULL | ref | IDX_E01FBE6A4E7AF8F | IDX_E01FBE6A4E7AF8F | 109 | homestead.gal.id | 1 | 25.00 | Using where |
Apa yang kita tinggalkan ialah jenis ALL
. Walaupun ALL
mungkin jenis sambungan yang paling teruk, terdapat beberapa kes di mana ia adalah satu -satunya pilihan. Mengikut keperluan kami, kami mahu semua imej galeri, jadi kami perlu mencari jadual keseluruhan galleries
. Apabila kita memerlukan semua maklumat di dalam jadual, indeks sangat bagus apabila cuba mencari maklumat khusus di dalam jadual, tetapi mereka tidak membantu kami. Apabila kita menghadapi keadaan ini, kita perlu menggunakan kaedah lain, seperti caching.
Oleh kerana kita sedang mengusahakan LIKE
, peningkatan terakhir yang boleh kita buat ialah menambah indeks teks penuh ke medan description
kami. Dengan cara ini, kita boleh menukar LIKE
ke match()
dan meningkatkan prestasi. Maklumat lanjut mengenai pengindeksan teks penuh boleh didapati di sini.
kita juga perlu menyemak dua situasi yang sangat menarik: ciri -ciri terkini dan berkaitan dalam aplikasi. Ini berlaku untuk galeri dan melibatkan beberapa situasi yang melampau yang harus kita perhatikan:
INSERT INTO `homestead`.`images` (`id`, `gallery_id`, `original_filename`, `filename`, `description`) VALUES (1, 1, 'me.jpg', 'me.jpg', 'A photo of me walking down the street'), (2, 1, 'dog.jpg', 'dog.jpg', 'A photo of my dog on the street'), (3, 1, 'cat.jpg', 'cat.jpg', 'A photo of my cat walking down the street'), (4, 1, 'purr.jpg', 'purr.jpg', 'A photo of my cat purring');
di atas adalah galeri yang berkaitan.
SELECT * FROM `homestead`.`images` AS i WHERE i.description LIKE '%street%';
di atas adalah galeri terkini.
Pada pandangan pertama, pertanyaan ini harus sangat cepat kerana mereka menggunakan LIMIT
. Ini berlaku dalam kebanyakan pertanyaan yang menggunakan LIMIT
. Malangnya bagi kami dan aplikasi kami, pertanyaan ini juga menggunakan ORDER BY
. Kerana kita perlu menyusun semua keputusan sebelum mengehadkan pertanyaan, kita kehilangan kelebihan menggunakan LIMIT
.
Oleh kerana kita tahu ORDER BY
boleh menjadi rumit, mari kita gunakan yang boleh dipercayai EXPLAIN
.
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | gal | NULL | ALL | IDX_F70E6EB7A76ED395 | NULL | NULL | NULL | 1 | 100.00 | Using where; Using filesort |
1 | SIMPLE | u | NULL | eq_ref | PRIMARY,UNIQ_1483A5E9BF396750 | PRIMARY | 108 | homestead.gal.id | 1 | 100.00 | NULL |
dan,
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | gal | NULL | ALL | NULL | NULL | NULL | NULL | 1 | 100.00 | Using filesort |
kita dapat melihat bahawa untuk kedua -dua pertanyaan kami, kami mempunyai jenis sambungan terburuk: ALL
.
Secara sejarah, pelaksanaan MySQL, terutamanya apabila digunakan dengan ORDER BY
, sering menjadi sumber isu prestasi MySQL. Gabungan ini juga digunakan dalam kebanyakan aplikasi interaktif dengan set data yang besar. Ciri -ciri seperti pengguna berdaftar baru dan tag popular sering menggunakan gabungan ini. LIMIT
created_at
dan ORDER BY
tanpa mengimbas dan menyusun set hasil lengkap. LIMIT
ORDER BY
ORDER BY
LIMIT
yang besar akan memaksa LIMIT
untuk menyusun lebih banyak baris. Ini akan menjejaskan prestasi. ORDER BY
dan LIMIT
, ini adalah beberapa langkah yang perlu kita ambil untuk meminimumkan isu -isu prestasi. ORDER BY
Kesimpulan
seperti yang telah kita lihat, sangat berguna untuk mengenal pasti masalah dalam pertanyaan seawal mungkin. Terdapat banyak masalah yang hanya diperhatikan apabila aplikasi kami sedang dalam pengeluaran dan terdapat banyak data atau banyak pelawat untuk mengakses pangkalan data. Jika anda boleh menggunakan EXPLAIN
untuk mengesan masalah ini seawal mungkin, maka kemungkinan masalah prestasi di masa depan adalah lebih kecil. EXPLAIN
dan indeks. EXPLAIN
Apakah kepentingan pengindeksan prestasi MySQL?
Bagaimanakah perintah menjelaskan membantu meningkatkan prestasi MySQL?
MySQL tidak menggunakan kekunci yang mungkin untuk beberapa sebab. Salah satu sebabnya ialah pengoptimuman menganggarkan bahawa menggunakan indeks memerlukan pengimbasan kebanyakan jadual dan memutuskan bahawa pengimbasan jadual akan lebih cepat. Sebab lain ialah lajur dalam klausa WHERE
tidak sepadan dengan lajur dalam indeks.
Terdapat beberapa cara untuk mengoptimumkan pertanyaan MySQL. Salah satu cara ialah menggunakan indeks dengan berkesan. Indeks boleh mempercepatkan pengambilan data dengan ketara. Walau bagaimanapun, mereka melambatkan operasi pengubahsuaian data seperti INSERT
, UPDATE
dan DELETE
. Oleh itu, sangat penting untuk mencari titik keseimbangan. Cara lain ialah menggunakan perintah EXPLAIN
untuk memahami bagaimana MySQL melaksanakan pertanyaan dan mendapati kemunculan yang berpotensi.
Kunci utama dalam MySQL adalah indeks. Kunci utama adalah pengecam unik untuk baris dalam jadual. Ia menguatkuasakan keunikan gabungan lajur atau lajur dan memastikan bahawa gabungan lajur atau lajur tidak mengandungi nilai NULL
. Sebaliknya, indeks adalah struktur data yang dapat meningkatkan kelajuan operasi pengambilan data. Ia boleh digunakan untuk mana -mana lajur atau gabungan lajur.
Anda boleh menggunakan pernyataan CREATE INDEX
untuk membuat indeks dalam MySQL. Sintaks adalah seperti berikut: CREATE INDEX index_name ON table_name (column1, column2, …);
. Ini mewujudkan indeks pada lajur yang ditentukan jadual yang ditentukan.
Indeks komposit, juga dikenali sebagai indeks multi-lajur, adalah indeks yang mengandungi pelbagai lajur. Di MySQL, indeks komposit boleh mengandungi sehingga 16 lajur, tetapi jumlah saiz lajur yang diindeks tidak boleh melebihi 767 bait.
Anda boleh menggunakan pernyataan DROP INDEX
untuk memadam indeks dalam MySQL. Sintaks adalah seperti berikut: DROP INDEX index_name ON table_name;
. Ini akan memadam indeks yang ditentukan dari jadual yang ditentukan.
Indeks kluster menentukan susunan data fizikal dalam jadual. Setiap jadual hanya boleh mempunyai satu indeks kluster. Sebaliknya, indeks yang tidak terkawal tidak mengubah urutan fizikal data dalam jadual. Sebaliknya, ia mengekalkan struktur data berasingan (indeks) yang menunjuk kepada baris data, yang membolehkan pengambilan data yang lebih cepat.
MySQL menggunakan pengoptimum berasaskan kos untuk memilih indeks untuk digunakan. Pengoptimuman menganggarkan kos pelaksanaan pelan untuk pertanyaan yang berbeza dan memilih pelan kos terendah. Kos dianggarkan berdasarkan faktor -faktor seperti bilangan baris yang akan dibaca, bilangan cakera cakera, kos CPU, dan penggunaan memori.
Atas ialah kandungan terperinci Prestasi mysql meningkatkan dengan indeks dan terangkan. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!