基于索引的SQL查询优化

基于索引的SQL查询优化,sql,oracle,query-optimization,Sql,Oracle,Query Optimization,我被分配了以下查询以及如何通过创建索引来优化它们: a)SELECT EmployeeID FROM Employee WHERE Name='John'AND Surname='Brown' b)SELECT EmployeeID FROM Employee WHERE Salary=1300 c)SELECT EmployeeID FROM Employee WHERE Salary BETWEEN 1000 AND 1500 d)SELECT EmployeeID FROM Empl

我被分配了以下查询以及如何通过创建索引来优化它们:

a)SELECT EmployeeID FROM Employee WHERE Name='John'AND Surname='Brown'

b)SELECT EmployeeID FROM Employee WHERE Salary=1300

c)SELECT EmployeeID FROM Employee WHERE Salary BETWEEN 1000 AND 1500

d)SELECT EmployeeID FROM Employee WHERE Salary+Bonus>1500
从员工表中: 雇员ID, 名称 姓, 薪水 奖金

我已经说过,对于第一个a)复合索引最好,第二个更好,第三个更好,第三个更好,第三个更好,第三个更好。我不确定我的选择。请验证一下,并纠正我,因为我是新来的。p.s.索引最好在Oracle中。提前谢谢

对于第一个a)复合索引最好

在什么栏目上?姓+名,名+姓?顺序很重要。在这种情况下,它可能根本不重要,但通常你要考虑整个应用程序,并思考你将如何进行查找。例如,如果您有另一个仅按姓氏查询的查询,则需要确保将姓氏列放在索引的第一位,以便此索引可用于两个查询。过度索引对性能的影响几乎与索引不足一样糟糕

第二个更好

再次,在选择索引时,需要考虑整个表/应用程序。一个表上只能有一个聚集索引。您的一个聚集索引很可能需要位于EmployeeID列上。即使我们在这里没有看到任何使用它的查询,这也是最常见的需求。在这里,定期的工资指数可能已经足够好了

为第三个分区的

定期的工资指数可能就足够了。数据库将能够转到第一条记录,然后“遍历索引”,直到不再匹配为止。但这取决于桌子的大小。。。如果表很大(分为10行和100行),分区是有意义的(通常在表本身上)。我不知道有多少企业有上千万的员工。同样,我们要做的一件事是避免过度索引,因此重新使用b)中的相同索引是很好的

某种聚集在(d)中的

这取决于数据库引擎和版本,但任何索引本身都不太可能有助于此查询。原因是表达式通常不可搜索,这意味着查询优化器无法足够聪明地知道索引是否可以工作。您可以做的是创建一个索引并在该列上放置一个索引

在所有情况下,由于您只请求EmployeeID列,因此您希望将EmployeeID添加到索引中,但实际上不在该字段上编制索引。只需包含索引的列即可。这样,数据库就可以完全从索引完成查询,而无需返回表。仅包含列,而不是在其上建立索引,是为了提高INSERT/UPDATE语句的性能,以避免需要重建索引

对于第一个a)复合索引最好

在什么栏目上?姓+名,名+姓?顺序很重要。在这种情况下,它可能根本不重要,但通常你要考虑整个应用程序,并思考你将如何进行查找。例如,如果您有另一个仅按姓氏查询的查询,则需要确保将姓氏列放在索引的第一位,以便此索引可用于两个查询。过度索引对性能的影响几乎与索引不足一样糟糕

第二个更好

再次,在选择索引时,需要考虑整个表/应用程序。一个表上只能有一个聚集索引。您的一个聚集索引很可能需要位于EmployeeID列上。即使我们在这里没有看到任何使用它的查询,这也是最常见的需求。在这里,定期的工资指数可能已经足够好了

为第三个分区的

定期的工资指数可能就足够了。数据库将能够转到第一条记录,然后“遍历索引”,直到不再匹配为止。但这取决于桌子的大小。。。如果表很大(分为10行和100行),分区是有意义的(通常在表本身上)。我不知道有多少企业有上千万的员工。同样,我们要做的一件事是避免过度索引,因此重新使用b)中的相同索引是很好的

某种聚集在(d)中的

这取决于数据库引擎和版本,但任何索引本身都不太可能有助于此查询。原因是表达式通常不可搜索,这意味着查询优化器无法足够聪明地知道索引是否可以工作。您可以做的是创建一个索引并在该列上放置一个索引

在所有情况下,由于您只请求EmployeeID列,因此您希望将EmployeeID添加到索引中,但实际上不在该字段上编制索引。只需包含索引的列即可。这样,数据库就可以完全从索引完成查询,而无需返回表。仅包含列,而不是在其上建立索引,是为了提高INSERT/UPDATE语句的性能,以避免需要重建索引。

对于d)基于函数的索引(FBI)是合适的:

CREATE INDEX emp_i3 ON Employee (Salary+Bonus);
对于d)基于函数的索引(FBI)是合适的:

CREATE INDEX emp_i3 ON Employee (Salary+Bonus);

嗨,Joel,您在计算列上的链接是针对sql server的。这是个错误吗?我相信你指的是oracle的虚拟列:@Sebas我错过了oracle标签,主要回答的是概念。看起来包含是Oracle没有做的其他事情。我不确定您关于“clusterd索引”的说明是否适用,因为只提到了一个表。嗨,Joel,您关于计算列的链接是针对sql server的。这是个错误吗?我相信你指的是oracle的虚拟列:@Sebas我错过了oracle标签,主要回答的是概念。看起来李