2017-05-31 82 views
0

我有2个表,ticket_data和nps_data。MySQL左加入非常缓慢,并且usuall永远挂起

ticket_data持有一般IT问题信息和nps_data持有用户反馈。 表格的基本思想是:

ticket_data表。 aprox。 150万行:30个字段:上TICKET_NUMBER,logged_date,logged_team 指数,resolution_date

 
|ticket_number | logged_date | logged_team | resolution_date | 
| I00001  | 2017-01-01 | Help Desk | 2017-01-02  | 
| I00002  | 2017-02-01 | Help Desk | 2017-03-01  | 
| I00010  | 2017-03-04 | desktop sup | 2017-03-04  | 

显然还有很多其他领域的,但是这是林与

nps_data表工作 aprox的83000行:10场: 指数TICKET_NUMBER

 
|ticket_number | resolving team| q1_score| 
| I00001  | helpdesk  | 5  | 
| I00002  | desktop sup | 0  | 
| I00010  | desktop sup | 10  | 

当我做一个简单的查询,如

 
select a.*, b.q1_score from 
(select * from ticket_data 
where resolution_date > '2017-01-01') a 
left join nps_data b 
on a.ticket_number = b.ticket_number 

该查询需要永久运行,当我说,我的意思是我在10分钟后停止查询。 但是,如果我运行查询,以便ticket_data一个叫ticket_details表,使用下面的查询

 
select * 
(select * from ticket_data 
where resolution_date > '2017-01-01') a 
left join ticket_details b 
on a.ticket_number = b.ticket_number 

的查询需要大约1.3秒的时间跑到其中有超过1,000,000行。

回答

0

在上面的查询中,您有一个子查询,其别名a未在索引上运行。您正在查询未索引的字段resolution_date

简单的修复方法是将一个索引添加到该字段。

门票号码索引。这可能是为什么当你加入时,查询运行速度更快。

另一种进一步优化的方法是不要在子查询中使用select *(这在生产系统中是不好的做法)。它为DBMS在子查询中传递所有结果创造了更多的开销。

另一种方式是做在列,如部分索引:

create index idx_tickets on ticket_data(ticket_number) where resolution_date > '2017-01-01'

但我只会做,如果的“2017年1月1日”时间戳是一个常数,它会总是被使用。

您也可以创建一个复合索引,这样查询引擎将运行一个Index Only Scan,从而它直接从索引中提取数据,而不必返回表格。

为了让我引用一些关于此的内容,我需要知道你正在运行的DBMS。

当然,所有这些都取决于您正在运行的DBMS的类型。

+0

对不起resolution_date已编入索引并且正在运行该子查询需要的时间不到一秒 – user2220694

+0

您正在使用哪些DBMS?你有没有做过一个解释查看查询的执行计划? –

+0

你也可以抽取表格(如果你使用的是Postgres),因为它看起来像你的'nps_data'可能臃肿了它的死行,查询计划器是以某种方式试图筛选。 –