如何解决在不同列上执行SELECT WHERE的表的最佳索引技术
我正在寻找一种高效的索引表索引技术,如下所示:
MariaDB [Webapp]> explain logs;
+----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| user_id | int(11) | YES | MUL | NULL | |
| activity_name | varchar(20) | NO | | NULL | |
| activity_key | varchar(255) | NO | | NULL | |
| activity_value | varchar(255) | NO | | NULL | |
| activity_date | datetime | NO | MUL | NULL | |
+----------------+--------------+------+-----+---------+----------------+
我确实这样搜索:
SELECT *
FROM logs
WHERE user_id IN (1,3)
AND activity_name IN ('login','logout')
AND activity_date >= '2020-02-01'
AND activity_date <= '2020-06-01'
涉及列user_id
,activity_name
和activity_date
的地方
有时是这样的:
SELECT *
FROM logs
WHERE user_id IN (1,'logout')
同时涉及user_id
和activity_name
,但没有日期。
也是这样的:
SELECT *
FROM logs
WHERE user_id IN (1,3)
AND activity_date >= '2020-02-01'
AND activity_date <= '2020-06-01'
SELECT *
FROM logs
WHERE activity_name IN ('login','logout')
AND activity_date >= '2020-02-01'
AND activity_date <= '2020-06-01'
我确实读过有关化合物索引的信息,如果我订购了搜索索引,它们会很好,但是如您所见,它并不适用,所以我认为它不合适。
我还读到单个索引可以一次只在一个列上使用,所以我认为这对我的情况不利。
请提出任何想法,我对MySQL不太熟悉。如何使查询最优化?
注意:我不使用通配符(*),因为我阅读通配符会减慢速度,但只是为了缩短查询时间而把它简化了>
解决方法
对于每个查询,基本思想是拥有一个索引,其列覆盖where
子句。对于您而言,这不能通过对四个查询使用单个索引来实现-我认为您需要3个索引。
首先,考虑以下索引:
logs(user_id,activity_name,activity_date)
它与第一个查询的where
子句匹配:
WHERE
user_id IN (1,3)
AND activity_name IN ('login','logout')
AND activity_date >= '2020-02-01'
AND activity_date <= '2020-06-01'
在第二个查询中也是如此(此处将忽略第三个索引列):
WHERE
user_id IN (1,'logout')
对于其他两个查询,您需要两个单独的索引:
WHERE
user_id IN (1,3)
AND activity_date >= '2020-02-01'
AND activity_date <= '2020-06-01'
需要:
logs(user_id,activity_date)
并且:
WHERE
activity_name IN ('login','logout')
AND activity_date >= '2020-02-01'
AND activity_date <= '2020-06-01'
需要:
logs(activity_name,activity_date)
旁注:通常,请勿盲目select *
;相反,请枚举结果集中所需的列-特别是如果您不希望全部使用时。如果只需要两三列,请考虑将它们添加到索引的末尾,从而将其变为 covering 索引。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。