请教一个简单的SQLselect
Advice on a simple SQL select
我正在寻找有关基本 SQL 脚本的一些反馈,“in (select)”是最有效的方法吗?还是我想让一些不必要的事情变得过于复杂。
SELECT emailAddress FROM user where companyId in (SELECT id FROM company WHERE trialist = 1 AND DATEADD(DAY,-14,TrialEndDate) = '2020-08-13 00:00:00');
此脚本将 运行 来自使用 Dapper 的 .Net Framework 控制台应用程序。
假设 company
table 中没有重复项(鉴于 table 中的命名约定,这似乎非常合理),我建议:
SELECT u.emailAddress
FROM user u JOIN
company c
ON u.companyId = c.id
WHERE c.trialist = 1 AND
c.TrialEndDate = DATEADD(day, 14, '2020-08-13');
我为什么推荐这个?两个原因。
首先是显式JOIN
给了优化器更多的优化选择。如果一种方法比另一种方法更快,那将是一个巨大的胜利。
其次,DATEADD()
函数使优化器 的工作变得更加困难 (几乎所有函数都有这种效果)。它排除了在列上使用索引;它防止优化器进行分区修剪(如果 table 在该列上分区);它混淆了收集的有关该列的统计信息。将函数移至常量可消除所有这些问题。
然后,如果您想优化查询,您可以在 company(trialist, trialenddate)
和 user(companyid)
上添加索引。
我正在寻找有关基本 SQL 脚本的一些反馈,“in (select)”是最有效的方法吗?还是我想让一些不必要的事情变得过于复杂。
SELECT emailAddress FROM user where companyId in (SELECT id FROM company WHERE trialist = 1 AND DATEADD(DAY,-14,TrialEndDate) = '2020-08-13 00:00:00');
此脚本将 运行 来自使用 Dapper 的 .Net Framework 控制台应用程序。
假设 company
table 中没有重复项(鉴于 table 中的命名约定,这似乎非常合理),我建议:
SELECT u.emailAddress
FROM user u JOIN
company c
ON u.companyId = c.id
WHERE c.trialist = 1 AND
c.TrialEndDate = DATEADD(day, 14, '2020-08-13');
我为什么推荐这个?两个原因。
首先是显式JOIN
给了优化器更多的优化选择。如果一种方法比另一种方法更快,那将是一个巨大的胜利。
其次,DATEADD()
函数使优化器 的工作变得更加困难 (几乎所有函数都有这种效果)。它排除了在列上使用索引;它防止优化器进行分区修剪(如果 table 在该列上分区);它混淆了收集的有关该列的统计信息。将函数移至常量可消除所有这些问题。
然后,如果您想优化查询,您可以在 company(trialist, trialenddate)
和 user(companyid)
上添加索引。