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
नहीं है .