And*_*res 2 mysql innodb mysql-5.7 query-performance
我有一个 MySql 数据库,用于存储来自应用程序的事件,自从我们创建它以来,我们只插入和选择数据,我们从未删除任何行。我不是数据库管理员,我的组织中没有数据库管理员,所以如果我遗漏了一些基本的东西,请多多包涵。数据库有一个像这样的表:
CREATE TABLE `eventlogs` (
`Id` int(11) NOT NULL AUTO_INCREMENT,
`LogType` int(11) NOT NULL,
`ProductId` longtext,
`Username` varchar(128) CHARACTER SET utf8 DEFAULT NULL,
`ClientVersion` longtext,
`Message` longtext,
`Referrer` longtext,
`UserAgent` longtext,
`CreatedDate` datetime NOT NULL,
PRIMARY KEY (`Id`),
KEY `IX_LogType` (`LogType`),
KEY `IX_CreatedDate` (`CreatedDate`),
KEY `IX_Username` (`Username`)
) ENGINE=InnoDB AUTO_INCREMENT=180712975 DEFAULT CHARSET=latin1;
Run Code Online (Sandbox Code Playgroud)
这曾经非常有效,但它达到了几乎不可能运行任何查询的程度,它们需要超过 15 分钟,有时甚至更多!这是我们运行的典型查询:
SELECT * FROM customily_logs.eventlogs
WHERE CreatedDate > '2020-06-01'
and Username = 'myuser'
and LogType = 3
Run Code Online (Sandbox Code Playgroud)
这是查询的执行计划:
{
"query_block": {
"select_id": 1,
"cost_info": {
"query_cost": "14073888.06"
},
"table": {
"table_name": "eventlogs",
"access_type": "index_merge",
"possible_keys": [
"IX_LogType",
"IX_CreatedDate",
"IX_Username"
],
"key": "intersect(IX_Username,IX_LogType)",
"key_length": "387,4",
"rows_examined_per_scan": 15809639,
"rows_produced_per_join": 7904819,
"filtered": "50.00",
"cost_info": {
"read_cost": "12492924.16",
"eval_cost": "1580963.90",
"prefix_cost": "14073888.06",
"data_read_per_join": "3G"
},
"used_columns": [
"Id",
"LogType",
"ProductId",
"Username",
"ClientVersion",
"Message",
"Referrer",
"UserAgent",
"CreatedDate"
],
"attached_condition": "((`customily_logs`.`eventlogs`.`LogType` = 3) and (`customily_logs`.`eventlogs`.`CreatedDate` > '2020-06-01') and (`customily_logs`.`eventlogs`.`Username` = 'myuser'))"
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是 Windows Server 2012 R2 x64 上的 MySQL 5.7.29。该表有 1.77 亿行,根据 MySql Workbench,它有 65.6 GiB 的数据和 8.8 GiB 的索引。Windows 机器是 AWS 上的 EC2 实例,具有 32 个内核、128 GB 的 RAM 和 2 TB 的 EBS 存储,具有 9000 IOPS,虽然它与其他正在运行的应用程序共享,但 CPU 使用率很少超过 50%,并且总是在 50 GB 左右可用内存。这些是服务器设置my.ini:
[client]
port=3307
[mysql]
no-beep
[mysqld]
port=3307
datadir=C:/ProgramData/MySQL/MySQL Server 5.7/Data
default-storage-engine=INNODB
sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
log-output=FILE
general-log=0
general_log_file="WIN-2BKHQL88U78.log"
slow-query-log=1
slow_query_log_file="WIN-2BKHQL88U78-slow.log"
long_query_time=10
log-error="WIN-2BKHQL88U78.err"
relay_log="WIN-2BKHQL88U78-relay"
server-id=1
report_port=3307
lower_case_table_names=1
secure-file-priv="C:/ProgramData/MySQL/MySQL Server 5.7/Uploads"
max_connections=151
table_open_cache=2000
tmp_table_size=3G
thread_cache_size=10
myisam_max_sort_file_size=100G
myisam_sort_buffer_size=4G
key_buffer_size=8M
read_buffer_size=64K
read_rnd_buffer_size=256K
innodb_flush_log_at_trx_commit=1
innodb_log_buffer_size=1M
innodb_buffer_pool_size = 24G
innodb_log_file_size=48M
innodb_thread_concurrency=33
innodb_autoextend_increment=64
innodb_buffer_pool_instances=8
innodb_concurrency_tickets=5000
innodb_old_blocks_time=1000
innodb_open_files=300
innodb_stats_on_metadata=0
innodb_file_per_table=1
innodb_checksum_algorithm=0
back_log=80
flush_time=0
join_buffer_size=256K
max_allowed_packet=4M
max_connect_errors=100
open_files_limit=4161
sort_buffer_size=256K
table_definition_cache=1400
binlog_row_event_max_size=8K
sync_master_info=10000
sync_relay_log=10000
sync_relay_log_info=10000
Run Code Online (Sandbox Code Playgroud)
我尝试将其innodb_buffer_pool_size增加到 32 GB,但没有帮助。我还运行ANALYZE它几乎立即完成,我检查了数据库中的碎片,但它似乎非常低(用this检查它)。我希望将查询时间减少到 1 分钟或更短,但我不知道这是否不切实际。多longtext列的使用会影响查询时间吗?
非常感谢您的帮助!
好消息是你需要更好地使用多列索引来更好地对应你的查询(参考:MySQL 如何使用索引)。
通过使用恒定的参考值,(该WHERE标准是=),Username而LogType之前的范围内CreatedDate,如果你创建联合索引与查询,这将帮助。
ALTER TABLE eventlogs
DROP INDEX IX_Username,
ADD INDEX IX_Username_LogType_CreatedDate(Username,LogType,CreatedDate),
ALGORITHM=INPLACE,
LOCK=NONE;
Run Code Online (Sandbox Code Playgroud)
我替换了现有索引,因为具有相同前缀的类似大小的索引是等效的。
如果返回的数据集大小不是很大,则使用 <1 分钟的查询应该是可能的。
longtext列在这里不会有太大影响,除非有很多行的大小超过 ~8k(即存储在行 - ref 之外),并且这会根据返回的行数而不是根据返回的行数影响查询时间搜索时间(因为索引不是长文本)。
| 归档时间: |
|
| 查看次数: |
70 次 |
| 最近记录: |