Sql 这两个数据库查询在代数上相同吗?

Sql 这两个数据库查询在代数上相同吗?,sql,relational-database,theory,relational-algebra,Sql,Relational Database,Theory,Relational Algebra,我试图从理论/布尔代数/关系演算的角度,找出这两个查询在逻辑上是否相同 我有一个查询,查询的OR运行不佳,即成本为138个单位: SELECT * FROM Customers WHERE (FirstName LIKE 'Ian%') OR (LastName LIKE 'Boyd%') 但是,当我将查询分解为我认为在逻辑上相同的部分时,它运行得更好,即0.6个单位: SELECT * FROM Customers WHERE (FirstName LIKE 'Ian%') UNION

我试图从理论/布尔代数/关系演算的角度,找出这两个查询在逻辑上是否相同

我有一个查询,查询的OR运行不佳,即成本为138个单位:

SELECT *
FROM Customers
WHERE (FirstName LIKE 'Ian%') OR (LastName LIKE 'Boyd%')
但是,当我将查询分解为我认为在逻辑上相同的部分时,它运行得更好,即0.6个单位:

SELECT *
FROM Customers
WHERE (FirstName LIKE 'Ian%')

UNION

SELECT *
FROM Customers
WHERE (LastName LIKE 'Boyd%')
现在,在我看来,这两个查询在逻辑上是等价的或相同的——从我向关系数据库引擎请求什么信息的角度来看。但是如果是这样的话,现代复杂的查询优化器应该理解所有这些,而不是以任何不同的方式运行查询。但事实确实如此;我们都知道这可以归结为古怪的查询优化器

当然,除非它们实际上是不相等的

在这种情况下:我想知道:

这是一个问题吗≡ 查询B

笔记
这不是关于性能调优的问题,涉及DDL、数据量或要求任何人调优查询。如果现在是这样,数据库引擎将运行第二个查询:那么我只需要使用愚蠢的优化器。这是一个语言不可知、数据库不可知、理论性的问题。我不是问如何清除过程缓存,我不是问如何使用重新编译执行。我不是在要求解决这个问题。我在问一个理论问题。

这两个查询的形式通常没有相同的语义-尽管可能需要更复杂的示例来演示不同的结果

第一个表单包含或具有SELECT。。。但不选择不同的。。。。就这样。参见该链接处的参考文献5、6

第二种形式是。。。协会但不是。。。联合所有。。。。因此,即使个人选择…s不明显


如果这是您在特定DBMS上的特定模式及其特定配置的唯一区别,我希望UNION并非所有形式的性能都会更差,因为它需要重复数据消除。

假设客户没有重复的行,这两种形式在逻辑上是相同的。这是一个合理的假设

UNION版本更快,可能是因为SQL引擎可以为类似的模式使用索引——它们不是以通配符开头的

更快且几乎等同的版本是:

SELECT *
FROM Customers
WHERE FirstName LIKE 'Ian%'
UNION ALL
SELECT *
FROM Customers
WHERE LastName LIKE 'Boyd%' AND FirstName NOT LIKE 'Ian%';
这里唯一的问题是FirstName是否为NULL。在这种情况下,逻辑将过滤掉甚至匹配的姓氏。需要将这一点考虑在内:

SELECT *
FROM Customers
WHERE FirstName LIKE 'Ian%'
UNION ALL
SELECT *
FROM Customers
WHERE LastName LIKE 'Boyd%' AND
      (FirstName NOT LIKE 'Ian%' OR FirstName IS NULL);

这些版本应该更快,因为它们使用UNIONALL而不是UNION。后者会导致删除重复项的开销。但是,WHERE子句可以删除这些重复项,而不必跨行查看。

这是关于关系代数的吗?-还是SQL?SQL表不是关系。PS两个查询是否表示相同的映射取决于语言。SQL表不是关系,它们可以有重复项&SQL运算符与它们的关系类似项不同,因为它们处理重复项和空值的方式不同。SQL的非关系方面阻碍了优化。不管怎么说,对于你选择的代数或SQL,你在哪里回答这个问题?从定义上看很简单。PS优化器做它所做的事情&它取决于优化器。你的理由是什么?我担心如果我使用了不完全正确的语言,那么一些学究会出现并自鸣得意。我现在明白我错了。我不明白你的评论。你的意思是,我是对的吗?粗略地说,在关系代数中,查询的类比表示相同的映射。假设在SQL中,输入是两行,都是“Ian”。然后第一个查询返回2行,但第二个查询返回1行。唉,问题是没有。PS我们可以将一组行的SQL表表示为一组行的关系集,并根据2VL定义SQL运算符,然后查看结果表达式可以优化还是不能优化。请为客户提供模式定义;也适用于具有引用客户的外键的任何表。推测:如果FirstName上有一个索引,LastName上有一个单独的索引,那么查询规划者可能会在联合的每个分离点上分别使用这些索引;然而,它不将这些用于OR条件,而是返回到完整的表扫描。您应该能够从DBMS获取诊断“查询执行计划”。撇开吹毛求疵不谈,我同意你的直觉,那两个查询应该遵循相同的执行计划;也许DBMS优化程序需要配置?