如何加快sql子查询

Posted

技术标签:

【中文标题】如何加快sql子查询【英文标题】:How to speed up sql sub query 【发布时间】:2019-08-22 11:12:02 【问题描述】:

我正在运行一项工作,运行时间太长。

我已经创建了一个作业来根据多个表的值进行更新

UPDATE applicant_scores 
  SET applicant_scores.Age=2.5
where applicant_scores.Applicant_id in 
  (select applicantinfo.subebno from applicantinfo
   WHERE SUBSTR(applicantinfo.DOB,7,4) ='1985')

这应该会更新大约 17000 行的列,但它需要的时间太长。

【问题讨论】:

你的 dbms 是什么? 我猜SUBSTR(applicantinfo.DOB,7,4) ='1985' 是问题所在。该列是如何索引的? WHERE IN 子句中创建一个包含子查询结果的临时表,并将其编入索引。 你怎么知道子查询是耗时的? 在你的子查询中使用 SUBSTR 可能是杀死它的原因。看起来您正在以字符串格式存储日期;考虑将申请人信息.DOB 列转换为日期格式(最佳实践)并使用 Year 函数(在该列上创建索引) 【参考方案1】:

我建议使用not exists 和索引:

UPDATE applicant_scores 
  SET applicant_scores.Age = 2.5
  WHERE EXISTS (SELECT 1
                FROM applicantinfo ai
                WHERE appliacnt_scores.Applicant_id = ai.subebno AND 
                      SUBSTR(ai.DOB, 7, 4) ='1985'
               );

为了提高性能,您需要在applicantinfo(subebno, DOB) 上建立索引。

注意:DOB 可能表示“出生日期”。它应该以date 的形式存储在您的数据库中,并且您应该使用适当的日期函数,例如:

extract(year from dob) = 1985
year(dob) = 1985
dob >= '1985-01-01' and dob < '1986-01-01'

不要将日期存储为字符串。不要在日期上使用字符串函数。

【讨论】:

【参考方案2】:

你的问题是这样的:

WHERE SUBSTR(applicantinfo.DOB,7,4) ='1985'

数据库无法快速找到符合该条件的所有行。没有索引。它必须检查数据库中的每一行以找到与该表达式匹配的行。

你有一个解决方案是你可以在你的表中添加另一列,也许叫它dob_year,然后就是那个日期的那一年。那么,你CREATE INDEX applicantinfo_dob_year ON applicantinfo(dob_year)。然后将您的WHERE 子句更改为WHERE dob_year ='1985')

https://use-the-index-luke.com/ 是了解数据库索引以及如何正确使用它们以加快查询速度的绝佳网站。

【讨论】:

【参考方案3】:
   SET Age_Score=(SELECT Age_Score FROM age_scoretbl WHERE  SUBSTR(applicantinfo.DOB,7,4)= age_scoretbl.Birth_Year);```






【讨论】:

我忽略了表 appliacnt_scores 并从 age_scoretbl.Birth_Year 填充了申请者信息.Age_Score。这很快。感谢 Gordon Linoff 关于日期数据类型的建议。著名的 !谢谢大家。

以上是关于如何加快sql子查询的主要内容,如果未能解决你的问题,请参考以下文章

子查询的 SQL 查询优化

如何重写具有连接子查询的 SQL 查询

我的子查询将执行时间增加了 20 秒。我怎样才能加快速度?

如何在 SQL 中组合两个查询? (子查询)

sql提示子查询返回的值不止一个,求解如何修改,谢谢。

如何优化此 SQL Server 查询 - 多个子查询