简体   繁体   English

向列添加索引会提高 SQL 中的 select 查询(没有 where)性能吗?

[英]Will adding an index to a column improve the select query (without where) performance in SQL?

I have a MySQL table that contains 20 000 000 rows, and columns like (user_id, registered_timestamp, etc).我有一个 MySQL 表,其中包含 20 000 000 行和(user_id、registered_timestamp 等)等列。 I have written a below query to get a count of users registered day wise.我写了一个下面的查询来计算每天注册的用户数量。 The query was taking a long time to execute.查询需要很长时间才能执行。 Will adding an index to the registered_timestamp column improve the execution time?向registered_timestamp 列添加索引会提高执行时间吗?

select date(registered_timestamp), count(userid) from table group by 1

Consider using this query to get a list of dates and the number of registrations on each date.考虑使用此查询来获取日期列表和每个日期的注册数量。

 SELECT date(registered_timestamp) date, COUNT(*) 
   FROM table
  GROUP BY date(registered_timestamp)

Then an index on table(registered_timestamp) will help a little because it's a covering index.然后table(registered_timestamp)上的索引会有所帮助,因为它是一个覆盖索引。

If you adapt your query to return dates from a limited range, for example.例如,如果您调整查询以返回有限范围内的日期。

 SELECT date(registered_timestamp) date, COUNT(*) 
   FROM table
  WHERE registered_timestamp >= CURDATE() - INTERVAL 8 DAY
    AND registered_timestamp < CURDATE() 
  GROUP BY date(registered_timestamp)

the index will help.该指数将有所帮助。 (This query returns results for the week ending yesterday.) However, the index will not help this query. (此查询返回昨天结束的一周的结果。)但是,索引不会帮助此查询。

 SELECT date(registered_timestamp) date, COUNT(*) 
   FROM table
  WHERE DATE(registered_timestamp) >= CURDATE() - INTERVAL 8 DAY /* slow! */
  GROUP BY date(registered_timestamp)

because the function on the column makes the query unsargeable .因为列上的function使查询无法判断。

You probably can address this performance issue with a MySQL generated column.您可能可以使用 MySQL 生成的列来解决此性能问题。 This command:这个命令:

ALTER TABLE `table` 
       ADD registered_date DATE 
       GENERATED ALWAYS AS DATE(registered_timestamp)
       STORED;

Then you can add an index on the generated column然后您可以在生成的列上添加索引

CREATE INDEX regdate ON `table` ( registered_date );

Then you can use that generated (derived) column in your query, and get a lot of help from that index.然后,您可以在查询中使用该生成(派生)列,并从该索引中获得很多帮助。

 SELECT registered_date, COUNT(*) 
   FROM table
  GROUP BY registered_date;

But beware, creating the generated column and its index will take a while.但请注意,创建生成的列及其索引需要一段时间。

select date(registered_timestamp), count(userid) from table group by 1

Would benefit from INDEX(registered_timestamp, userid) but only because such an index is "covering".将从INDEX(registered_timestamp, userid)受益,但这只是因为这样的索引是“覆盖”的。 The query will still need to read every row of the index, and do a filesort.查询仍然需要读取索引的每一行,并进行文件排序。

If userid is the PRIMARY KEY , then this would give you the same answers without bothering to check each userid for being NOT NULL .如果useridPRIMARY KEY ,那么这将为您提供相同的答案,而无需检查每个userid是否NOT NULL

select date(registered_timestamp), count(*) from table group by 1

And INDEX(registered_timestamp) would be equivalent to the above suggestion.并且INDEX(registered_timestamp)将等同于上述建议。 (This is because InnoDB implicitly tacks on the PK.) (这是因为 InnoDB 隐式添加了 PK。)

If this query is common, then you could build and maintain a "summary table", which collects the count every night for the day's registrations.如果这个查询很常见,那么您可以构建和维护一个“汇总表”,它每天晚上收集当天的注册计数。 Then the query would be a much faster fetch from that smaller table.然后查询将从那个较小的表中更快地获取。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM