添加WHERE子句会使查询变得非常慢

时间:2010-11-19 19:44:09

标签: mysql sql

考虑以下两个问题:

select a.*, c.*
from account a
join customer c on a.customer_id = c.id
join import i on a.import_id = i.id
join import_bundle ib on i.import_bundle_id = ib.id

select a.*, c.*
from account a
join customer c on a.customer_id = c.id
join import i on a.import_id = i.id
join import_bundle ib on i.import_bundle_id = ib.id
where ib.id = 8

第一个查询速度很快,第二个查询速度超慢。知道为什么吗?我猜我需要索引或其他东西,但我不明白索引是如何工作的。我正在使用MySQL。

如果我在第二个查询中执行EXPLAIN,会发生以下情况:

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra   
 1  SIMPLE  ib  const   PRIMARY     PRIMARY     8   const   1   Using index
 1  SIMPLE  c   ALL     PRIMARY         144858  
 1  SIMPLE  a   ref     fk_account_customer_id,fk_account_import_id     fk_account_customer_id  8   mcif.c.id   2   
 1  SIMPLE  i   eq_ref  PRIMARY,import_bundle_id    PRIMARY     8   mcif.a.import_id    1   Using where

但我不知道如何解释这一点。

编辑:这是我最终使用的:

select a.*,
       c.*
  from account a
  join customer c on a.customer_id = c.id
  join (select id,
               import_bundle_id
          from import
         where import_bundle_id = 8) i on a.import_id = i.id
  join import_bundle ib on i.import_bundle_id = ib.id

import_bundle.id上添加索引没有做任何事情。

5 个答案:

答案 0 :(得分:1)

使用EXPLAIN http://dev.mysql.com/doc/refman/5.0/en/explain.html了解索引可以改善您的搜索。

此处索引如何工作http://www.tizag.com/mysqlTutorial/mysql-index.php

答案 1 :(得分:1)

后一个查询强制MySQL使用ib.id = 8查找结果集中的记录。

如果你为import_bundle.id添加索引,那么MySQL将能够快速找到相应的记录,而不是必须全部检查。

数据库索引就像教科书中的一个,而不是查看每个页面,你转到后面的索引,找到你想要的页码,然后直接去那里。

答案 2 :(得分:1)

  • 关于效果,在您的查询中,您确实需要。*和c。*?

  • 因此,索引的使用不够充分。我不熟悉mysql,但是你可以尝试使用这样的子查询加入吗?

    select a.*, c.*
    from account a
    join customer c on a.customer_id = c.id
    join 
    (    
        SELECT id, import_bundle_id FROM import WHERE id = 8
    ) as i on a.import_id = i.id
    join import_bundle ib on i.import_bundle_id = ib.id
    where ib.id = 8
  • 可能最好的索引是:import.import_bundle_id上​​的索引和import_bundle.id上的另一个索引。

答案 3 :(得分:0)

我并不熟悉mysql,但ib.id上的索引几乎肯定会有所帮助。通常应将您在JOIN或WHERE子句中使用的任何字段编入索引。此外,您可以尝试过滤i.import_bundle_id而不是ib.id,看看是否有帮助。

索引通常可以更快地查找信息。他们可以使用哈希表或类似的方法缩小他们必须查看的位置,而不是必须查看遍布整个数据库的远程和广泛分散的每个项目,而不是将其缩小到正确的记录范围。 。 Wikipedia explains it远比我好。 :)

答案 4 :(得分:0)

其他答案指向正确的方向,直至ib.id的索引。但是,ib.id看起来像主键(PK)。它是否在您的数据库中设置为PK?如果是这样,它应该通过PK自动获得索引。如果它没有被设置为PK,并且它确实是应该的列,那么您的数据库将遇到更多问题,而不仅仅是性能。

简而言之,如果ib.id应该是主键,请将其设置为1,并且您的性能应该会提高,因为它会自动获得索引(并且您不必担心单独添加任何索引) )。