2017-05-31 61 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'可能臃腫了它的死行,查詢計劃器是以某種方式試圖篩選。 –