【问题标题】:why this index is not a good fit for query like this为什么这个索引不适合这样的查询
【发布时间】:2019-11-11 11:20:44
【问题描述】:

假设我的数据库中有以下索引:

CREATE INDEX myindex on t2(emp_no, title);

和我的查询:

SELECT 
    t1.emp_no,
    t1.name,
FROM
    t1, t2
WHERE t1.emp_no = t2.emp_no and t2.title = 'some value';


有人建议我不要使用该索引进行查询,因为它没用,而且它可能会以某种方式使查询变慢。
但是为什么以及如何这个索引没有用呢?

【问题讨论】:

  • 您使用的是哪个DBMS 产品? “SQL”只是一种查询语言,不是特定数据库产品的名称,不同的DBMS产品之间的索引用法有很大的不同。请为您正在使用的数据库产品添加tag
  • 与性能无关,但是:您应该真正开始使用“现代”(近 30 岁)显式 JOIN 运算符,而不是古老而脆弱的隐式连接
  • 你不能真正“不使用和索引”——查询优化器将决定使用索引是否有意义。并且优化器通常会做对。
  • 不看表定义就很难判断。但是,如果您打算过滤 title 作为执行的第一步,则将该列放在索引的前面会更好。

标签: sql database indexing


【解决方案1】:

您的查询应使用标准、明确的JOIN 语法编写:

SELECT t1.emp_no, t1.name,
FROM t1 JOIN
     t2
     ON t1.emp_no = t2.emp_no and t2.title = 'some value';

对于此查询,一个最佳索引位于t2(emp_no, title)。这应该没问题。执行计划将扫描t1 并使用索引查找t2 中的匹配值。

因为您只想要来自t1 的列,所以exists 将是编写查询的典型方式:

SELECT t1.emp_no, t1.name,
FROM t1
WHERE EXISTS (SELECT 1
              FROM t2
              WHERE t1.emp_no = t2.emp_no and t2.title = 'some value'
             );

这将使用相同的索引。

【讨论】:

  • 不存在从何而来?原始查询似乎要求确实存在的记录。为什么索引(emp_no, title)“最佳”不允许首先在 t2 中找到具有请求标题的(可能是少数)匹配行,然后通过 emp_no(可能是主键)从 t1 中选择匹配行我们所知道的)?
  • @Thilo 。 . .这是一个非常好的问题。我不确定,但我确定了答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-05
  • 1970-01-01
  • 1970-01-01
  • 2019-05-16
  • 1970-01-01
  • 2011-08-24
相关资源
最近更新 更多