通过索引中列的顺序优化查询

时间:2019-01-16 10:57:21

标签: mysql sql database indexing

我有一个包含域和ID的表 查询是

    select distinct domain 
    from user 
    where id = '1'

索引使用顺序idx_domain_ididx_id_domain

如果执行顺序为

  

(FROM子句,WHERE子句,GROUP BY子句,HAVING子句,SELECT   子句,ORDER BY子句)

然后,如果查询使用排序的where列比select列快,那么查询应该更快。

该表有460万行。

使用idx_domain_id的时间 time using idx_domain_id

更改订单后的时间 time after change the order

2 个答案:

答案 0 :(得分:2)

这是您的查询:

select distinct first_name 
from user 
where id = '1';

您发现user(first_name, id)user(id, firstname)快。

为什么会这样呢?首先,这可能只是您如何安排时间的人工产物。如果您的表非常小(即数据可容纳在单个数据页上),则索引通常对提高性能不是很有用。

第二,如果您只运行一次查询,那么第一次运行查询时,可能会有“冷缓存”。第二次,数据已经存储在内存中,因此运行速度更快。

其他问题也可能出现。您没有指定什么时间。细微的差异可能是由于噪音造成的,可能没有意义。

您没有提供足够的信息来给出更明确的解释。其中包括:

  • 重复的计时在冷缓存上运行。
  • 表的大小信息和匹配的行数。
  • 布局信息,尤其是id的类型。
  • 说明两个查询的计划。

答案 1 :(得分:2)

^

由于@{^CAPTURE}select distinct domain from user where id = '1' ,因此最多只包含一个 行。因此,关键字id是无用的。

最有用的索引是您已经拥有的索引,PRIMARY KEY。它将向下钻取BTree来找到DISTINCT,并提供位于此处的PRIMARY KEY(id)的值。

另一方面,考虑

id='1'

现在,显而易见的索引是domain。这对于select distinct domain from user where something_else = '1' 子句来说是最佳的,它是“覆盖”的(意味着查询所需的所有列都存在于索引中)。交换索引中的列会比较慢。同时,由于可能存在多行,因此INDEX(something_else, domain)表示某些含义。但是,这不是合乎逻辑的事情。

关于标题问题(列顺序):WHERE子句中的DISTINCT列应排在 first 之前。 (有关更多详细信息,请参见下面的链接。)

=表示先收集所有行,然后对它们进行重复数据删除。当给出相同答案时,为什么要花那么多力气?

WHERE

这只会打一行,而不是所有的1。

阅读我的Indexing Cookbook

(是的,戈登有很多优点。)