Mysql 查询需要 5 分钟以上,有 1910 万条记录

问题描述 投票:0回答:1

我使用的是 Ubuntu 服务器版本 20.04

配置为 16GB RAM 和 2GB 交换设施。

我的会话表中有 1910 万条记录:

+----------+-----------------+-----------------+
| count(*) | min(session_id) | max(session_id) |
+----------+-----------------+-----------------+
| 19168798 |               6 |        19170401 |
+----------+-----------------+-----------------+

这是我的询问:

  SELECT appid, country, COUNT(DISTINCT(uuid)) as total 
  FROM sessions 
  WHERE appid = (appids) 
    AND created >= (createdFrom) AND created <= (createdTo) 
  GROUP BY country 
  ORDER BY total DESC;

我已经在我的 ID、uuid 和创建的列上建立了索引。 当我运行查询时,加载数据几乎需要 5 分钟。

这里,是我的mysqld.cnf文件内容

[mysqld]
#
# * Basic Settings
#
user        = mysql
# pid-file  = /var/run/mysqld/mysqld.pid
# socket    = /var/run/mysqld/mysqld.sock
# port      = 3306
# datadir   = /var/lib/mysql


# If MySQL is running as a replication slave, this should be
# changed. Ref https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_tmpdir
# tmpdir        = /tmp
#
# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
bind-address        = 127.0.0.1
mysqlx-bind-address = 127.0.0.1
#
# * Fine Tuning
#
key_buffer_size     = 16M
# max_allowed_packet    = 64M
# thread_stack      = 256K

# thread_cache_size       = -1

# This replaces the startup script and checks MyISAM tables if needed
# the first time they are touched
myisam-recover-options  = BACKUP

# max_connections        = 151

# table_open_cache       = 4000

#
# * Logging and Replication
#
# Both location gets rotated by the cronjob.
#
# Log all queries
# Be aware that this log type is a performance killer.
# general_log_file        = /var/log/mysql/query.log
# general_log             = 1
#
# Error log - should be very few entries.
#
log_error = /var/log/mysql/error.log
#
# Here you can see queries with especially long duration
# slow_query_log        = 1
# slow_query_log_file   = /var/log/mysql/mysql-slow.log
# long_query_time = 2
# log-queries-not-using-indexes
#
# The following can be used as easy to replay backup logs or for replication.
# note: if you are setting up a replication slave, see README.Debian about
#       other settings you may need to change.
# server-id     = 1
# log_bin           = /var/log/mysql/mysql-bin.log
# binlog_expire_logs_seconds    = 2592000
max_binlog_size   = 100M
# binlog_do_db      = include_database_name
# binlog_ignore_db  = include_database_name

DESCRIBE sessions;

的结果
  +----------------+--------------+------+-----+---------+----------------+
    | Field          | Type         | Null | Key | Default | Extra          |
    +----------------+--------------+------+-----+---------+----------------+
    | session_id     | int          | NO   | PRI | NULL    | auto_increment |
    | uuid           | varchar(60)  | NO   | MUL | NULL    |                |
    | userid         | int          | YES  |     | NULL    |                |
    | appid          | int          | NO   |     | NULL    |                |
    | mau_count      | int          | YES  |     | 0       |                |
    | systemversion  | varchar(256) | NO   |     | NULL    |                |
    | os             | varchar(256) | NO   |     | NULL    |                |
    | language       | varchar(256) | YES  |     | NULL    |                |
    | country        | varchar(256) | YES  |     | NULL    |                |
    | appversion     | varchar(256) | YES  |     | NULL    |                |
    | phonename      | varchar(256) | YES  |     | NULL    |                |
    | devicemodel    | varchar(256) | YES  |     | NULL    |                |
    | city           | varchar(256) | YES  |     | NULL    |                |
    | state          | varchar(256) | YES  |     | NULL    |                |
    | latitude       | varchar(256) | YES  |     | NULL    |                |
    | longitude      | varchar(256) | YES  |     | NULL    |                |
    | startdatetime  | datetime     | YES  |     | NULL    |                |
    | enddatetime    | datetime     | YES  |     | NULL    |                |
    | duration       | int          | YES  |     | NULL    |                |
    | phonecarrier   | varchar(256) | YES  |     | NULL    |                |
    | created_at     | datetime     | YES  |     | NULL    |                |
    | updated_at     | datetime     | YES  |     | NULL    |                |
    | is_deleted     | int          | NO   |     | NULL    |                |
    | created        | date         | YES  | MUL | NULL    |                |
    | api_version    | varchar(50)  | YES  |     | NULL    |                |
    +----------------+--------------+------+-----+---------+----------------+

SHOW INDEXES FROM sessions;

的结果
+----------+------------+----------------+--------------+----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table    | Non_unique | Key_name       | Seq_in_index | Column_name    | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+----------+------------+----------------+--------------+----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| sessions |          0 | PRIMARY        |            1 | session_id     | A         |    19169624 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
| sessions |          0 | session_id     |            1 | session_id     | A         |    19169624 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
| sessions |          1 | sessionUuid    |            1 | uuid           | A         |     2738517 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
| sessions |          1 | sessionCreated |            1 | created        | A         |        5189 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
| sessions |          1 | sessionCreated |            2 | applicationsid | A         |       25939 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
| sessions |          1 | sessionCreated |            3 | country        | A         |      259048 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
| sessions |          1 | sessionCreated |            4 | language       | A         |      383392 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
| sessions |          1 | sessionCreated |            5 | uuid           | A         |     4792406 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
+----------+------------+----------------+--------------+----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+

请指导我如何使此查询加速以及我需要更改什么。

sql mysql performance query-optimization
1个回答
0
投票

如果查询没有匹配的索引,19.1 M 条记录就相当多了。唯一可以使用的索引是

created
的索引,这取决于查询中使用的日期范围:

尝试创建与 WEHRE 子句和 GROUP BY 匹配的索引:

create index session_appid_created on sessions (appid, created, country)

甚至

create index session_appid_created on sessions (appid, created, country, uuid)
© www.soinside.com 2019 - 2024. All rights reserved.