2014-08-27 34 views
0

我们的一些SQL查询需要3个多小时才能执行,考虑到我们的数据库目前大约有5000个条目,这确实很长。SQL查询占用时间超过1小时

这里两个最长声明:

/* Alte Jobs anzeigen */ 

update vwr_synch.listings set vwr_synch.listings.Alt="alt" 
where vwr_synch.listings.JobKey not in (select vwr_synch.jobs.JobKey from vwr_synch.jobs) 
; 

update vwr_synch.listings set vwr_synch.listings.Alt="alt" where vwr_synch.listings.VWRStatus="NoJobs" or vwr_synch.listings.VWRStatus="Problem" 
; 


update vwr_synch.listings set vwr_synch.listings.Alt=NULL 
where vwr_synch.listings.VWRStatus="Active" and vwr_synch.listings.VWRRetry!="0" and vwr_synch.listings.Alt="alt" 
; 


/* Neue Jobs anzeigen */ 

update vwr_synch.jobs set vwr_synch.jobs.NeuAlt="Neu" 
where vwr_synch.jobs.JobKey not in (select vwr_synch.listings.JobKey from vwr_synch.listings) and (vwr_synch.jobs.`Status`="Active" and vwr_synch.jobs.Retry="0") 
; 
+0

是你正在更新的那些视图吗?这是什么vwr前缀是什么? – Donal 2014-08-27 11:42:58

+0

@Donal没有vwr前缀是由应用程序创建的 – 2014-08-27 11:48:09

回答

3

示例代码中有多个语句,所以我就重点放在了第一位。

我更喜欢not in,因为使用NULL的语义,虽然有证据表明not in可能更有效(请参阅评论中的链接)。这是第一个查询:

update vwr_synch.listings 
    set vwr_synch.listings.Alt = 'alt' 
    where vwr_synch.listings.JobKey not in (select vwr_synch.jobs.JobKey from vwr_synch.jobs); 

我将其更改为:

update vwr_synch.listings l 
    set l.Alt = 'alt' 
    where not exists (select 1 from vwr_synch.jobs.JobKey jk where jk.JobKey = l.JobKey); 

然后,这有效地工作,你需要vwr_synch.jobs.JobKey(JobKey)的索引。

接下来的两个语句是:

update vwr_synch.listings l 
    set l.Alt = 'alt' 
    where l.VWRStatus in ('NoJobs', 'Problem'); 

update vwr_synch.listings l 
    set l.Alt = NULL 
    where l.VWRStatus = 'Active' and l.VWRRetry <> '0' and l.Alt = 'alt'; 

对于这些,你想对vwr_synch.listings(VWRStatus, Alt, VWRRetry)的索引。

+0

根据[本文](http://explainextended.com/2009/09/18/not-in-vs-not-exists-vs-left-join- is-null-mysql /),'NOT EXISTS'实际上比'NOT IN'慢。我会让索引成为你答案的主要内容。 – Arth 2014-08-27 11:47:53

+0

另外,使用where子句来确定你需要的索引。看看你的SQL我看到这些列上需要的索引:vwr_synch.listings.JobKey,vwr_synch.jobs.JobKey,vwr_synch.listings.VWRStatus,vwr_synch.listings.VWRRetry,vwr_synch.listings.Alt,vwr_synch.jobs.Status,vwr_synch。 jobs.Retry – Dave 2014-08-27 11:49:08

+0

@Arth。 。 。我实际上更喜欢'NOT IN',因为语义更符合人们的期望。当子查询中的某个元素为假时,“NOT IN”从不返回true。我修改了答案,但我在博客中对这个评论感到担忧:“很难说出这个确切的原因......”。 – 2014-08-27 11:54:10