Mysql optimizaiton:有什么方法可以让它更快?

时间:2015-06-30 10:15:57

标签: mysql database join query-optimization

更新

感谢所有帮助。我将总结答案。

来自@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_idtable1作为table3   在table1table3_id = table3id其中table1id< 100000   按table1订购。id desc limit 1000;

最后,我发现,如果我将table2从内连接更改为左连接,那么所有的痛苦都消失了,它是0.03s!

  

table1左侧加入id选择table1_idtable1作为table2   在table1table2_id = table2id离开加入table3   table1table3_id = table3id其中table1id<的 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_idtable1作为table2   在table1table2_id = table2id其中table1id<    100000 table1排序。id desc limit 1000;

(0.40s)

  

table1内部加入id选择table1_idtable1作为table2   在table1table2_id = table2id其中table1id<的 1000   按table1订购。id desc limit 1000;

(0.01秒)

  

table1内部加入id选择table1_idtable1作为table2   在table1table2_id = table2id离开加入table3   table1table3_id = table3id其中table1id<的 100000   按table1订购。id desc limit 1000;

(2.31s)

  

table1内部加入id选择table1_idtable1作为table2   在table1table2_id = table2id离开加入table3   table1table3_id = table3id其中table1id< 1000 订单   按table1id 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 |                |
+---------------------------+------------------+------+-----+---------------------+----------------+

2 个答案:

答案 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在这方面有一些改进。

请记住,查询有数百万种变体。虽然我感谢您尝试隔离查询的重要部分;您可能会发现将任何答案都应用回“真实”的答案中。查询可能会遇到其他一些打嗝。