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

Subquery mysql selalu melakukan filesort

Using filesort belum tentu hal yang buruk. Namanya agak menyesatkan. Meskipun berisi "file", itu tidak berarti bahwa data ditulis di mana saja di hard disk. Itu masih hanya diproses di memori.

Dari manual :

Anda mengerti mengapa ini terjadi dalam kueri Anda, bukan? Menggunakan subkueri semacam ini adalah gaya yang buruk karena bergantung subkueri. Untuk setiap baris di app . Anda tabel subquery dieksekusi. Sangat buruk. Tulis ulang kueri dengan join .

select app.id,
gp.dateup
from app 
join gamesplatform_pricehistory gp on gp.id_app = app.id
where app.id > 0
and gp.country = 1
and gp.dateup = (SELECT MAX(dateup) FROM gamesplatform_pricehistory smgp WHERE smgp.id_app = gp.id_app AND smgp.country = 1)
;

Ini masih menggunakan subquery dependen, tetapi explain terlihat jauh lebih baik:

| id |        select_type | table |  type | possible_keys |     key | key_len |                        ref | rows |                    Extra |
|----|--------------------|-------|-------|---------------|---------|---------|----------------------------|------|--------------------------|
|  1 |            PRIMARY |   app | index |       PRIMARY | PRIMARY |       4 |                     (null) |    2 | Using where; Using index |
|  1 |            PRIMARY |    gp |   ref |        id_app |  id_app |       5 |    db_2_034bc.app.id,const |    1 | Using where; Using index |
|  2 | DEPENDENT SUBQUERY |  smgp |   ref |        id_app |  id_app |       5 | db_2_034bc.gp.id_app,const |    1 |              Using index |

Cara lain untuk menulis ulang, adalah ini:

select app.id,
gp.dateup
from app 
LEFT join 
(SELECT id_app, MAX(dateup) AS dateup 
 FROM gamesplatform_pricehistory
 WHERE country = 1
 GROUP BY id_app
)gp on gp.id_app = app.id
where app.id > 0
;

Penjelasannya terlihat lebih baik:

| id | select_type |                      table |  type | possible_keys |     key | key_len |    ref | rows |                    Extra |
|----|-------------|----------------------------|-------|---------------|---------|---------|--------|------|--------------------------|
|  1 |     PRIMARY |                        app | index |       PRIMARY | PRIMARY |       4 | (null) |    2 | Using where; Using index |
|  1 |     PRIMARY |                 <derived2> |   ALL |        (null) |  (null) |  (null) | (null) |    2 |                          |
|  2 |     DERIVED | gamesplatform_pricehistory | index |        (null) |  id_app |      13 | (null) |    2 | Using where; Using index |

Dan ini adalah versi di mana Anda tidak memiliki subquery dependen sama sekali:

select app.id,
gp.dateup
from app 
left join gamesplatform_pricehistory gp on gp.id_app = app.id and country = 1
left join gamesplatform_pricehistory gp2 on gp.id_app = app.id and country = 1 and gp.dateup < gp2.dateup
where app.id > 0
and gp2.dateup is null
;

Ini bekerja seperti ini:Ketika gp.dateup sudah maksimal, tidak ada gp2.dateup .



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. INSERT INTO Table dari beberapa tabel

  2. Manajemen akun pengguna, peran, izin, otentikasi PHP dan MySQL - Bagian 2

  3. PHP - Amankan halaman khusus anggota dengan sistem login

  4. Apakah MySQL memungkinkan untuk membuat database dengan titik?

  5. Output PHP kosong dari database MySQL untuk longblob