Saya mengalami masalah kinerja pada permintaan basis data tertentu yang memiliki set hasil yang besar.
Kueri yang dimaksud, saya punya tiga AND
dalam klausa WHERE
Apakah urutan klausa itu penting?
Seperti pada, jika saya menempatkan klausa ASI_EVENT_TIME pertama (karena itu akan menghapus sebagian besar hasil dari salah satu klausa.
Apakah itu akan meningkatkan waktu berjalan pada kueri?
PERTANYAAN:
SELECT DISTINCT activity_seismo_info.*
FROM `activity_seismo_info`
WHERE
activity_seismo_info.ASI_ACTIVITY_ID IS NOT NULL AND
activity_seismo_info.ASI_SEISMO_ID IN (43,44,...,259) AND
(
activity_seismo_info.ASI_EVENT_TIME>='2011-03-10 00:00:00' AND
activity_seismo_info.ASI_EVENT_TIME<='2011-03-17 23:59:59'
)
ORDER BY activity_seismo_info.ASI_EVENT_TIME DESC
JELASKAN kueri:
+----+-------------+---------+-------+---------------------------+--------------+---------+------+-------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------------------+--------------+---------+------+-------+-----------------------------+
| 1 | SIMPLE | act...o | range | act...o_FI_1,act...o_FI_2 | act...o_FI_1 | 5 | NULL | 65412 | Using where; Using filesort |
+----+-------------+---------+-------+---------------------------+--------------+---------+------+-------+-----------------------------+
Menggunakan:
PHP 5.2
MySQL 5.0.51a-3ubuntu5.4
Propel 1.3
Symfony 1.2.5
mysql
performance
mysql-5
Patrick
sumber
sumber
order by
termasuk dalam database.Jawaban:
Saya kira tidak. Pengoptimal kueri harus cukup pintar.
Anda dapat mencoba mengatur ulang klausa WHERE dan melihat bahwa EXPLAINS memberi tahu Anda hal yang sama dalam setiap kasus.
Tentang apa yang dapat dilakukan untuk mengoptimalkan kueri ini: Apakah ada indeks di ASI_EVENT_TIME? (ini yang paling penting menurut saya untuk kueri ini karena Anda juga mengurutkan hasil menggunakannya).
Apakah ada indeks pada dua bidang lainnya (ASI_SEISMO_ID dan ASI_ACTIVITY_ID)?
Akan sangat membantu jika Anda memposting struktur tabel.
sumber
Dari dokumentasi :
Jadi ya, itu harus sama dengan urutan kolom dalam indeks gabungan .
sumber
WHERE c = 'foo' AND a = 'bar' AND b = 'foobar'
dan indeks masih memenuhi syarat untuk digunakan.Tidak, itu tidak masalah.
Pengoptimal melakukan banyak transformasi sederhana langsung setelah mem-parsing SQL - ini adalah salah satunya.
sumber
mengoptimalkan sama dengan
Namun,
Tidak dapat mengoptimalkan kedua bagian. Sebagai contoh,
tidak dapat memanfaatkan INDEX (a, b) atau INDEX (b, a)
Untuk frasa berbeda, tes '=' apa pun DAN bersama-sama dalam klausa WHERE digunakan terlebih dahulu satu non - '=' (IN, ANTARA,>, dll) dapat ditangani. Tidak lebih dari satu dapat dioptimalkan secara efektif.
Kueri Anda memiliki 3 klausa seperti itu.
Ternyata, INDEX (EVENT_TIME) mungkin yang paling berguna - ini akan membantu dengan salah satu AND, dan mungkin digunakan untuk menghindari "filesort" untuk ORDER BY.
Jika tidak ada baris duplikat (mengapa ada?), Lalu singkirkan DISTINCT. Itu bahkan menyebabkan lebih banyak upaya.
Berikan SHOW CREATE TABLE dan SHOW TABLE STATUS saat mengajukan pertanyaan kinerja.
Perbarui ... Versi yang lebih baru (mis., MySQL 5.7) dapat, dalam beberapa situasi, memperlakukan
IN( list of constants )
hampir seperti=
. Agar aman, patuhi pesanan ini (setiap bagian bersifat opsional):=
.INs
.sumber
MySQL di mana dokumen pengoptimalan mengatakan:
Dengan cara ini rasional untuk pengoptimal kueri untuk menghilangkan BAGAIMANA kita menggunakan kolom dalam kueri (Tidak hanya MySQL tetapi SQL adalah bahasa deklaratif dan harus melakukan apa yang kita inginkan bukan seperti yang kita inginkan).
Namun saya masih suka memiliki jenis yang sama untuk kolom kunci komposit dalam permintaan tetapi kadang-kadang tak terhindarkan misalnya ketika kita menggunakan ORM atau ActiveRecord, dalam beberapa kerangka kerja seperti yii2, menyesuaikan kriteria relasi akan ditambahkan pada akhir kondisi "aktif" tetapi kita masih membutuhkan kemampuan QueryBuilders di berbagai bagian aplikasi.
sumber
Setiap bidang yang digunakan dalam klausa WHERE / HAVING Anda dan memiliki selektivitas tinggi (jumlah nilai unik / jumlah total catatan> 10% ~ 20%) HARUS diindeks.
Jadi, jika
ASI_EVENT_TIME
kolom Anda memiliki banyak nilai yang mungkin, pertama-tama indeks semuanya. Kemudian seperti yang dikatakan @ypercube, coba atur ulang dan lihat apa yang EXPLAIN katakan. Seharusnya semuanya hampir sama.Selain itu, ingin Anda melihat pada Indexing SQL LIKE Filter . Meskipun itu bukan jawaban yang Anda butuhkan, tetapi Anda masih akan belajar tentang bagaimana pengindeksan bekerja di bawah tenda.
* Sunting: Lihat tautan yang disediakan di bawah di komentar untuk mempelajari lebih lanjut tentang pengindeksan.
sumber