【发布时间】:2016-12-19 19:07:37
【问题描述】:
我有一个简单但很长的查询,它计算结果的内容大约需要 14 秒。主表上的计数本身花费不到一秒钟,但在多次加入后延迟太高,如下所示
Select Count(Distinct visits.id) As Count_id
From visits
Left Join clients_locations ON visits.client_location_id = clients_locations.id
Left Join clients ON clients_locations.client_id = clients.id
Left Join locations ON clients_locations.location_id = locations.id
Left Join users ON visits.user_id = users.id
Left Join potentialities ON clients_locations.potentiality = potentialities.id
Left Join classes ON clients_locations.class = classes.id
Left Join professions ON clients.profession_id = professions.id
Inner Join specialties ON clients.specialty_id = specialties.id
Left Join districts ON locations.district_id = districts.id
Left Join provinces ON districts.province_id = provinces.id
Left Join locations_types ON locations.location_type_id = locations_types.id
Left Join areas ON clients_locations.area_id = areas.id
Left Join calls ON calls.visit_id = visits.id
解释的输出是
+---+---+---+---+---+---+---+---+---+---+ |编号 |选择类型 |表|类型 |可能的键 |关键 | key_len |参考 |行 |额外 | +---+---+---+---+---+---+---+---+---+---+ | 1 |简单 |特产 |索引 |初级 |专业名称 | 52 |空 | 53 |使用索引 | | 1 |简单 |客户 |参考 |初级,专业 |专业 | 4 | crm_db.specialties.id | 143 | | | 1 |简单 |客户位置 |参考 | PRIMARY,client_id |客户 ID | 4 | crm_db.clients.id | 1 | | | 1 |简单 |地点 | eq_ref |初级 |初级 | 4 | crm_db.clients_locations.location_id | 1 | | | 1 |简单 |地区 | eq_ref |初级 |初级 | 4 | crm_db.locations.district_id | 1 |使用位置 | | 1 |简单 |访问 |参考 | unique_visit,client_location_id |独特的访问 | 4 | crm_db.clients_locations.id | 4 |使用索引 | | 1 |简单 |来电 |参考 | call_unique,visit_id | call_unique | 4 | crm_db.visits.id | 1 |使用索引 | +---+---+---+---+---+---+---+---+---+---+
更新 1
上面的查询与动态 where 语句 $sql = $sql . "Where ". $whereFilter 一起使用,但我以简单的形式提交了它。所以不要考虑答案只是消除连接:)
更新 2 这是动态过滤的示例
$temp = $this->province_id;
if ($temp != null) {
$whereFilter = $whereFilter . " and provinces.id In ($temp) ";
}
但在启动案例中,我们的案例中没有 where 语句
【问题讨论】:
-
如果您只是计算访问中的唯一 ID,为什么还需要加入?
-
你似乎没有过滤,所以你为什么需要
count(distinct)。我的意思是,在joins 中有一个或两个inner join,但似乎没有必要加入。 -
我稍后将此查询与动态 where 语句 'Where $whereFilter' 一起使用
-
当一个“访问”有 0 个“调用”时,是否算作 1?当“访问”有 3 个“调用”时,它算作 1 吗?还是3?这对于理解并可能消除
LEFT JOINs至关重要。 -
如果您动态添加使用这些左连接中的字段的 where 子句,则您将它们更改为内连接。这会给你不正确的结果。
标签: mysql database query-optimization