Mengapa kemas kini pertanyaan ini gagal dilaksanakan dengan jayanya?
P粉885562567
P粉885562567 2023-09-03 16:39:14
0
2
468

Saya mempunyai 2 meja, pelanggan (3000 baris) dan phone_call_log (350,000 baris).

Saya perlu melaksanakan masa panggilan terakhir kepada setiap pelanggan menggunakan log panggilan (lebih pantas untuk carian bahagian hadapan).

Indeksnya adalah seperti berikut:

  • masa_mula (cap masa)
  • panggilan(bigint(32) tidak ditandatangani)
  • Pemanggil(bigint(32) tidak ditandatangani)
  • Nombor telefon (bigint(32) tidak ditandatangani)
  • last_call(timestamp)

Apabila menjalankan pertanyaan ini, untuk lajur pemanggil/pemanggil, masa penyiapan adalah kurang daripada 2 saat tanpa pernyataan OR, tetapi dengan pernyataan OR, ia tidak akan selesai (dalam ujian, saya tidak membiarkannya berjalan selama lebih daripada 30 minit).

KEMASKINI pelanggan SET pelanggan.last_call = ( PILIH maks(phone_call_log.start_time) DARI phone_call_log WHERE phone_call_log.callee = pelanggan.nombor telefon ATAU phone_call_log.caller = pelanggan.nombor telefon ) DI MANA pelanggan.nombor telefon BUKAN NULL DAN panjang(pelanggan.nombor telefon) > DAN pelanggan.nombor telefon > 

P粉885562567
P粉885562567

membalas semua (2)
P粉009186469

terpantas

Tukar strim data untuk mengemas kini apabila panggilan masukcustomers.last_call.

Kemas kini sambungan

UPDATEJOIN相比,IN ( SELECT ... )Kesannya lebih baik.

atau

OR会降低性能。查询很可能会为每个客户扫描整个phone_call_log.

Satu penyelesaian ialah melakukan duaUPDATE, dan gunakan indeks yang sesuai:

UPDATE SET customers.last_call = GREATEST( customers.last_call, ( select max(phone_call_log.start_time) FROM phone_call_log WHERE phone_call_log.callee = customers.phonenumber ) WHERE ... UPDATE SET customers.last_call = GREATEST( customers.last_call, ( ... caller ... ) ) WHERE ...

Ini memerlukan mencipta indeks berikut padaphone_call_log:

INDEX(callee, start_time) INDEX(caller, start_time)

danpadam pemanggil indeks lajur tunggal semasa dan penerima.

Jenis data

Untuk nombor telefon, gunakanBIGINT可能是错误的,特别是考虑到LENGTH(customers.phonenumber) > 6.

Sebenarnya, semuanya berpunca daripada ujian mudah:

where customers.phonenumber is not null AND LENGTH(customers.phonenumber) > 6 AND customers.phonenumber > 1000000;

Setiap>检查都会检查NOT NULL; gunakan hanya satu daripadanya berdasarkan jenis data, dan indekskannya.

(Sila berikanSHOW CREATE TABLE; 'Bahasa Inggeris' tidak cukup tepat.)

    P粉354602955

    Pertanyaan menggunakanORtidak boleh menggunakan indeks dengan cekap. Saya cadangkan anda mencuba perkara berikut:

    UPDATE customers SET last_call = GREATEST( (SELECT MAX(start_time) FROM phone_call_log WHERE callee = customers.phonenumber), (SELECT MAX(start_time) FROM phone_call_log WHERE caller = customers.phonenumber) )

    Sila ambil perhatian bahawaGREATESTmempunyai masalah mengendalikan nilai NULL.

      Muat turun terkini
      Lagi>
      kesan web
      Kod sumber laman web
      Bahan laman web
      Templat hujung hadapan
      Tentang kita Penafian Sitemap
      Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!