在OR条件下,Mysql查询运行时间过长

时间:2013-06-28 06:19:40

标签: mysql

这是查询需要12秒的时间

SELECT SQL_CALC_FOUND_ROWS DISTINCT `t`.* FROM `wp_pods_bars` AS `t` 
LEFT JOIN `wp_podsrel` AS `rel_city` ON 
    ( `rel_city`.`field_id` = 13918 AND `rel_city`.`item_id` = `t`.`id` ) OR 
    ( `rel_city`.`related_field_id` = 13918 AND `rel_city`.`related_item_id` = `t`.`id` ) 

如果我这样做

SELECT SQL_CALC_FOUND_ROWS DISTINCT `t`.* FROM `wp_pods_bars` AS `t` 
LEFT JOIN `wp_podsrel` AS `rel_city` ON 
    ( `rel_city`.`field_id` = 13918 AND `rel_city`.`item_id` = `t`.`id` )

SELECT SQL_CALC_FOUND_ROWS DISTINCT `t`.* FROM `wp_pods_bars` AS `t` 
LEFT JOIN `wp_podsrel` AS `rel_city` ON 
    ( `rel_city`.`related_field_id` = 13918 AND `rel_city`.`related_item_id` = `t`.`id` ) 

每个查询运行0,09秒。为什么这样以及如何解决这个问题?

编辑:

EXPLAIN SELECT SQL_CALC_FOUND_ROWS DISTINCT `t`.* FROM `wp_pods_bars` AS `t` 
LEFT JOIN `wp_podsrel` AS `rel_city` ON 
    ( `rel_city`.`related_field_id` = 13918 AND `rel_city`.`related_item_id` = `t`.`id` ) 

结果

id,select_type,table,type,possible_keys,key,key_len,ref,rows,Extra
1,SIMPLE,t,ALL,NULL,NULL,NULL,NULL,1340,Using temporary
1,SIMPLE,rel_city,ref,rel_field_rel_item_idx,rel_field_item_idx,rel_field_rel_item_idx,14,const,barchick.t.id,1,Using index; Distinct

第二

EXPLAIN SELECT SQL_CALC_FOUND_ROWS DISTINCT `t`.* FROM `wp_pods_bars` AS `t` 
LEFT JOIN `wp_podsrel` AS `rel_city` ON 
( `rel_city`.`related_field_id` = 13918 AND `rel_city`.`related_item_id` = `t`.`id` ) 

结果

id,select_type,table,type,possible_keys,key,key_len,ref,rows,Extra
1,SIMPLE,t,ALL,NULL,NULL,NULL,NULL,1340,Using temporary
1,SIMPLE,rel_city,ref,rel_field_rel_item_idx,rel_field_item_idx,rel_field_rel_item_idx,14,const,barchick.t.id,1,Using index; Distinct 

1 个答案:

答案 0 :(得分:1)

您拥有的LEFT加入是多余的,因为您不会在结果中使用正确的表格。并且DISTINCT将删除由联接生成的任何重复行。

因此,您的查询等同于从表中获取所有行的查询(只要wp_pods_bars中有主键或唯一键):

SELECT t.* FROM wp_pods_bars AS t ;

DISTINCT,没有JOIN,没有OR


MariaDB中有一项功能,名为 Table Elimination (另请参阅 Sergey Petrunia's blog 以获取解释)可能符合您的意愿,消除连接,但当然从MySQL切换到MariaDB可能不适合您。