我有2个人和角色。 我必须以角色为基础的所有人。
select person.* from person inner join role on
person.roleid = role.id Where role.id = @Roleid
或
select person.* from person inner join role on
person.roleid = role.id AND role.id = @Roleid
上述两种解决方案中哪一项更好,为什么?
答案 0 :(得分:13)
第一个更好,因为它在逻辑上是连贯的。范围条件与连接无关,因此将其作为连接的一部分是一个kludge,在这种情况下是无用的。
答案 1 :(得分:9)
关系代数没有区别。来自这里和内部联接的标准是可以互换的。我根据可读性和情况使用两者。
在这种特殊情况下,您还可以使用:
select person.* from person WHERE person.roleid = @Roleid
唯一的区别是它不需要在角色表中存在一行(但我假设你具有参照完整性)并且如果roleid不是唯一的,它将不会返回多行(它几乎肯定是在我可以预见的大多数场景。)
答案 2 :(得分:8)
最好的办法是尝试这些查询并通过MS Sql的执行计划运行它们。我做了这个,结果看起来像这样:
正如您所看到的,性能是相同的(已授予,在您的数据库上运行它可能会产生不同的结果。)因此,最佳查询是一个遵循用于编写查询的一致约定。
答案 3 :(得分:2)
SQL Server应该以相同的方式评估这些查询。就个人而言,我会使用AND。我喜欢在连接中保留连接表的所有条件,以便它们可以一起使用,并且很容易找到。
答案 4 :(得分:2)
两个查询都是相同的。在查询处理期间,SQL Server在应用连接条件过滤器后立即应用WHERE过滤器,因此您最终将以相同的方式过滤。
答案 5 :(得分:2)
我更喜欢#1,我相信它更好地表达了声明的意图。您正在加入基于roleid&的两个表。 role.id以及您基于@Roleid进行过滤
SELECT person.*
FROM person INNER JOIN role ON person.roleid = role.id
Where role.id = @Roleid
答案 6 :(得分:0)
Sqlserver可能有一个等同于“解释计划”的声明,Oracle,PostgreSQL和MySQL都支持这种或那种形式。它可以非常有用地告诉您查询解析器和优化器将如何处理您的查询。
答案 7 :(得分:0)
我会选择第一个,但记得在测试代码时你应该明确选择每个表,而不是做select *
答案 8 :(得分:0)
由于您没有从role
获取列,因此最好不要将其包含在FROM
子句中。使用此:
SELECT *
FROM person
WHERE person.roleid IN (SELECT id FROM role WHERE id = @Roleid)
这样,优化器只能看到FROM
子句中的一个表,并且可以快速找出结果集的基数(即结果集中的行数< =表中的行数{ {1}})。
当您使用person
抛出两个表时,优化器必须查看JOIN
子句以确定这些表是否是等连接的,以及连接列上是否存在唯一索引。如果ON
子句中的谓词很复杂(多个AND和OR)或者只是错误(有时非常错误),优化器可能会选择次优连接策略。
显然,这个特定的示例非常有用,因为您可以直接按ON
过滤persons
(无加入或子查询),但如果您必须过滤其他列,则上述注意事项有效roleid = @Roleid
(例如@Rolename)。
答案 9 :(得分:-4)
使用此查询会产生任何性能影响吗?
SELECT person.* FROM person,role WHERE person.roleid=role.id AND role.id=@RoleID