更新
感谢所有帮助。我将总结答案。
来自@Jaydee,他的答案成功地将结果减少到0.09秒,并且它与LIMIT中的数字呈线性关系。
select * from(select table1.id as table1_id from table1 where table1.id< 100000命令由table1.id desc limit 1000)t1内连接 table1 on t1.table2_id = table2.id left join table3 on t1.table3_id = table3.id by t1.id;
来自@Rick James,他提到它可能是表2中的问题。因为我的表2只有几列,所以我可以把它排除在外,即使在客户端也可以自己加入!
所以我删除了表2,它只有0.02秒!
从
table1
左侧加入id
选择table1_id
。table1
作为table3
在table1
。table3_id
=table3
。id
其中table1
。id
< 100000 按table1
订购。id
desc limit 1000;
最后,我发现,如果我将table2从内连接更改为左连接,那么所有的痛苦都消失了,它是0.03s!
从
table1
左侧加入id
选择table1_id
。table1
作为table2
在table1
。table2_id
=table2
。id
离开加入table3
table1
。table3_id
=table3
。id
其中table1
。id
<的 100000 按table1
订购。id
desc limit 1000;
再次感谢您的帮助!
==============================
注意:我在嵌入式服务器上运行,有限的内存(大约1G,足以实际输入所有数据,200,000个数据)并使用SD卡作为存储。
从table1中选择table1.id,其中id< 100000 order by id desc limit 1000;
(0.01秒)
从
table1
内部加入id
选择table1_id
。table1
作为table2
在table1
。table2_id
=table2
。id
其中table1
。id
< 100000 按table1
排序。id
desc limit 1000;
(0.40s)
从
table1
内部加入id
选择table1_id
。table1
作为table2
在table1
。table2_id
=table2
。id
其中table1
。id
<的 1000 按table1
订购。id
desc limit 1000;
(0.01秒)
从
table1
内部加入id
选择table1_id
。table1
作为table2
在table1
。table2_id
=table2
。id
离开加入table3
table1
。table3_id
=table3
。id
其中table1
。id
<的 100000 按table1
订购。id
desc limit 1000;
(2.31s)
从
table1
内部加入id
选择table1_id
。table1
作为table2
在table1
。table2_id
=table2
。id
离开加入table3
table1
。table3_id
=table3
。id
其中table1
。id
< 1000 订单 按table1
。id
desc limit 1000;
(0.03S)
正如评论所说,我使用了解释,但我并不真正理解解释说的是什么。请帮我查一下。以下是最长的2.31s。
+----+-------------+----------------------+--------+-------------------------------------------------------------------+---------------------------------------+---------+---------------------------------------------+-------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------------------+--------+-------------------------------------------------------------------+---------------------------------------+---------+---------------------------------------------+-------+----------------------------------------------+
| 1 | SIMPLE | table2 | index | PRIMARY,table2_id_index | table1_id_index | 4 | NULL | 1 | Using index; Using temporary; Using filesort |
| 1 | SIMPLE | table1 | ref | PRIMARY,table1_table2_id_foreign,table1_id_index | table1_table2_id_foreign | 4 | videocap.table2.id | 27222 | Using where |
| 1 | SIMPLE | table3 | eq_ref | PRIMARY | PRIMARY | 4 | videocap.table1.table3_id | 1 | Using index |
+----+-------------+----------------------+--------+-------------------------------------------------------------------+---------------------------------------+---------+---------------------------------------------+-------+----------------------------------------------+
来自desc表的结果
表1:
+-------------------------+------------------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------------+------------------+------+-----+---------------------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| table2_id | int(10) unsigned | NO | MUL | NULL | |
| table3_id | int(10) unsigned | NO | MUL | 0 | |
| created_at | timestamp | NO | | 0000-00-00 00:00:00 | |
| updated_at | timestamp | NO | | 0000-00-00 00:00:00 | |
+-------------------------+------------------+------+-----+---------------------+----------------+
表2:
+-----------------+------------------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+------------------+------+-----+---------------------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| created_at | timestamp | NO | | 0000-00-00 00:00:00 | |
| updated_at | timestamp | NO | | 0000-00-00 00:00:00 | |
+-----------------+------------------+------+-----+---------------------+----------------+
表3:
+---------------------------+------------------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------------------+------------------+------+-----+---------------------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| created_at | timestamp | NO | | 0000-00-00 00:00:00 | |
| updated_at | timestamp | NO | | 0000-00-00 00:00:00 | |
+---------------------------+------------------+------+-----+---------------------+----------------+
答案 0 :(得分:2)
这是如何表现的? (哎呀。更正)
select *
from
( SELECT table1.id as table1_id
from table1
where table1.id < 100000
order by table1.id desc
limit 1000
) t1
inner join table2 on t1.table2_id = table2.id
left join table3 on t1.table3_id = table3.id
order by t1.id;
答案 1 :(得分:1)
看起来table2有1行。那是对的吗?每个表中有多少行?
在table2中只有一行,优化器似乎决定让它开始使用。
在所有情况下,PRIMARY KEY(id)
,尤其是在使用InnoDB时,最适合
where table1.id < $number
order by table1.id desc
但是,如果该表的大部分具有id&lt; 100000,然后优化器可能(错误地)决定进行表扫描(因为它没有考虑LIMIT
)。你用的是什么版本? 5.6在这方面有一些改进。
请记住,查询有数百万种变体。虽然我感谢您尝试隔离查询的重要部分;您可能会发现将任何答案都应用回“真实”的答案中。查询可能会遇到其他一些打嗝。