在我的情况下,我有以下几列。
a,b,c,d,e,f
-> f is updated time stamp
-> b has cardinality of two distinct elements.
-> c and d columns have maximum distinct elements 10.
-> = queries on columns a, b and like queries on columns c, d and e
我的查询组合如下所示。
a b ORDER BY DESC f
a b c ORDER BY DESC f
a b d ORDER BY DESC f
a b e ORDER BY DESC f
我想知道创建索引的可行选择是什么。
a。我可以一起在(a,b,c,d,e)或(a,b,c,d,e,f)上创建索引吗?
b。将时间戳列f添加到索引是否有帮助?
c。索引中提到的列顺序是否可以提高性能?
示例查询
SELECT * FROM SampleTable T WHERE T.a = 123 and T.b='y' ORDER BY DESC T.f
SELECT * FROM SampleTable T WHERE T.a = 123 and T.b='y' and T.c Like '' ORDER BY DESC T.f
SELECT * FROM SampleTable T WHERE T.a = 123 and T.b='y' and T.d Like '' ORDER BY DESC T.f
SELECT * FROM SampleTable T WHERE T.a = 123 and T.b='y' and T.e Like '' ORDER BY DESC T.f
答案 0 :(得分:2)
a。我可以一起在(a,b,c,d,e)或(a,b,c,d,e,f)上创建索引吗?
INDEX(a, b, c, d, e, f)
将处理需要(a, b, c, d, e)
的情况。因此,只做更长的一个。但是-这将完全不会完全处理您的任何示例SELECTs
。
b。将时间戳列f添加到索引是否有帮助?
是的。例如,WHERE T.a = 123 and T.b='y' ORDER BY DESC T.f
喜欢INDEX(a,b)
,但更喜欢(a,b,f)
。但是不是(a,b,c,f)
并不比(a,b)
好。仅使用最左边的; c
在这里。
c。索引中提到的列顺序是否可以提高性能?
这取决于。 WHERE T.a = 123 and T.b='y'
对INDEX(a,b)
和(b,a)
一样满意。但是,假设两个测试均为=
。 (此外,“基数”也没关系。)
AND c赞
与AND c = ''
相同。但是AND c LIKE 'x%' works like a "range" and
和c类似'%x'cannot use an index for
c`。
要最佳地处理所有4个示例查询,您将需要4个索引。但是,以下一个索引可能是一个合理的折衷方案:
INDEX(a,b,f)
阅读此内容;它说明了所有这些,还有更多内容:http://mysql.rjweb.org/doc.php/index_cookbook_mysql
答案 1 :(得分:1)
情况1:此表具有且仅包含以下列,a, b, c, d, e, f
情况2:此表包含更多列
对于情况1,我认为您不需要在(a,b,c,d,e)或(a,b,c,d,e,f)上创建索引,因为:
对于情况2,我也不认为您需要创建这两个索引:
那您应该添加什么索引? 我认为那应该取决于您的业务。
如果该表不会被过分更新,并且会执行很多查询,我认为您可以添加服务器不同的索引以提高查询性能。
index on (a b f)
index on (a b c f)
index on (a b d f)
index on (a b e f)
如果查询和更新同时存在,则索引过多。我们需要仔细考虑。我注意到您已经列出了b,c和d的基数,所有三列都有少量不同元素的基数。也许具有更大的不同元素基数。这样,在(a,b,c)或(a,b,d)上添加索引与使用索引几乎相同,然后根据返回表数据进行过滤。 (a,b,e)可能会更有效。
index on (a, b, e)
考虑按f排序,我不确定基数是什么。如果最终查询结果不是太大,则msyql将使用mysql排序缓冲区。因此加f不是必需的。 如果结果太大,也许您可以考虑:
index on (a, b, f).
当查询条件为a = xxx and b = yyy order by f
时,mysql将不需要对结果进行排序。它只是返回表并读取所有列,然后返回到客户端。
当查询条件类似于a = xxx and b = yyy and c like 'zzz' order by f
或a = xxx and b = yyy and d like 'zzz' order by f
或a = xxx and b = yyy and e like 'zzz' order by f
时。因为a和b是相等的条件,并且索引类似于(a,b,f),所以当条件为a = xxx and b = yyy
时,结果将按f排序。其实,mysql会从innodb一步一步地获取数据,详细步骤如下:
a = xxx and b = yyy
通过索引(a,b,f)检索第一个主要ID d like 'zzz'
。如果匹配,则放入结果集中。如果不匹配,请谨慎。注意:工作流仅在查询条件必须包含a和b并且相关条件必须等于条件时才起作用,例如“ a = xxx和b = yyy”。否则,mysql将在其他工作流程中执行,并将使用file或sort_buffer对结果进行排序。
无论如何,以上所有这些分析都是理论上的。最好的方法仍然是对您的环境进行一些测试。无论您创建索引的效率如何,当业务变化时,情况都会变得更糟。