मैंने JOIN
. में कुछ सुधार किए हैं संस्करण; नीचे देखें।
मैं गति के लिए जॉइन दृष्टिकोण के लिए वोट करता हूं। यहां बताया गया है कि मैंने इसे कैसे निर्धारित किया:
हो रहा है, संस्करण 1
mysql> FLUSH STATUS;
mysql> SELECT city
-> FROM us_vch200
-> WHERE state IN ('IL', 'MO', 'PA')
-> GROUP BY city
-> HAVING count(DISTINCT state) >= 3;
+-------------+
| city |
+-------------+
| Springfield |
| Washington |
+-------------+
mysql> SHOW SESSION STATUS LIKE 'Handler%';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| Handler_external_lock | 2 |
| Handler_read_first | 1 |
| Handler_read_key | 2 |
| Handler_read_last | 1 |
| Handler_read_next | 4175 | -- full index scan
(etc)
+----+-------------+-----------+-------+-----------------------+------------+---------+------+------+--------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+-------+-----------------------+------------+---------+------+------+--------------------------------------------------+
| 1 | SIMPLE | us_vch200 | range | state_city,city_state | city_state | 769 | NULL | 4176 | Using where; Using index for group-by (scanning) |
+----+-------------+-----------+-------+-----------------------+------------+---------+------+------+--------------------------------------------------+
'अतिरिक्त' बताता है कि उसने GROUP BY
. से निपटने का फैसला किया है और INDEX(city, state)
. का उपयोग करें भले ही INDEX(state, city)
समझ में आ सकता है।
हो रहा है, संस्करण 2
इसे INDEX(state, city)
पर स्विच करना पैदावार:
mysql> FLUSH STATUS;
mysql> SELECT city
-> FROM us_vch200 IGNORE INDEX(city_state)
-> WHERE state IN ('IL', 'MO', 'PA')
-> GROUP BY city
-> HAVING count(DISTINCT state) >= 3;
+-------------+
| city |
+-------------+
| Springfield |
| Washington |
+-------------+
mysql> SHOW SESSION STATUS LIKE 'Handler%';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| Handler_commit | 1 |
| Handler_external_lock | 2 |
| Handler_read_key | 401 |
| Handler_read_next | 398 |
| Handler_read_rnd | 398 |
(etc)
+----+-------------+-----------+-------+-----------------------+------------+---------+------+------+------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+-------+-----------------------+------------+---------+------+------+------------------------------------------+
| 1 | SIMPLE | us_vch200 | range | state_city,city_state | state_city | 2 | NULL | 397 | Using where; Using index; Using filesort |
+----+-------------+-----------+-------+-----------------------+------------+---------+------+------+------------------------------------------+
शामिल हों
mysql> SELECT x.city
-> FROM us_vch200 x
-> JOIN us_vch200 y ON y.city= x.city AND y.state = 'MO'
-> JOIN us_vch200 z ON z.city= x.city AND z.state = 'PA'
-> WHERE x.state = 'IL';
+-------------+
| city |
+-------------+
| Springfield |
| Washington |
+-------------+
2 rows in set (0.00 sec)
mysql> SHOW SESSION STATUS LIKE 'Handler%';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| Handler_commit | 1 |
| Handler_external_lock | 6 |
| Handler_read_key | 86 |
| Handler_read_next | 87 |
(etc)
+----+-------------+-------+------+-----------------------+------------+---------+--------------------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+-----------------------+------------+---------+--------------------+------+--------------------------+
| 1 | SIMPLE | y | ref | state_city,city_state | state_city | 2 | const | 81 | Using where; Using index |
| 1 | SIMPLE | z | ref | state_city,city_state | state_city | 769 | const,world.y.city | 1 | Using where; Using index |
| 1 | SIMPLE | x | ref | state_city,city_state | state_city | 769 | const,world.y.city | 1 | Using where; Using index |
+----+-------------+-------+------+-----------------------+------------+---------+--------------------+------+--------------------------+
केवल INDEX(state, city)
ज़रूरी है। इस फॉर्मूलेशन के लिए हैंडलर नंबर सबसे छोटे हैं, इसलिए मुझे लगता है कि यह सबसे तेज़ है।
ध्यान दें कि कैसे ऑप्टिमाइज़र ने अपना मन बना लिया कि किस तालिका से शुरू करना है, शायद
. के कारण+-------+----------+
| state | COUNT(*) |
+-------+----------+
| IL | 221 |
| MO | 81 | -- smallest
| PA | 96 |
+-------+----------+
निष्कर्ष
JOIN
(अनावश्यक t
. के बिना टेबल) शायद सबसे तेज़ है। साथ ही इस समग्र सूचकांक की आवश्यकता है:INDEX(state, city)
।
अपने उपयोग के मामले में वापस अनुवाद करने के लिए:
city --> documentid
state --> termid
चेतावनी:वाईएमएमवी क्योंकि दस्तावेज और टर्मिड के लिए मूल्यों का वितरण मेरे द्वारा उपयोग किए जाने वाले परीक्षण मामले से काफी भिन्न हो सकता है।