如何使用 SQL 索引?
How to use SQL indexes?
我有一个包含 n 个不同页面的应用程序,现在我想跟踪每次用户访问我的页面时的页面访问情况。因此,我创建了一个 table 来存储用户的日志详细信息,如下所示:
| id | visited_page_name |last_visited_at |user_id |
+----+----------------------------+----------------------------+-
| 1 | 1 | 2020-12-25 21:06:38.694452 | 459050 |
| 2 | 1 | 2020-12-25 21:07:01.072066 | 78557 |
| 3 | 2 | 2020-12-25 21:07:07.793581 | 78557 |
| 4 | 3 | 2020-12-25 21:07:16.180584 | 78557 |
| 5 | 2 | 2020-12-25 21:07:24.339918 | 459050 |
| 6 | 2 | 2020-12-25 21:07:34.186563 | 78558 |
| 7 | 3 | 2020-12-25 21:07:40.429625 | 78558 |
并且我已将 (user, visted_page_name)
设置为唯一索引 (last_visited_at, visted_oage_name)
。详情见下文table:
+-------------------------------+------------+-----------------------------------------------------------------+--------------+-------------------+-----------
| Table| Non_unique| Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type
--------+-------------+----------+--------+------+-------------------+-------------+----------+--------+------+-------------------+-------------+----------+----
| log | 0 | PRIMARY | 1 | id | A | 7 | NULL | NULL | | BTREE
| log | 0 | log_user_id_visited_page_nam_4569a199_uniq | 1 | user_id | A | 7 | NULL | NULL | | BTREE
| log | 0 | log_user_id_visited_page_nam_4569a199_uniq | 2 | visited_page_name | A | 7 | NULL | NULL | | BTREE
| log | 1 | log_visited_d9fd74_idx | 1 | visited_at | A | 7 | NULL | NULL | | BTREE
| log | 1 | log_visited_d9fd74_idx | 2 | visited_page_name | A | 7 | NULL | NULL | | BTREE
+-------------------------------+------------+-----------------------------------------------------------------+--------------+-------------------+---
现在我正在使用 EXPLAIN EXTENDED SELECT * from log WHERE last_visited_at <= 2020-12-25 21:07:40.429625 and visited_page_name in (1, 2)\G
。这给了我以下结果:
id: 1
select_type: SIMPLE
table: log
partitions: NULL
type: ALL
possible_keys: log_visited_d9fd74_idx
key: NULL
key_len: NULL
ref: NULL
rows: 7
filtered: 14.29
Extra: Using where
这表明我的查询没有使用索引。那么,任何人都可以解释为什么会这样吗?我犯了什么错误?
索引 log_visited_d9fd74_idx
(visited_at
, visited_page_name
) 是要使用的候选,但由于您的 table 仅包含 7 行,因此读取速度更快table 比通过索引。当您的 table 增长时,查询可能会使用索引。
索引 log_user_id_visited_page_nam_4569a199_uniq
(user_id
, visited_page_name
) 可能不应该是唯一的,除非当用户多次访问同一个页面时你不想惹麻烦。
我有一个包含 n 个不同页面的应用程序,现在我想跟踪每次用户访问我的页面时的页面访问情况。因此,我创建了一个 table 来存储用户的日志详细信息,如下所示:
| id | visited_page_name |last_visited_at |user_id |
+----+----------------------------+----------------------------+-
| 1 | 1 | 2020-12-25 21:06:38.694452 | 459050 |
| 2 | 1 | 2020-12-25 21:07:01.072066 | 78557 |
| 3 | 2 | 2020-12-25 21:07:07.793581 | 78557 |
| 4 | 3 | 2020-12-25 21:07:16.180584 | 78557 |
| 5 | 2 | 2020-12-25 21:07:24.339918 | 459050 |
| 6 | 2 | 2020-12-25 21:07:34.186563 | 78558 |
| 7 | 3 | 2020-12-25 21:07:40.429625 | 78558 |
并且我已将 (user, visted_page_name)
设置为唯一索引 (last_visited_at, visted_oage_name)
。详情见下文table:
+-------------------------------+------------+-----------------------------------------------------------------+--------------+-------------------+-----------
| Table| Non_unique| Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type
--------+-------------+----------+--------+------+-------------------+-------------+----------+--------+------+-------------------+-------------+----------+----
| log | 0 | PRIMARY | 1 | id | A | 7 | NULL | NULL | | BTREE
| log | 0 | log_user_id_visited_page_nam_4569a199_uniq | 1 | user_id | A | 7 | NULL | NULL | | BTREE
| log | 0 | log_user_id_visited_page_nam_4569a199_uniq | 2 | visited_page_name | A | 7 | NULL | NULL | | BTREE
| log | 1 | log_visited_d9fd74_idx | 1 | visited_at | A | 7 | NULL | NULL | | BTREE
| log | 1 | log_visited_d9fd74_idx | 2 | visited_page_name | A | 7 | NULL | NULL | | BTREE
+-------------------------------+------------+-----------------------------------------------------------------+--------------+-------------------+---
现在我正在使用 EXPLAIN EXTENDED SELECT * from log WHERE last_visited_at <= 2020-12-25 21:07:40.429625 and visited_page_name in (1, 2)\G
。这给了我以下结果:
id: 1
select_type: SIMPLE
table: log
partitions: NULL
type: ALL
possible_keys: log_visited_d9fd74_idx
key: NULL
key_len: NULL
ref: NULL
rows: 7
filtered: 14.29
Extra: Using where
这表明我的查询没有使用索引。那么,任何人都可以解释为什么会这样吗?我犯了什么错误?
索引 log_visited_d9fd74_idx
(visited_at
, visited_page_name
) 是要使用的候选,但由于您的 table 仅包含 7 行,因此读取速度更快table 比通过索引。当您的 table 增长时,查询可能会使用索引。
索引 log_user_id_visited_page_nam_4569a199_uniq
(user_id
, visited_page_name
) 可能不应该是唯一的,除非当用户多次访问同一个页面时你不想惹麻烦。