Saya memiliki ponsel pintar (5000 ditambahkan per hari) di database MySQL

Smartphone (Id: int PK, Harga: double, DisplaySize: double, Ram: int)

Dan 1 000 000 peringatan yang dibuat oleh pengguna untuk diberi tahu jika ponsel cerdas yang cocok dengan preferensi mereka ditambahkan;

Alert (Id: int PK, PriceMin: double, PriceMax: double, DisplaySizeMin: double, DisplaySizeMax: double, RamMin: int, RamMax: int)

Saya memiliki batch (dijalankan setiap hari) yang akan memeriksa smartphone yang ditambahkan (~5000) dan menemukan peringatan yang sesuai seperti ini:

for smartphone in smartphones:
    smartphone_alerts = session.query(Alert).filter(
    smartphone.price >= Alert.price_min,
    smartphone.price <= Alert.price_max,
    smartphone.displaySize >= Alert.displaySize_min,
    smartphone.displaySize <= Alert.displaySize_max,
    smartphone.ram>= Alert.ram_min,
    smartphone.ram<= Alert.ram_max,
    ).all()

    #add alerts to a dict

Dibutuhkan lebih dari 24 jam untuk mendapatkan semua peringatan yang cocok untuk 5000 ponsel cerdas dan 1 000 000 peringatan!

Apakah ada cara untuk mengoptimalkan ini? Model database yang lebih baik? Algoritma yang efisien?

0
Trivial Worker 17 Mei 2021, 12:56

1 menjawab

Jawaban Terbaik

Anda belum memberikan banyak informasi. Secara khusus, Anda tidak memberi tahu kami apa pun tentang kueri Alert Anda.

Saya kira Anda melakukan semacam kueri SELECT * FROM Smartphones;, membaca setiap baris ke dalam RAM, lalu membaca Peringatan yang sama, dan kemudian memfilter pasangan baris demi pasangan. O(n**2): Jumlah Ponsel Cerdas x jumlah Peringatan = 5.000.000.000. Tidak heran dibutuhkan sepanjang hari!

Jika Anda menggunakan kueri seperti ini, Anda akan membuat MySQL melakukan pekerjaan itu. Untuk itulah ia dibuat.

SELECT Smartphone.Id, Alert.Id,
       Smartphone.Price, Smartphone.DisplaySize, Smartphone.Ram
  FROM Smartphones
  JOIN Alerts   ON Smartphones.Price >= Alerts.Price_min
               AND Smartphones.Price <= Alerts.Price_max
               AND Smartphones.DisplaySize >= Alerts.DisplaySize_min
               AND Smartphones.DisplaySize <= Alerts.DisplaySize_max
               AND Smartphones.Ram >= Alerts.Ram_min
               AND Smartphones.Ram <= Alerts.Ram_max

Saya curiga, tapi saya tidak yakin, indeks ini akan banyak membantu

CREATE INDEX pricerange ON Alerts(Price_min, Price_max DESC)
CREATE INDEX price ON Smartphones(Price)

Saya menempatkan indeks pada Harga karena mereka cenderung selektif daripada indeks pada ukuran layar atau RAM.

0
O. Jones 17 Mei 2021, 12:35