Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Pengoptimalan kueri -- terlalu lama dan menghentikan server

Menambahkan indeks membantu dalam banyak kasus, tetapi Anda memiliki subquery yang bergabung dengan subquery lain, tidak ada indeks di tabel Anda saat ini yang dapat membantu Anda mempercepat. Satu-satunya cara Anda dapat menggunakan indeks di sini adalah dengan membuat tabel sementara.

Jadi seperti yang ditunjukkan Markus, Anda perlu memecah kueri Anda menjadi beberapa kueri yang lebih kecil yang menyimpan hasilnya di tabel sementara. Daripada Anda dapat menambahkan indeks ke dalamnya dan semoga mempercepat kueri Anda. Hal baik lainnya tentang memecah kueri besar menjadi beberapa kueri yang lebih kecil adalah Anda dapat membuat profil dengan lebih baik bagian mana yang lebih lambat dan memperbaikinya.

Anda juga telah menggunakan satu subquery dua kali yang buruk untuk kinerja karena hasilnya tidak di-cache.

Berikut adalah contoh bagaimana Anda dapat melakukannya:

DROP TEMPORARY TABLE IF EXISTS tmp_k;
CREATE TEMPORARY TABLE tmp_k
    ENGINE=Memory
SELECT 
    gps_unit_location.*,
    @i:= IF(((Speed_Kmh > 80) AND (@b = 0)), @i + 1, @i) AS IntervalID,
    @r:= IF(((Speed_Kmh > 80) AND (@b = 0)), 1, @r + 1) AS RowNumber,
    @b:= IF((Speed_Kmh > 80), 1, 0) AS IntervalCheck
FROM
    gps_unit_location,
    (SELECT @i:=0) i, 
    (SELECT @r:=0) r, 
    (SELECT @b:=0) b
ORDER BY
    dt,
    idgps_unit_location;

ALTER TABLE tmp_k ADD INDEX (IntervalID);

DROP TEMPORARY TABLE IF EXISTS tmp_max;
CREATE TEMPORARY TABLE tmp_max
    ENGINE=Memory
SELECT 
    IntervalID, 
    MAX(RowNumber) AS MaxRowNo
FROM
    temp_k
WHERE
    IntervalCheck = 1
GROUP BY 
    IntervalID;

ALTER TABLE tmp_max ADD INDEX (IntervalID);

SELECT 
    k.idgps_unit,
    MIN(k.dt) AS DT_Start,
    MIN(IF(k.RowNumber = 1, k.Lat, NULL)) AS Latitude_Start,
    MIN(IF(k.RowNumber = 1, k.Long, NULL)) AS Longitude_Start,
    MIN(IF(k.RowNumber = 1, k.Speed_kmh, NULL) AS Speed_Start,
    MAX(k.dt) AS DT_End,
    MIN(IF(k.RowNumber = m.MaxRowNo, k.Lat, NULL)) AS Latitude_End
    MIN(IF(k.RowNumber = m.MaxRowNo, k.Long, NULL)) AS Longitude_End
    MIN(IF(k.RowNumber = m.MaxRowNo, k.Speed_kmh, NULL)) AS Speed_End,
    AVG(Speed_kmh) AS Average_Speed,
    gu.name,
    gu.notes,
    gu.serial
FROM
    tmp_k AS k
    INNER JOIN tmp_max AS m
        USING(IntervalID)
    INNER JOIN gps_unit AS gu
        USING(idgps_unit)
    INNER JOIN user AS u
    ON (gu.idcustomer = u.idcustomer)
WHERE
    (k.IntervalCheck = 1) 
     AND (u.iduser = 14)
GROUP BY 
    k.IntervalID, 
    k.idgps_unit;

DROP TEMPORARY TABLE tmp_k;
DROP TEMPORARY TABLE tmp_max;


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Pesanan Kustom MySQL

  2. Apa cara termudah untuk menghapus database dari CLI dengan manage.py di Django?

  3. ClassNotFoundException saat menghubungkan ke Mysql dengan JDBC

  4. Perbedaan antara MySql dan MySqli di PHP

  5. masukkan beberapa nilai dalam satu atribut