[英]MySQL latency caused by using index; Using temporary; Using filesort
我有一個查詢,該查詢將兩個表連接起來並按主鍵排序數據。 這導致MySQL非常流行的問題“使用索引;使用臨時文件;使用文件排序”。
該問題在我的具有約40萬條記錄的生產表中導致嚴重的延遲問題。
這是更多信息:
我有兩個表:Doctor和Area。 Doctor表具有指向Area的外鍵。
醫生:
+-----------------------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------------+---------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| area_id | int(11) | NO | MUL | NULL | |
+-----------------------------+---------------+------+-----+---------+----------------+
醫生索引:
+---------------+------------+------------------------+--------------+------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+---------------+------------+------------------------+--------------+------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| doctor | 0 | PRIMARY | 1 | id | A | 5546 | NULL | NULL | | BTREE | | |
| doctor | 1 | doctor_dfd0e917 | 1 | area_id | A | 29 | NULL | NULL | | BTREE | | |
+---------------+------------+------------------------+--------------+------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
區域:
+------------------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
+------------------------+-------------+------+-----+---------+----------------+
面積索引:
+---------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+---------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| area | 0 | PRIMARY | 1 | id | A | 24 | NULL | NULL | | BTREE | | |
+---------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
我正在嘗試運行以下查詢:
SELECT `doctor`.`id`,
`area`.`id`
FROM
`doctor`
INNER JOIN
`area` ON (`doctor`.`area_id` = `area`.`id`)
ORDER BY
`doctor`.`id` DESC LIMIT 100;
EXPLAIN返回以下內容(帶有問題的“使用”索引;“使用臨時”;“使用文件排序”):
+----+-------------+---------------+-------+------------------------+------------------------+---------+--------------+------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------------+-------+------------------------+------------------------+---------+--------------+------+----------------------------------------------+
| 1 | SIMPLE | area | index | PRIMARY | PRIMARY | 4 | NULL | 24 | Using index; Using temporary; Using filesort |
| 1 | SIMPLE | doctor | ref | doctor_dfd0e917 | doctor_dfd0e917 | 4 | area.id | 191 | Using index |
+----+-------------+---------------+-------+------------------------+------------------------+---------+--------------+------+----------------------------------------------+
如果刪除ORDER BY子句,則會達到預期的效果:
+----+-------------+---------------+-------+------------------------+------------------------+---------+--------------+------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------------+-------+------------------------+------------------------+---------+--------------+------+----------------------------------------------+
| 1 | SIMPLE | area | index | PRIMARY | PRIMARY | 4 | NULL | 24 | Using index |
| 1 | SIMPLE | doctor | ref | doctor_dfd0e917 | doctor_dfd0e917 | 4 | area.id | 191 | Using index |
+----+-------------+---------------+-------+------------------------+------------------------+---------+--------------+------+----------------------------------------------+
即使使用主鍵,為什么ORDER BY子句也會在這里引起問題?
先感謝您。
看來每個醫生只有一個區域。 查看此查詢的工作方式:
SELECT d.id,
(SELECT a.id FROM area a ON a.id = d.area_id) as area_id
FROM doctor d
ORDER BY d.id DESC
LIMIT 100;
如果要使用inner join
測試表中是否存在醫生,請添加:
SELECT d.id,
(SELECT a.id FROM area a ON a.id = d.area_id) as area_id
FROM doctor d
WHERE EXISTS (SELECT 1 FROM area a ON a.id = d.area_id)
ORDER BY d.id DESC
LIMIT 100;
這兩個都很有可能會按順序掃描doctors
表,並根據需要從area
獲取信息。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.