基于索引的SQL查询优化

时间:2013-11-10 18:21:19

标签: 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 Employee WHERE Salary+Bonus>1500

表格中的员工: 员工ID, 名称, 姓, 薪水, 奖金

我已经说过,对于第一个a),一个复合索引最好,第二个聚类更好,第三个聚合,一个聚类(d我不确定我的选择)你能不能对它们进行验证并纠正我,因为我是新手.Pindexes最好是在Oracle.Thanks提前。

2 个答案:

答案 0 :(得分:3)

  

对于第一个a)复合指数最好

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

  

第二个更好的聚类

同样,在选择索引时需要考虑整个表/应用程序。表上只能有一个聚簇索引。您的一个聚簇索引很可能需要位于EmployeeID列上。即使我们在这里没有看到任何查询,这也是最常见的需求。薪水的常规指数在这里可能还不错。

  

为第三个分区

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

  某种聚集在一起(d

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

在所有情况下,由于您只是在请求EmployeeID列,因此您希望将EmployeeID添加到索引中,但实际上并不对该字段进行索引。只需INCLUDE包含索引的列。通过这种方式,数据库将能够完全从索引中完成查询,而无需返回到表中。仅包含列而不是索引列的原因是为了提高INSERT / UPDATE语句的性能,以避免需要重建索引。

答案 1 :(得分:2)

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

CREATE INDEX emp_i3 ON Employee (Salary+Bonus);