Mysql
 sql >> डेटाबेस >  >> RDS >> Mysql

Mysql सबक्वेरी हमेशा फाइलोर्ट कर रही है

Using filesort जरूरी नहीं कि बुरी चीज हो। नाम थोड़ा भ्रामक है। हालांकि इसमें "फाइल" है, इसका मतलब यह नहीं है कि डेटा हार्ड डिस्क पर कहीं भी लिखा गया है। इसे अभी भी स्मृति में संसाधित किया जाता है।

मैनुअल से :

आप समझते हैं कि आपकी क्वेरी में ऐसा क्यों होता है, है ना? इस प्रकार की उपश्रेणियों का उपयोग करना खराब शैली है क्योंकि यह एक आश्रित है सबक्वेरी आपके app . में प्रत्येक पंक्ति के लिए तालिका सबक्वेरी निष्पादित की जाती है। बहुत बुरा। 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)
;

यह अभी भी एक आश्रित सबक्वेरी का उपयोग करता है, लेकिन explain बहुत बेहतर दिखता है:

| 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 |

इसे फिर से लिखने का दूसरा तरीका यह होगा:

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
;

व्याख्या और भी बेहतर दिखती है:

| 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 |

और यहां एक ऐसा संस्करण है जहां आपके पास कोई आश्रित सबक्वायरी नहीं है:

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
;

यह इस तरह काम करता है:जब gp.dateup अधिकतम है, कोई 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. तालिका मौजूद होने के बाद एक नई आईडी (ऑटो इंक्रीमेंट) जोड़ने की समस्या

  2. MySQL में गलत स्ट्रिंग मान को कैसे ठीक करें

  3. MySQL स्टार्टअप त्रुटि - मूल तत्व गुम है

  4. DATEDIFF - NULL को अभी से बदलें ()

  5. ग्रहण ईई में एसक्यूएल तालिका में डेटा सम्मिलित करना