mysql连接两个索引需要很长时间!

时间:2011-01-03 12:38:32

标签: mysql drupal inner-join

大家好 我在dripal中有一个自定义查询,这个查询是:

select count(distinct B.src) 
from node A, url_alias B 
where concat('node/',A.nid)= B.src;

现在,节点中的nid是主键,我已将src作为url_alias表中的索引。 等了一分多钟后我得到了这个:

+-----------------------+  
| count(distinct B.src) |  
+-----------------------+  
|                325715 |  
+-----------------------+  
1 row in set (1 min 24.37 sec)  

通过检查“解释”我得到了这个:

******************* 1. row ***************************  
           id: 1  
  select_type: SIMPLE  
        table: A  
         type: index  
possible_keys: NULL  
          key: PRIMARY  
      key_len: 4  
          ref: NULL  
         rows: 325716  
        Extra: Using index  
*************************** 2. row ***************************  
           id: 1  
  select_type: SIMPLE  
        table: B  
         type: ALL  
possible_keys: src_language_pid,src  
          key: NULL  
      key_len: NULL  
          ref: NULL  
         rows: 325928  
        Extra: Range checked for each record (index map: 0xC)  
2 rows in set (0.00 sec)  

现在我的问题是:为什么这个查询没有使用src的索引,以及如何优化它?

感谢您的帮助

3 个答案:

答案 0 :(得分:1)

性能问题与concat的使用有关 如果nid是一个整数,那么会导致很多工作。

我认为你必须在url_alias中添加一个索引的nid列。

不幸的是,您的表格不再正常化。

答案 1 :(得分:1)

COUNT(DISTINCT something)对于非平凡的查询,如果计算的表达式中不存在唯一索引,则强制查询在运行查询时在其上构建唯一索引。

这本来就很慢,在大多数情况下都是:

  • 不是必需的 - 解决方案:重写查询以便不需要使用

  • 如果真的有必要使用unique,那么通常会更快地将查询分成两个,一个将获得查询的有用结果,该结果将创建B.src的重复项和另一个查询这不需要不同的

最后,学会使用EXPLAIN,这样您就可以开始了解如何执行查询以及如何优化它们。

答案 2 :(得分:0)

1)解释这个查询,用EXPLAIN SLECT count ....启动它。

2)尝试将连接条件(where)作为连接移动:

 select count(distinct B.src) from node A inner join url_alias B ON concat('node/',A.nid)=B.src

3)快速索引的东西应该是节点表中的“concat('node /',nid)”。这里必须为每一行节点重新编译这个东西。根据您的MySQL版本,您可能无法使用表达式(只是列)构建索引。所以你可以有一个专用于存储“concat('node /',nid)”的列,你可以将其称为node_nid并将其编入索引。并检查你还没有得到它!