如何使用 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) 可能不应该是唯一的,除非当用户多次访问同一个页面时你不想惹麻烦。