我有2个表,ticket_data和nps_data。
ticket_data保存一般IT问题信息,nps_data保存用户反馈。 表格的基本概念是:
ticket_data表。 aprox的。 1,500,000行: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 83,000行:10个字段: index 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_details的表连接ticket_data,该表使用以下查询具有超过1,000,000行
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秒才能运行。
答案 0 :(得分:0)
在上面的查询中,您有一个子查询,其别名a
未在索引上运行。您正在查询未编入索引的字段resolution_date
。
简单的解决方法是为该字段添加索引。
票证编号 已编入索引。这可能就是为什么当你加入时,查询运行得更快。
进一步优化此方法的另一种方法是不要在子查询中执行select *
(无论如何,这在生产系统中都是不好的做法)。它为DBMS创建了更多的开销,以便在子查询中传递所有结果。
另一种方法是对列进行部分索引,例如:
create index idx_tickets on ticket_data(ticket_number) where resolution_date > '2017-01-01'
但是,如果2017-01-01'的时间戳,我只会这样做。是一个永远使用的常数。
您还可以创建一个复合索引,因此查询引擎将运行Index Only Scan
,从而直接从索引中提取数据,而无需返回到表中。
为了让我参考这个,我需要知道你在运行什么DBMS。
当然,所有这些都取决于您正在运行的DBMS类型。