在MySQL的索引中添加GROUPBY和ORDERBY列好吗
我在查询的Where子句中的列上有复合索引,但是我应该在索引中添加GROUPBY和ORDERBY列吗 例如,我有一个查询:在MySQL的索引中添加GROUPBY和ORDERBY列好吗,mysql,indexing,Mysql,Indexing,我在查询的Where子句中的列上有复合索引,但是我应该在索引中添加GROUPBY和ORDERBY列吗 例如,我有一个查询: select c1, c2 from table t1 where c3 = "A" and c4 = "B" Group By c1 Order By c5 我当前的索引位于c3和c4上(与查询的顺序相同)。我是否应该在索引中添加c1和c4以提高查询性能?考虑以下几点: DROP TABLE IF EXISTS my_table; CREATE TABLE my_ta
select c1, c2
from table t1
where c3 = "A"
and c4 = "B"
Group By c1
Order By c5
我当前的索引位于c3和c4上(与查询的顺序相同)。我是否应该在索引中添加c1和c4以提高查询性能?考虑以下几点:
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(id SERIAL PRIMARY KEY
,c1 INT NOT NULL
,c2 CHAR(1) NOT NULL
);
SELECT DISTINCT c1
FROM my_table t1
WHERE c2 = 'A'
此查询将受益于(c2,c1)上的覆盖索引
请注意,这可以很容易地进行测试-尽管奇怪的是,如果您同时提供了两个索引(c1,c2)和(c2,c1),它似乎选择了错误的一个。这取决于您
where c3 = "A"
and c4 = "B"
Group By c1
Order By c5
可以使用以下任一项:
INDEX(c3, c4, c1)
INDEX(c4, c3, c1)
它无法通过分组方式
进入订单方式
(除非它们相同)
另一方面,这更难优化:
where c3 > "A" -- note the inequality (a "range")
and c4 = "B"
Group By c1
Order By c5
这是最好的:
INDEX(c4, c3) -- the order matters now: '=' first
进一步:
where c3 = "A"
and c4 = "B"
Group By c1
Order By c1 -- same as GROUP BY
LIMIT 10 -- now can get to this
如果有,这将在10行之后停止
INDEX(c3, c4, c1) or INDEX(c4, c3, c1)
在其他示例中添加一个LIMIT
:他们将找到所有行,对它们进行排序,然后交付10行
关于最佳综合指数的更多讨论:
要使索引“覆盖”,请(在末尾)附加查询中的任何其他列。(但不要对此太过兴奋。经验法则:索引的列数不要超过5列。)“覆盖”增加了额外的速度,因为查询可以完全在索引的B树中执行。查询(有点)无意义,这也使得问题变得无意义。一个好的经验法则是“如果没有任何聚合函数,那么就不需要GROUPBY子句”。如果您只想返回不同的结果,请使用DISTINCT。很难用这么少的上下文来回答这个问题,但作为一般性建议,我建议使用EXPLAIN来确定给定查询使用哪些索引:可能要学习如何使用
分组方式。如果没有任何聚合,它就没有任何作用。正如草莓所说,您假设的查询是不切实际的。此外,由于ORDERBY子句中使用了未聚合和未选择的字段,因此它将无效并抛出错误。无论如何,如果您想了解一些索引技巧,您可能会读到以下内容:示例查询有点有趣,但我认为这里真正的问题是mysql是否使用索引来优化group by/order by?这里回答了按方面排序的问题