Rumah > Soal Jawab > teks badan
Saya cuba mengoptimumkan pertanyaan SQL, tetapi saya ingin tahu cara melakukannya dengan betul.
SELECT r0_.* FROM ride r0_ use index (ride_booking_id_IDX) LEFT JOIN booking b1_ ON r0_.booking_id = b1_.id LEFT JOIN spot s2_ ON r0_.from_spot_id = s2_.id LEFT JOIN spot s3_ ON r0_.to_spot_id = s3_.id WHERE b1_.start_at <= '2023-04-21' AND b1_.end_at >= '2023-04-20' AND b1_.paid_at IS NOT NULL AND b1_.cancelled_at IS NULL AND ((s2_.zone_id = 1 OR s3_.zone_id = 1)) AND s2_.type = 'parking';
Di sini, saya memaksa penggunaan indeks (booking_id, from_spot_id, to_spot_id)
, yang menyebabkan pertanyaan dilaksanakan dalam masa 25 saat dari tarikh terdekat dalam kira-kira 100 milisaat!
booking
表大约有 200 万行,而 ride
Meja mempunyai kira-kira 5 juta baris.
Walau bagaimanapun, saya dapat melihatnya mengimbas lebih banyak baris menggunakan pengindeksan paksa:
id | Pilih jenis | Meja | Partition | Taip | Kunci yang mungkin | Kunci | key_len | Rujukan | OK | Ditapis | Tambahan |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | Mudah | b1_ | Skop | Utama, booking_id_end_IDX, booking_id_IDX, booking_id_start_IDX, IDX_E00CEDDEB75363F7, IDX_E00CEDDE37D3107C, IDX_E00CEDDEDEA4208C, booking_paid_at_IDX | IDX_E00CEDDE37D3107C | 6 | 111456 | 6.6 | Gunakan syarat indeks; | ||
Mudah | r0_ | Rujukan | ride_booking_id_IDX | ride_booking_id_IDX | 109 | ector.b1_.id | 1 | 100.0 | |||
Mudah | s2_ | eq_ref | Utama, IDX_B9327A739F2C3FAB, spot_type_IDX | Utama | 4 | ector.r0_.from_spot_id | 1 | 72.52 | Tempat penggunaan | ||
Mudah | s3_ | eq_ref | Utama | Utama | 4 | ector.r0_.to_spot_id | 1 | 100.0 | Tempat penggunaan |
id | Pilih jenis | Meja | Partition | Taip | Kunci yang mungkin | Kunci | key_len | Rujukan | OK | Ditapis | Tambahan |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | Mudah | s2_ | Rujukan | Utama, IDX_B9327A739F2C3FAB, spot_type_IDX | spot_type_IDX | 767 | Malar | 161 | 100.0 | Gunakan syarat indeks | |
1 | Mudah | r0_ | Rujukan | IDX_9B3D7CD0ABAF30D3, IDX_9B3D7CD03301C60, ride_booking_id_IDX, booking_from_spot_to_spot_IDX | IDX_9B3D7CD0ABAF30D3 | 5 | ector.s2_.id | 392 | 100.0 | ||
1 | Mudah | b1_ | eq_ref | Utama, booking_id_end_IDX, booking_id_IDX, booking_id_start_IDX, IDX_E00CEDDEB75363F7, IDX_E00CEDDE37D3107C, IDX_E00CEDDEDEA4208C, booking_paid_at_IDX | Utama | 108 | ector.r0_.booking_id | 1 | 5.0 | Tempat penggunaan | |
1 | Mudah | s3_ | eq_ref | Utama | Utama | 4 | ector.r0_.to_spot_id | 1 | 100.0 | Tempat penggunaan |
Setakat yang saya tahu, tarikh yang saya gunakan untuk dibandingkan dengan start_at
和 end_at
adalah sebab mengapa pertanyaan itu nyata lebih pantas.
Jadi saya cuba mengasingkan bahagian paling perlahan kepada pertanyaan yang lebih kecil:
从预订 b 中选择 *,其中 b.start_at < '2021-01-01' 和 b.end_at > '2021-01-01';
Pada tempahan meja, saya mempunyai dua indeks(start_at)
和 (end_at)
ia membantu pertanyaan ini berjalan dengan lebih pantas apabila anda semakin hampir kepada maksimum dan min (memandangkan indeks akan menapis kebanyakan baris, terdapat sedikit baris yang tinggal) mengimbas).
Namun, apabila saya mengambil nilai rawak cukup jauh pada masa lalu, ia menjadi lebih perlahan. Pertanyaan di atas mengambil masa 10 saat untuk dijalankan kerana ia hanya menggunakan satu daripada dua indeks seperti yang dijangkakan, saya tidak tahu mengapa penjelasan itu tidak muncul untuk merge_index pada pertanyaan yang begitu mudah:
id | Pilih jenis | Meja | Partition | Taip | Kunci yang mungkin | Kunci | key_len | Rujukan | OK | Ditapis | Tambahan |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | Mudah | b | Skop | IDX_E00CEDDEB75363F7,IDX_E00CEDDE37D3107C | IDX_E00CEDDEB75363F7 | 6 | 1147319 | 50 | Gunakan syarat indeks; |