【发布时间】:2019-03-06 11:17:35
【问题描述】:
我有一个 570 万行和 1.9GB 大小的 MySQL InnoDB 表:
+-------------------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+---------+------+-----+---------+----------------+
| id | int(20) | NO | PRI | NULL | auto_increment |
| listing_id | int(20) | YES | | NULL | |
| listing_link | text | YES | | NULL | |
| transaction_title | text | YES | | NULL | |
| image_thumb | text | YES | | NULL | |
| seller_link | text | YES | | NULL | |
| seller_name | text | YES | | NULL | |
| sale_date | date | YES | | NULL | |
+-------------------+---------+------+-----+---------+----------------+
这是我的 3GB RAM 服务器的 my.ini 设置:
key_buffer = 16M
max_allowed_packet = 16M
sort_buffer_size = 8M
net_buffer_length = 8K
read_buffer_size = 2M
read_rnd_buffer_size = 16M
myisam_sort_buffer_size = 8M
log_error = "mysql_error.log"
innodb_autoinc_lock_mode=0
join_buffer_size = 8M
thread_cache_size = 8
thread_concurrency = 8
query_cache_size = 64M
query_cache_limit = 2M
ft_min_word_len = 4
thread_stack = 192K
tmp_table_size = 64M
innodb_buffer_pool_size = 2G
innodb_additional_mem_pool_size = 16M
innodb_log_file_size = 512M
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 1
innodb_lock_wait_timeout = 120
innodb_write_io_threads = 8
innodb_read_io_threads = 8
innodb_thread_concurrency = 16
innodb_log_files_in_group = 3
innodb_max_dirty_pages_pct = 90
当我运行下一个查询时,需要 20 多分钟才能返回结果:
SELECT transaction_title,
listing_id,
seller_name,
Max(sale_date) AS sale_date,
Count(*) AS count
FROM sales_meta
WHERE `sale_date` BETWEEN '2017-06-06' AND '2017-06-06'
GROUP BY listing_id
HAVING Count(*) > 1
ORDER BY count DESC,
seller_name;
我做了一些研究,看来我需要添加一些索引来加快速度,但我很困惑如何去做。有一些单列索引和一些多列索引,我应该做哪一个?
为了让事情变得更复杂,我需要定期在此表上执行一些其他查询:
SELECT *
FROM sales_meta
WHERE ` sale_date `= '2017-06-06';
和
SELECT DISTINCT `seller_name`
FROM `sales_meta`;
这两个可能不那么费力,但我仍然需要尽可能优化它们,尽管三个查询中的第一个是目前的重中之重。
【问题讨论】:
-
。 .您的查询格式不正确。您的
select包含几个不在group by中的未聚合列。在优化之前修复查询。 -
@GordonLinoff 你能否展示一下这个查询的正确查询结构是什么样的,也许作为下面的答案?
-
。 .我不知道你想做什么,所以,不,我不能。我可以说
select中的未聚合列都应该在group by中。 -
也就是说,您将获得一个随机的标题和名称,因为您也没有按它们进行分组。
-
@Acidon 请发布 SHOW INDEX FROM sales_meta > SIFsales-meta.txt 的文本结果;并告诉我们 3 个查询中的任何一个是否仍然“缓慢”。如果第一个表现良好,你应该能够使用你的 BETWEEN 而不仅仅是 EQUAL 并且有出色的表现。你有多少内存?您是否使用任何 SSD/NVME 进行数据存储? SELECT @@version 的结果是什么;谢谢
标签: mysql sql indexing query-optimization innodb